@@ -21,6 +21,16 @@ static void ZSTD_compressStream2_wrapper(compressStream2_result* result, ZSTD_CC
21
21
result->bytes_written = outBuffer.pos;
22
22
}
23
23
24
+ static void ZSTD_compressStream2_flush(compressStream2_result* result, ZSTD_CCtx* ctx, uintptr_t dst, size_t maxDstSize, const uintptr_t src, size_t srcSize) {
25
+ ZSTD_outBuffer outBuffer = { (void*)dst, maxDstSize, 0 };
26
+ ZSTD_inBuffer inBuffer = { (void*)src, srcSize, 0 };
27
+ size_t retCode = ZSTD_compressStream2(ctx, &outBuffer, &inBuffer, ZSTD_e_flush);
28
+
29
+ result->return_code = retCode;
30
+ result->bytes_consumed = inBuffer.pos;
31
+ result->bytes_written = outBuffer.pos;
32
+ }
33
+
24
34
static void ZSTD_compressStream2_finish(compressStream2_result* result, ZSTD_CCtx* ctx, uintptr_t dst, size_t maxDstSize, const uintptr_t src, size_t srcSize) {
25
35
ZSTD_outBuffer outBuffer = { (void*)dst, maxDstSize, 0 };
26
36
ZSTD_inBuffer inBuffer = { (void*)src, srcSize, 0 };
@@ -203,6 +213,49 @@ func (w *Writer) Write(p []byte) (int, error) {
203
213
return len (p ), err
204
214
}
205
215
216
+ // Flush writes any unwritten data to the underlying io.Writer.
217
+ func (w * Writer ) Flush () error {
218
+ if w .firstError != nil {
219
+ return w .firstError
220
+ }
221
+
222
+ ret := 1 // So we loop at least once
223
+ for ret > 0 {
224
+ srcPtr := C .uintptr_t (uintptr (0 )) // Do not point anywhere, if src is empty
225
+ if len (w .srcBuffer ) > 0 {
226
+ srcPtr = C .uintptr_t (uintptr (unsafe .Pointer (& w .srcBuffer [0 ])))
227
+ }
228
+
229
+ C .ZSTD_compressStream2_flush (
230
+ w .resultBuffer ,
231
+ w .ctx ,
232
+ C .uintptr_t (uintptr (unsafe .Pointer (& w .dstBuffer [0 ]))),
233
+ C .size_t (len (w .dstBuffer )),
234
+ srcPtr ,
235
+ C .size_t (len (w .srcBuffer )),
236
+ )
237
+ ret = int (w .resultBuffer .return_code )
238
+ if err := getError (ret ); err != nil {
239
+ return err
240
+ }
241
+ w .srcBuffer = w .srcBuffer [w .resultBuffer .bytes_consumed :]
242
+ written := int (w .resultBuffer .bytes_written )
243
+ _ , err := w .underlyingWriter .Write (w .dstBuffer [:written ])
244
+ if err != nil {
245
+ return err
246
+ }
247
+
248
+ if ret > 0 { // We have a hint if we need to resize the dstBuffer
249
+ w .dstBuffer = w .dstBuffer [:cap (w .dstBuffer )]
250
+ if len (w .dstBuffer ) < ret {
251
+ w .dstBuffer = make ([]byte , ret )
252
+ }
253
+ }
254
+ }
255
+
256
+ return nil
257
+ }
258
+
206
259
// Close closes the Writer, flushing any unwritten data to the underlying
207
260
// io.Writer and freeing objects, but does not close the underlying io.Writer.
208
261
func (w * Writer ) Close () error {
@@ -231,7 +284,11 @@ func (w *Writer) Close() error {
231
284
}
232
285
w .srcBuffer = w .srcBuffer [w .resultBuffer .bytes_consumed :]
233
286
written := int (w .resultBuffer .bytes_written )
234
- w .underlyingWriter .Write (w .dstBuffer [:written ])
287
+ _ , err := w .underlyingWriter .Write (w .dstBuffer [:written ])
288
+ if err != nil {
289
+ C .ZSTD_freeCStream (w .ctx )
290
+ return err
291
+ }
235
292
236
293
if ret > 0 { // We have a hint if we need to resize the dstBuffer
237
294
w .dstBuffer = w .dstBuffer [:cap (w .dstBuffer )]
0 commit comments