updated streaming API
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 6e8f0fb..6de2e90 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -2960,16 +2960,15 @@
     }
 }
 
-size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_wCursor* output, ZSTD_rCursor* input)
+size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
 {
-    size_t sizeRead = input->size;
-    size_t sizeWritten = output->size;
-    size_t const result = ZSTD_compressStream_generic(zcs, output->ptr, &sizeWritten, input->ptr, &sizeRead, zsf_gather);
-    input->ptr = (const char*)(input->ptr) + sizeRead;
-    input->size -= sizeRead;
-    output->ptr = (char*)(output->ptr) + sizeWritten;
-    output->size -= sizeWritten;
-    output->nbBytesWritten += sizeWritten;
+    size_t sizeRead = input->size - input->pos;
+    size_t sizeWritten = output->size - output->pos;
+    size_t const result = ZSTD_compressStream_generic(zcs,
+                                                      (char*)(output->dst) + output->pos, &sizeWritten,
+                                                      (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
+    input->pos += sizeRead;
+    output->pos += sizeWritten;
     return result;
 }
 
@@ -2978,36 +2977,32 @@
 
 /*! ZSTD_flushStream() :
 *   @return : amount of data remaining to flush */
-size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_wCursor* output)
+size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
 {
     size_t srcSize = 0;
-    size_t sizeWritten = output->size;
-    size_t const result = ZSTD_compressStream_generic(zcs, output->ptr, &sizeWritten, &srcSize, &srcSize, zsf_flush);  /* use a valid src address instead of NULL */
-    output->ptr = (char*)(output->ptr) + sizeWritten;
-    output->size -= sizeWritten;
-    output->nbBytesWritten += sizeWritten;
+    size_t sizeWritten = output->size - output->pos;
+    size_t const result = ZSTD_compressStream_generic(zcs, output->dst + output->pos, &sizeWritten, &srcSize, &srcSize, zsf_flush);  /* use a valid src address instead of NULL */
+    output->pos += sizeWritten;
     if (ZSTD_isError(result)) return result;
     return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
 }
 
 
-size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_wCursor* output)
+size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
 {
-    BYTE* const ostart = (BYTE*)(output->ptr);
-    BYTE* const oend = ostart + output->size;
+    BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
+    BYTE* const oend = (BYTE*)(output->dst) + output->size;
     BYTE* op = ostart;
 
     if (zcs->stage != zcss_final) {
         /* flush whatever remains */
         size_t srcSize = 0;
-        size_t sizeWritten = output->size;
+        size_t sizeWritten = output->size - output->pos;
         size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end);  /* use a valid src address instead of NULL */
         size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
         op += sizeWritten;
         if (remainingToFlush) {
-            output->ptr = op;
-            output->size -= sizeWritten;
-            output->nbBytesWritten += sizeWritten;
+            output->pos += sizeWritten;
             return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4);
         }
         /* create epilogue */
@@ -3021,9 +3016,7 @@
         size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
         op += flushed;
         zcs->outBuffFlushedSize += flushed;
-        output->ptr = op;
-        output->size = oend-op;
-        output->nbBytesWritten += op-ostart;
+        output->pos += op-ostart;
         if (toFlush==flushed) zcs->stage = zcss_init;  /* end reached */
         return toFlush - flushed;
     }
diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
index 57ca211..74e166a 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1393,13 +1393,13 @@
 }
 
 
-size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_wCursor* output, ZSTD_rCursor* input)
+size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
 {
-    const char* const istart = (const char*)(input->ptr);
-    const char* const iend = istart + input->size;
+    const char* const istart = (const char*)(input->src) + input->pos;
+    const char* const iend = (const char*)(input->src) + input->size;
     const char* ip = istart;
-    char* const ostart = (char*)(output->ptr);
-    char* const oend = ostart + output->size;
+    char* const ostart = (char*)(output->dst) + output->pos;
+    char* const oend = (char*)(output->dst) + output->size;
     char* op = ostart;
     U32 someMoreWork = 1;
 
@@ -1417,8 +1417,7 @@
                     if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */
                         memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
                         zds->lhSize += iend-ip;
-                        input->ptr = iend;
-                        input->size = 0;
+                        input->pos = input->size;
                         return (hSize - zds->lhSize) + ZSTD_blockHeaderSize;   /* remaining header bytes + next block header */
                     }
                     memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
@@ -1522,11 +1521,8 @@
     }   }
 
     /* result */
-    input->ptr = ip;
-    input->size = (size_t)(iend-ip);
-    output->ptr = op;
-    output->size = (size_t) (oend-op);
-    output->nbBytesWritten += (size_t)(op-ostart);
+    input->pos += (size_t)(ip-istart);
+    output->pos += (size_t)(op-ostart);
     {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->zd);
         if (!nextSrcSizeHint) return (zds->outEnd != zds->outStart);   /* return 0 only if fully flushed too */
         nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->zd) == ZSTDnit_block);
diff --git a/lib/zstd.h b/lib/zstd.h
index 718416d..056940f 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -324,16 +324,17 @@
 *  Streaming
 ********************************************************************/
 
-typedef struct ZSTD_readCursor_s {
-  const void* ptr;            /**< position of cursor - update to new position */
-  size_t size;                /**< remaining buffer size to read - update preserves end of buffer */
-} ZSTD_rCursor;
+typedef struct ZSTD_inBuffer_s {
+  const void* src;    /**< start of input buffer */
+  size_t size;        /**< size of input buffer */
+  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_inBuffer;
 
-typedef struct ZSTD_writeCursor_s {
-  void* ptr;                  /**< position of cursor - update to new position */
-  size_t size;                /**< remaining buffer size to write - update preserves end of buffer */
-  size_t nbBytesWritten;      /**< already written bytes - update adds bytes newly written (accumulator) */
-} ZSTD_wCursor;
+typedef struct ZSTD_outBuffer_s {
+  void*  dst;         /**< start of output buffer */
+  size_t size;        /**< size of output buffer */
+  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_outBuffer;
 
 
 /*======   compression   ======*/
@@ -350,14 +351,14 @@
 *  Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
 *
 *  Use ZSTD_compressStream() repetitively to consume input stream.
-*  The function will automatically advance cursors.
-*  Note that it may not consume the entire input, in which case `input->size > 0`,
+*  The function will automatically update both `pos`.
+*  Note that it may not consume the entire input, in which case `pos < size`,
 *  and it's up to the caller to present again remaining data.
 *  @return : a hint to preferred nb of bytes to use as input for next function call (it's just a hint, to improve latency)
 *            or an error code, which can be tested using ZSTD_isError().
 *
 *  At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
-*  Cursor will be updated.
+*  `output->pos` will be updated.
 *  Note some content might still be left within internal buffer if `output->size` is too small.
 *  @return : nb of bytes still present within internal buffer (0 if it's empty)
 *            or an error code, which can be tested using ZSTD_isError().
@@ -380,9 +381,9 @@
 size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer */
 
 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
-size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_wCursor* output, ZSTD_rCursor* input);
-size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_wCursor* output);
-size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_wCursor* output);
+size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
 
 /* advanced */
 ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
@@ -404,8 +405,8 @@
 *   or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
 *
 *  Use ZSTD_decompressStream() repetitively to consume your input.
-*  The function will update cursors.
-*  Note that it may not consume the entire input (input->size > 0),
+*  The function will update both `pos`.
+*  Note that it may not consume the entire input (pos < size),
 *  in which case it's up to the caller to present remaining input again.
 *  @return : 0 when a frame is completely decoded and fully flushed,
 *            1 when there is still some data left within internal buffer to flush,
@@ -422,7 +423,7 @@
 size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer */
 
 size_t ZSTD_initDStream(ZSTD_DStream* zds);
-size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_wCursor* output, ZSTD_rCursor* input);
+size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
 
 /* advanced */
 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
diff --git a/programs/fileio.c b/programs/fileio.c
index 66ccbc7..04d5a71 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -336,30 +336,30 @@
         DISPLAYUPDATE(2, "\rRead : %u MB  ", (U32)(readsize>>20));
 
         /* Compress using buffered streaming */
-        {   ZSTD_rCursor rCursor = { ress.srcBuffer, inSize };
-            ZSTD_wCursor wCursor = { ress.dstBuffer, ress.dstBufferSize, 0 };
-            { size_t const result = ZSTD_compressStream(ress.cctx, &wCursor, &rCursor);
+        {   ZSTD_inBuffer  inBuff = { ress.srcBuffer, inSize, 0 };
+            ZSTD_outBuffer outBuff= { ress.dstBuffer, ress.dstBufferSize, 0 };
+            { size_t const result = ZSTD_compressStream(ress.cctx, &outBuff, &inBuff);
               if (ZSTD_isError(result)) EXM_THROW(23, "Compression error : %s ", ZSTD_getErrorName(result)); }
-            if (rCursor.size != 0)
+            if (inBuff.pos != inBuff.size)
                 /* inBuff should be entirely consumed since buffer sizes are recommended ones */
                 EXM_THROW(24, "Compression error : input block not fully consumed");
 
             /* Write cBlock */
-            { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, wCursor.nbBytesWritten, dstFile);
-              if (sizeCheck!=wCursor.nbBytesWritten) EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName); }
-            compressedfilesize += wCursor.nbBytesWritten;
+            { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
+              if (sizeCheck!=outBuff.pos) EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName); }
+            compressedfilesize += outBuff.pos;
         }
         DISPLAYUPDATE(2, "\rRead : %u MB  ==> %.2f%%   ", (U32)(readsize>>20), (double)compressedfilesize/readsize*100);
     }
 
     /* End of Frame */
-    {   ZSTD_wCursor wCursor = { ress.dstBuffer, ress.dstBufferSize, 0 };
-        size_t const result = ZSTD_endStream(ress.cctx, &wCursor);
+    {   ZSTD_outBuffer outBuff = { ress.dstBuffer, ress.dstBufferSize, 0 };
+        size_t const result = ZSTD_endStream(ress.cctx, &outBuff);
         if (result!=0) EXM_THROW(26, "Compression error : cannot create frame end");
 
-        { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, wCursor.nbBytesWritten, dstFile);
-          if (sizeCheck!=wCursor.nbBytesWritten) EXM_THROW(27, "Write error : cannot write frame end into %s", dstFileName); }
-        compressedfilesize += wCursor.nbBytesWritten;
+        { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
+          if (sizeCheck!=outBuff.pos) EXM_THROW(27, "Write error : cannot write frame end into %s", dstFileName); }
+        compressedfilesize += outBuff.pos;
     }
 
     /* Status */
@@ -624,19 +624,18 @@
 
     /* Main decompression Loop */
     while (1) {
-        ZSTD_rCursor rCursor = { ress.srcBuffer, readSize };
-        ZSTD_wCursor wCursor = { ress.dstBuffer, ress.dstBufferSize, 0 };
-        size_t const toRead = ZSTD_decompressStream(ress.dctx, &wCursor, &rCursor );
+        ZSTD_inBuffer  inBuff = { ress.srcBuffer, readSize, 0 };
+        ZSTD_outBuffer outBuff= { ress.dstBuffer, ress.dstBufferSize, 0 };
+        size_t const toRead = ZSTD_decompressStream(ress.dctx, &outBuff, &inBuff );
         if (ZSTD_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(toRead));
-        readSize = rCursor.size;
 
         /* Write block */
-        storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, wCursor.nbBytesWritten, storedSkips);
-        frameSize += wCursor.nbBytesWritten;
+        storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, outBuff.pos, storedSkips);
+        frameSize += outBuff.pos;
         DISPLAYUPDATE(2, "\rDecoded : %u MB...     ", (U32)(frameSize>>20) );
 
         if (toRead == 0) break;   /* end of frame */
-        if (readSize) EXM_THROW(37, "Decoding error : should consume entire input");
+        if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input");
 
         /* Fill input buffer */
         if (toRead > ress.srcBufferSize) EXM_THROW(38, "too large block");
diff --git a/programs/zstreamtest.c b/programs/zstreamtest.c
index 7ef58fe..7f136b1 100644
--- a/programs/zstreamtest.c
+++ b/programs/zstreamtest.c
@@ -155,8 +155,8 @@
     U32 testNb=0;
     ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem);
     ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem);
-    ZSTD_rCursor rCursor;
-    ZSTD_wCursor wCursor;
+    ZSTD_inBuffer  inBuff;
+    ZSTD_outBuffer outBuff;
 
     /* Create compressible test buffer */
     if (!CNBuffer || !compressedBuffer || !decodedBuffer || !zc || !zd) {
@@ -173,39 +173,41 @@
     /* Basic compression test */
     DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
     ZSTD_initCStream_usingDict(zc, CNBuffer, 128 KB, 1);
-    wCursor.ptr = (char*)(compressedBuffer)+cSize;
-    wCursor.size = compressedBufferSize;
-    wCursor.nbBytesWritten = 0;
-    rCursor.ptr = CNBuffer;
-    rCursor.size = CNBufferSize;
-    { size_t const r = ZSTD_compressStream(zc, &wCursor, &rCursor);
+    outBuff.dst = (char*)(compressedBuffer)+cSize;
+    outBuff.size = compressedBufferSize;
+    outBuff.pos = 0;
+    inBuff.src = CNBuffer;
+    inBuff.size = CNBufferSize;
+    inBuff.pos = 0;
+    { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff);
       if (ZSTD_isError(r)) goto _output_error; }
-    if (rCursor.size != 0) goto _output_error;   /* entire input should be consumed */
-    { size_t const r = ZSTD_endStream(zc, &wCursor);
+    if (inBuff.pos != inBuff.size) goto _output_error;   /* entire input should be consumed */
+    { size_t const r = ZSTD_endStream(zc, &outBuff);
       if (r != 0) goto _output_error; }  /*< error, or some data not flushed */
-    cSize += wCursor.nbBytesWritten;
+    cSize += outBuff.pos;
     DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
 
     /* skippable frame test */
     DISPLAYLEVEL(4, "test%3i : decompress skippable frame : ", testNb++);
     ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
-    rCursor.ptr = compressedBuffer;
-    rCursor.size = cSize;
-    wCursor.ptr = decodedBuffer;
-    wCursor.size = CNBufferSize;
-    wCursor.nbBytesWritten = 0;
-    { size_t const r = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+    inBuff.src = compressedBuffer;
+    inBuff.size = cSize;
+    inBuff.pos = 0;
+    outBuff.dst = decodedBuffer;
+    outBuff.size = CNBufferSize;
+    outBuff.pos = 0;
+    { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
       if (r != 0) goto _output_error; }
-    if (wCursor.nbBytesWritten != 0) goto _output_error;   /* skippable frame len is 0 */
+    if (outBuff.pos != 0) goto _output_error;   /* skippable frame len is 0 */
     DISPLAYLEVEL(4, "OK \n");
 
     /* Basic decompression test */
     DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
     ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
-    { size_t const r = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+    { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
       if (r != 0) goto _output_error; }  /* should reach end of frame == 0; otherwise, some data left, or an error */
-    if (wCursor.nbBytesWritten != CNBufferSize) goto _output_error;   /* should regenerate the same amount */
-    if (rCursor.size != 0) goto _output_error;   /* should have read the entire frame */
+    if (outBuff.pos != CNBufferSize) goto _output_error;   /* should regenerate the same amount */
+    if (inBuff.pos != inBuff.size) goto _output_error;   /* should have read the entire frame */
     DISPLAYLEVEL(4, "OK \n");
 
     /* check regenerated data is byte exact */
@@ -220,26 +222,27 @@
     DISPLAYLEVEL(4, "test%3i : decompress byte-by-byte : ", testNb++);
     {   size_t r = 1;
         ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
-        rCursor.ptr = compressedBuffer;
-        wCursor.ptr = decodedBuffer;
-        wCursor.nbBytesWritten = 0;
+        inBuff.src = compressedBuffer;
+        outBuff.dst = decodedBuffer;
+        inBuff.pos = 0;
+        outBuff.pos = 0;
         while (r) {   /* skippable frame */
-            rCursor.size = 1;
-            wCursor.size = 1;
-            r = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+            inBuff.size = inBuff.pos + 1;
+            outBuff.size = outBuff.pos + 1;
+            r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
             if (ZSTD_isError(r)) goto _output_error;
         }
         ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
         r=1;
         while (r) {   /* normal frame */
-            rCursor.size = 1;
-            wCursor.size = 1;
-            r = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+            inBuff.size = inBuff.pos + 1;
+            outBuff.size = outBuff.pos + 1;
+            r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
             if (ZSTD_isError(r)) goto _output_error;
         }
     }
-    if (wCursor.nbBytesWritten != CNBufferSize) goto _output_error;   /* should regenerate the same amount */
-    if ((size_t)(rCursor.ptr - compressedBuffer) != cSize) goto _output_error;   /* should have read the entire frame */
+    if (outBuff.pos != CNBufferSize) goto _output_error;   /* should regenerate the same amount */
+    if (inBuff.pos != cSize) goto _output_error;   /* should have read the entire frame */
     DISPLAYLEVEL(4, "OK \n");
 
     /* check regenerated data is byte exact */
@@ -345,7 +348,7 @@
         const BYTE* srcBuffer;
         const BYTE* dict;
         size_t maxTestSize, dictSize;
-        size_t cSize, totalTestSize, totalCSize, totalGenSize;
+        size_t cSize, totalTestSize, totalGenSize;
         U32 n, nbChunks;
         XXH64_state_t xxhState;
         U64 crcOrig;
@@ -395,31 +398,30 @@
         /* multi-segments compression test */
         XXH64_reset(&xxhState, 0);
         nbChunks    = (FUZ_rand(&lseed) & 127) + 2;
-        {   ZSTD_wCursor wCursor = { cBuffer, cBufferSize, 0 } ;
+        {   ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
             for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
                 /* compress random chunk into random size dst buffer */
-                {   size_t readChunkSize = FUZ_randomLength(&lseed, maxSampleLog);
+                {   size_t const readChunkSize = FUZ_randomLength(&lseed, maxSampleLog);
                     size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - readChunkSize);
                     size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                     size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
-                    ZSTD_rCursor rCursor = { srcBuffer+srcStart, readChunkSize };
-                    wCursor.size = dstBuffSize;
+                    ZSTD_inBuffer inBuff = { srcBuffer+srcStart, readChunkSize, 0 };
+                    outBuff.size = outBuff.pos + dstBuffSize;
 
-                    { size_t const compressionError = ZSTD_compressStream(zc, &wCursor, &rCursor);
+                    { size_t const compressionError = ZSTD_compressStream(zc, &outBuff, &inBuff);
                       CHECK (ZSTD_isError(compressionError), "compression error : %s", ZSTD_getErrorName(compressionError)); }
-                    readChunkSize -= rCursor.size;
 
-                    XXH64_update(&xxhState, srcBuffer+srcStart, readChunkSize);
-                    memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, readChunkSize);
-                    totalTestSize += readChunkSize;
+                    XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
+                    memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos);
+                    totalTestSize += inBuff.pos;
                 }
 
                 /* random flush operation, to mess around */
                 if ((FUZ_rand(&lseed) & 15) == 0) {
                     size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
-                    size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
-                    wCursor.size = dstBuffSize;
-                    {   size_t const flushError = ZSTD_flushStream(zc, &wCursor);
+                    size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
+                    outBuff.size = outBuff.pos + adjustedDstSize;
+                    {   size_t const flushError = ZSTD_flushStream(zc, &outBuff);
                         CHECK (ZSTD_isError(flushError), "flush error : %s", ZSTD_getErrorName(flushError));
             }   }   }
 
@@ -429,33 +431,32 @@
                     size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                     size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
                     U32 const enoughDstSize = (adjustedDstSize >= remainingToFlush);
-                    wCursor.size = adjustedDstSize;
-                    remainingToFlush = ZSTD_endStream(zc, &wCursor);
+                    outBuff.size = outBuff.pos + adjustedDstSize;
+                    remainingToFlush = ZSTD_endStream(zc, &outBuff);
                     CHECK (ZSTD_isError(remainingToFlush), "flush error : %s", ZSTD_getErrorName(remainingToFlush));
                     CHECK (enoughDstSize && remainingToFlush, "ZSTD_endStream() not fully flushed (%u remaining), but enough space available", (U32)remainingToFlush);
             }   }
             crcOrig = XXH64_digest(&xxhState);
-            cSize = wCursor.nbBytesWritten;
+            cSize = outBuff.pos;
         }
 
         /* multi - fragments decompression test */
         ZSTD_initDStream_usingDict(zd, dict, dictSize);
         {   size_t decompressionResult = 1;
-            ZSTD_rCursor rCursor = { cBuffer, cSize };
-            ZSTD_wCursor wCursor = { dstBuffer, dstBufferSize, 0 };
-            for (totalCSize = 0, totalGenSize = 0 ; decompressionResult ; ) {
+            ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
+            ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
+            for (totalGenSize = 0 ; decompressionResult ; ) {
                 size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                 size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                 size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
-                rCursor.size = readCSrcSize;
-                wCursor.size = dstBuffSize;
-                decompressionResult = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+                inBuff.size = inBuff.pos + readCSrcSize;
+                outBuff.size = inBuff.pos + dstBuffSize;
+                decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                 CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult));
-                totalCSize += readCSrcSize - rCursor.size;
             }
             CHECK (decompressionResult != 0, "frame not fully decoded");
-            CHECK (wCursor.nbBytesWritten != totalTestSize, "decompressed data : wrong size")
-            CHECK (totalCSize != cSize, "compressed data should be fully read")
+            CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size")
+            CHECK (inBuff.pos != cSize, "compressed data should be fully read")
             {   U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
                 if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
                 CHECK (crcDest!=crcOrig, "decompressed data corrupted");
@@ -475,15 +476,15 @@
 
         /* try decompression on noisy data */
         ZSTD_initDStream(zd);
-        {   ZSTD_rCursor rCursor = { cBuffer, cSize };
-            ZSTD_wCursor wCursor = { dstBuffer, dstBufferSize, 0 };
-            while (wCursor.nbBytesWritten < dstBufferSize) {
+        {   ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
+            ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
+            while (outBuff.pos < dstBufferSize) {
                 size_t const randomCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                 size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
-                size_t const adjustedDstSize = MIN(dstBufferSize - wCursor.nbBytesWritten, randomDstSize);
-                wCursor.size = adjustedDstSize;
-                rCursor.size = randomCSrcSize;
-                {   size_t const decompressError = ZSTD_decompressStream(zd, &wCursor, &rCursor);
+                size_t const adjustedDstSize = MIN(dstBufferSize - outBuff.pos, randomDstSize);
+                outBuff.size = outBuff.pos + adjustedDstSize;
+                inBuff.size  = inBuff.pos + randomCSrcSize;
+                {   size_t const decompressError = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                     if (ZSTD_isError(decompressError)) break;   /* error correctly detected */
     }   }   }   }
     DISPLAY("\r%u fuzzer tests completed   \n", testNb);