static SquashMSCompStream* squash_ms_stream_new (SquashCodec* codec, SquashStreamType stream_type, SquashOptions* options) { SquashMSCompStream* stream; assert (codec != NULL); assert (stream_type == SQUASH_STREAM_COMPRESS || stream_type == SQUASH_STREAM_DECOMPRESS); stream = squash_malloc (sizeof (SquashMSCompStream)); if (SQUASH_UNLIKELY(stream == NULL)) return (squash_error (SQUASH_MEMORY), NULL); squash_ms_stream_init (stream, codec, stream_type, options, squash_ms_stream_destroy); MSCompStatus status; MSCompFormat format = squash_ms_format_from_codec (codec); if (stream->base_object.stream_type == SQUASH_STREAM_COMPRESS) { status = ms_deflate_init (format, &(stream->mscomp)); } else { status = ms_inflate_init (format, &(stream->mscomp)); } if (SQUASH_UNLIKELY(status != MSCOMP_OK)) { squash_object_unref (stream); return (squash_error (squash_ms_status_to_squash_status (status)), NULL); } return stream; }
static SquashStatus squash_ms_decompress_buffer (SquashCodec* codec, size_t* decompressed_length, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_length)], size_t compressed_length, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_length)], SquashOptions* options) { MSCompStatus status = ms_decompress (squash_ms_format_from_codec (codec), compressed, compressed_length, decompressed, decompressed_length); return squash_ms_status_to_squash_status (status); }
static SquashStatus squash_ms_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { MSCompStatus status = ms_compress (squash_ms_format_from_codec (codec), uncompressed, uncompressed_size, compressed, compressed_size); return squash_ms_status_to_squash_status (status); }
static SquashStatus squash_ms_process_stream (SquashStream* stream, SquashOperation operation) { SquashStatus status = SQUASH_FAILED; MSCompStatus res; SquashMSCompStream* s = (SquashMSCompStream*) stream; uint8_t nul_buf; s->mscomp.in = stream->next_in; s->mscomp.in_avail = stream->avail_in; s->mscomp.out = stream->next_out; s->mscomp.out_avail = stream->avail_out; if (s->mscomp.in == NULL) { s->mscomp.in = &nul_buf; } if (stream->stream_type == SQUASH_STREAM_COMPRESS) { res = ms_deflate(&(s->mscomp), squash_ms_comp_flush_from_operation (operation)); } else { res = ms_inflate(&(s->mscomp)); } stream->next_in = s->mscomp.in; stream->avail_in = s->mscomp.in_avail; stream->next_out = s->mscomp.out; stream->avail_out = s->mscomp.out_avail; switch (stream->stream_type) { case SQUASH_STREAM_COMPRESS: switch (operation) { case SQUASH_OPERATION_PROCESS: switch ((int) res) { case MSCOMP_OK: status = (stream->avail_in == 0) ? SQUASH_OK : SQUASH_PROCESSING; break; default: status = squash_ms_status_to_squash_status (res); break; } break; case SQUASH_OPERATION_FLUSH: switch ((int) res) { case MSCOMP_OK: status = SQUASH_OK; break; default: status = squash_ms_status_to_squash_status (res); break; } break; case SQUASH_OPERATION_FINISH: switch ((int) res) { case MSCOMP_OK: status = SQUASH_PROCESSING; break; case MSCOMP_STREAM_END: status = SQUASH_OK; break; default: status = squash_ms_status_to_squash_status (res); break; } break; case SQUASH_OPERATION_TERMINATE: squash_assert_unreachable (); break; } break; case SQUASH_STREAM_DECOMPRESS: switch (operation) { case SQUASH_OPERATION_PROCESS: case SQUASH_OPERATION_FLUSH: case SQUASH_OPERATION_FINISH: switch ((int) res) { case MSCOMP_OK: case MSCOMP_POSSIBLE_STREAM_END: status = (stream->avail_in == 0 && stream->avail_out > 0) ? SQUASH_OK : SQUASH_PROCESSING; break; default: status = squash_ms_status_to_squash_status (res); break; } break; case SQUASH_OPERATION_TERMINATE: squash_assert_unreachable (); } break; } return status; }