190 squash_stream_thread_func (SquashStream* stream) {
 
  191   SquashStreamPrivate* priv = stream->priv;
 
  194   mtx_lock (&(priv->io_mtx));
 
  196   cnd_signal (&(priv->result_cnd));
 
  198   while ((operation = priv->request) == SQUASH_OPERATION_INVALID) {
 
  199     cnd_wait (&(priv->request_cnd), &(priv->io_mtx));
 
  201   priv->request = SQUASH_OPERATION_INVALID;
 
  203   priv->result = stream->codec->impl.process_stream (stream, operation);
 
  204   priv->finished = 
true;
 
  205   cnd_signal (&(priv->result_cnd));
 
  206   mtx_unlock (&(priv->io_mtx));
 
  224   SquashStreamPrivate* priv = stream->priv;
 
  227   priv->result = status;
 
  228   cnd_signal (&(priv->result_cnd));
 
  229   mtx_unlock (&(priv->io_mtx));
 
  233   mtx_lock (&(priv->io_mtx));
 
  234   while ((operation = priv->request) == SQUASH_OPERATION_INVALID) {
 
  235     cnd_wait (&(priv->request_cnd), &(priv->io_mtx));
 
  237   priv->request = SQUASH_OPERATION_INVALID;
 
  242 squash_stream_send_to_thread (SquashStream* stream, 
SquashOperation operation) {
 
  243   SquashStreamPrivate* priv = stream->priv;
 
  246   priv->request = operation;
 
  247   cnd_signal (&(priv->request_cnd));
 
  248   mtx_unlock (&(priv->io_mtx));
 
  250   mtx_lock (&(priv->io_mtx));
 
  251   while ((result = priv->result) == SQUASH_STATUS_INVALID) {
 
  252     cnd_wait (&(priv->result_cnd), &(priv->io_mtx));
 
  254   priv->result = SQUASH_STATUS_INVALID;
 
  256   if (priv->finished == 
true) {
 
  257     mtx_unlock (&(priv->io_mtx));
 
  258     thrd_join (priv->thread, NULL);
 
  280                     SquashOptions* options,
 
  284   assert (stream != NULL);
 
  286   s = (SquashStream*) stream;
 
  300   s->stream_type = stream_type;
 
  301   s->state = SQUASH_STREAM_STATE_IDLE;
 
  304   s->destroy_user_data = NULL;
 
  307     s->priv = malloc (
sizeof (SquashStreamPrivate));
 
  309     mtx_init (&(s->priv->io_mtx), mtx_plain);
 
  310     mtx_lock (&(s->priv->io_mtx));
 
  312     s->priv->request = SQUASH_OPERATION_INVALID;
 
  313     cnd_init (&(s->priv->request_cnd));
 
  315     s->priv->result = SQUASH_STATUS_INVALID;
 
  316     cnd_init (&(s->priv->result_cnd));
 
  318     s->priv->finished = 
false;
 
  322       thrd_create (&(s->priv->thread), (thrd_start_t) squash_stream_thread_func, s);
 
  323     assert (res == thrd_success);
 
  325     while (s->priv->result == SQUASH_STATUS_INVALID)
 
  326       cnd_wait (&(s->priv->result_cnd), &(s->priv->io_mtx));
 
  327     s->priv->result = SQUASH_STATUS_INVALID;
 
  345   assert (stream != NULL);
 
  347   s = (SquashStream*) stream;
 
  349   if (SQUASH_UNLIKELY(s->priv != NULL)) {
 
  350     SquashStreamPrivate* priv = (SquashStreamPrivate*) s->priv;
 
  352     if (!priv->finished) {
 
  355     cnd_destroy (&(priv->request_cnd));
 
  356     cnd_destroy (&(priv->result_cnd));
 
  357     mtx_destroy (&(priv->io_mtx));
 
  362   if (s->destroy_user_data != NULL && s->user_data != NULL) {
 
  363     s->destroy_user_data (s->user_data);
 
  366   if (s->options != NULL) {
 
  385   va_list options_list;
 
  386   SquashStream* stream;
 
  388   va_start (options_list, stream_type);
 
  390   va_end (options_list);
 
  408   SquashCodec* codec_real;
 
  411   if (codec_real == NULL) {
 
  435                     const char* 
const* keys,
 
  436                     const char* 
const* values) {
 
  451                                 SquashOptions* options) {
 
  452   SquashCodec* codec_real;
 
  454   assert (codec != NULL);
 
  458   return (codec_real != NULL) ?
 
  474   assert (codec != NULL);
 
  476   va_list options_list;
 
  479   va_start (options_list, stream_type);
 
  481   va_end (options_list);
 
  497                                       SquashOptions* options) {
 
  502 squash_stream_process_internal (SquashStream* stream, 
SquashOperation operation) {
 
  504   SquashCodecImpl* impl = NULL;
 
  507   SquashStreamPrivate* priv = (SquashStreamPrivate*) stream->priv;
 
  509   assert (stream != NULL);
 
  510   codec = stream->codec;
 
  511   assert (codec != NULL);
 
  513   assert (impl != NULL);
 
  545   switch (stream->state) {
 
  546     case SQUASH_STREAM_STATE_IDLE:
 
  547     case SQUASH_STREAM_STATE_RUNNING:
 
  550     case SQUASH_STREAM_STATE_FLUSHING:
 
  553     case SQUASH_STREAM_STATE_FINISHING:
 
  556     case SQUASH_STREAM_STATE_FINISHED:
 
  561   if (current_operation > operation) {
 
  565   const size_t avail_in = stream->avail_in;
 
  566   const size_t avail_out = stream->avail_out;
 
  592   uint8_t* next_out = NULL;
 
  593   uint8_t output_sbb = 0;
 
  594   if (stream->avail_out == 0) {
 
  595     next_out = stream->next_out;
 
  596     stream->avail_out = 1;
 
  597     stream->next_out = &output_sbb;
 
  600   while (current_operation <= operation) {
 
  603       if (stream->avail_in == 0 && stream->state == SQUASH_STREAM_STATE_IDLE) {
 
  606         res = squash_stream_send_to_thread (stream, current_operation);
 
  607       } 
else if (impl->process_stream != NULL) {
 
  608         res = impl->process_stream (stream, current_operation);
 
  610         res = squash_buffer_stream_process ((SquashBufferStream*) stream);
 
  614       if (current_operation == operation) {
 
  617             res = squash_stream_send_to_thread (stream, current_operation);
 
  618           } 
else if (impl->process_stream == NULL) {
 
  621             res = impl->process_stream (stream, current_operation);
 
  634       if (impl->process_stream != NULL) {
 
  636           if (!(priv->finished))
 
  637             res = squash_stream_send_to_thread (stream, current_operation);
 
  639           res = impl->process_stream (stream, current_operation);
 
  642         res = squash_buffer_stream_finish ((SquashBufferStream*) stream);
 
  655       if (stream->avail_out == 0) {
 
  661       switch (current_operation) {
 
  663           stream->state = SQUASH_STREAM_STATE_RUNNING;
 
  666           stream->state = SQUASH_STREAM_STATE_FLUSHING;
 
  669           stream->state = SQUASH_STREAM_STATE_FINISHING;
 
  672           squash_assert_unreachable ();
 
  677       stream->state = SQUASH_STREAM_STATE_FINISHED;
 
  681       stream->state = SQUASH_STREAM_STATE_IDLE;
 
  689     stream->avail_out = 0;
 
  690     stream->next_out = next_out;
 
  693   stream->total_in += (avail_in - stream->avail_in);
 
  694   stream->total_out += (avail_out - stream->avail_out);
 
SquashStream * squash_codec_create_stream_with_options(SquashCodec *codec, SquashStreamType stream_type, SquashOptions *options)
Create a new stream with existing SquashOptions. 
Performing the requested operation from the current state is not supported. 
The requested operation is not available. 
SquashStatus squash_stream_finish(SquashStream *stream)
Finish writing to a stream. 
SquashOperation squash_stream_yield(SquashStream *stream, SquashStatus status)
Yield execution back to the main thread. 
SquashCodec * squash_get_codec(const char *codec)
Retrieve a SquashCodec. 
SquashStream * squash_stream_new_codec(SquashCodec *codec, SquashStreamType stream_type,...)
Create a new stream using a codec instance. 
void(* SquashDestroyNotify)(void *data)
Callback to be invoked when information data is no longer needed. 
The data is processed in a background thread. 
Reached the end of the stream while decoding. 
SquashStream * squash_stream_newa(const char *codec, SquashStreamType stream_type, const char *const *keys, const char *const *values)
Create a new stream with key/value option arrays. 
Operation partially completed. 
SquashOptions * squash_options_newv(SquashCodec *codec, va_list options)
Create a new group of options from a variadic list. 
SquashStream * squash_stream_new_codec_with_options(SquashCodec *codec, SquashStreamType stream_type, SquashOptions *options)
Create a new stream using codec and options intances. 
SquashCodecImpl * squash_codec_get_impl(SquashCodec *codec)
Get the codec's function table. 
Insufficient space in buffer. 
Continue processing the stream normally. 
void * squash_object_unref(void *obj)
Decrement the reference count on an object. 
SquashStream * squash_stream_newv(const char *codec, SquashStreamType stream_type, va_list options)
Create a new stream with a variadic list of options. 
SquashStatus squash_stream_flush(SquashStream *stream)
Flush a stream. 
void squash_stream_init(void *stream, SquashCodec *codec, SquashStreamType stream_type, SquashOptions *options, SquashDestroyNotify destroy_notify)
Initialize a stream. 
SquashStatus
Status codes. 
SquashStream * squash_stream_new_with_options(const char *codec, SquashStreamType stream_type, SquashOptions *options)
Create a new stream with options. 
SquashOperation
Operations to perform on a stream. 
SquashStatus squash_error(SquashStatus status)
Emit an error. 
void squash_stream_destroy(void *stream)
Destroy a stream. 
void * squash_object_ref(void *obj)
Increment the reference count on an object. 
SquashStream * squash_stream_new(const char *codec, SquashStreamType stream_type,...)
Create a new stream. 
SquashStatus squash_stream_process(SquashStream *stream)
Process a stream. 
Finish processing the stream. 
Operation completed successfully. 
void squash_object_destroy(void *obj)
Destroy an object. 
SquashStreamType
Stream type. 
void squash_object_init(void *obj, bool is_floating, SquashDestroyNotify destroy_notify)
Initialize a new object.