| 72 | } |
| 73 | |
| 74 | void ZstdDeflatingWriteBuffer::nextImpl() |
| 75 | { |
| 76 | if (!offset()) |
| 77 | return; |
| 78 | |
| 79 | ZSTD_EndDirective mode = ZSTD_e_flush; |
| 80 | |
| 81 | input.src = reinterpret_cast<unsigned char *>(working_buffer.begin()); |
| 82 | input.size = offset(); |
| 83 | input.pos = 0; |
| 84 | |
| 85 | try |
| 86 | { |
| 87 | bool ended = false; |
| 88 | do |
| 89 | { |
| 90 | out->nextIfAtEnd(); |
| 91 | |
| 92 | output.dst = reinterpret_cast<unsigned char *>(out->buffer().begin()); |
| 93 | output.size = out->buffer().size(); |
| 94 | output.pos = out->offset(); |
| 95 | |
| 96 | |
| 97 | size_t compression_result = ZSTD_compressStream2(cctx, &output, &input, mode); |
| 98 | if (ZSTD_isError(compression_result)) |
| 99 | throw Exception( |
| 100 | ErrorCodes::ZSTD_ENCODER_FAILED, "Zstd stream encoding failed: error: '{}'; zstd version: {}", ZSTD_getErrorName(compression_result), ZSTD_VERSION_STRING); |
| 101 | |
| 102 | out->position() = out->buffer().begin() + output.pos; |
| 103 | |
| 104 | bool everything_was_compressed = (input.pos == input.size); |
| 105 | bool everything_was_flushed = compression_result == 0; |
| 106 | |
| 107 | ended = everything_was_compressed && everything_was_flushed; |
| 108 | } while (!ended); |
| 109 | } |
| 110 | catch (...) |
| 111 | { |
| 112 | /// Do not try to write next time after exception. |
| 113 | out->position() = out->buffer().begin(); |
| 114 | throw; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | void ZstdDeflatingWriteBuffer::finish() |
| 119 | { |