liblzma: Add LZMA_FULL_BARRIER support to single-threaded encoder.

In the single-threaded encoder LZMA_FULL_BARRIER is simply
an alias for LZMA_FULL_FLUSH.
This commit is contained in:
Lasse Collin 2013-10-02 12:55:11 +03:00
parent fef0c6b410
commit 97bb38712f
4 changed files with 54 additions and 11 deletions

View File

@ -240,12 +240,12 @@ typedef enum {
/**
* \brief The `action' argument for lzma_code()
*
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or LZMA_FINISH,
* the same `action' must is used until lzma_code() returns LZMA_STREAM_END.
* Also, the amount of input (that is, strm->avail_in) must not be modified
* by the application until lzma_code() returns LZMA_STREAM_END. Changing the
* `action' or modifying the amount of input will make lzma_code() return
* LZMA_PROG_ERROR.
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER,
* or LZMA_FINISH, the same `action' must is used until lzma_code() returns
* LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must
* not be modified by the application until lzma_code() returns
* LZMA_STREAM_END. Changing the `action' or modifying the amount of input
* will make lzma_code() return LZMA_PROG_ERROR.
*/
typedef enum {
LZMA_RUN = 0,
@ -293,7 +293,7 @@ typedef enum {
*
* All the input data going to the current Block must have
* been given to the encoder (the last bytes can still be
* pending in* next_in). Call lzma_code() with LZMA_FULL_FLUSH
* pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH
* until it returns LZMA_STREAM_END. Then continue normally
* with LZMA_RUN or finish the Stream with LZMA_FINISH.
*
@ -302,6 +302,29 @@ typedef enum {
* no unfinished Block, no empty Block is created.
*/
LZMA_FULL_BARRIER = 4,
/**<
* \brief Finish encoding of the current Block
*
* This is like LZMA_FULL_FLUSH except that this doesn't
* necessarily wait until all the input has been made
* available via the output buffer. That is, lzma_code()
* might return LZMA_STREAM_END as soon as all the input
* has been consumed (avail_in == 0).
*
* LZMA_FULL_BARRIER is useful with a threaded encoder if
* one wants to split the .xz Stream into Blocks at specific
* offsets but doesn't care if the output isn't flushed
* immediately. Using LZMA_FULL_BARRIER allows keeping
* the threads busy while LZMA_FULL_FLUSH would make
* lzma_code() wait until all the threads have finished
* until more data could be passed to the encoder.
*
* With a lzma_stream initialized with the single-threaded
* lzma_stream_encoder() or lzma_easy_encoder(),
* LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH.
*/
LZMA_FINISH = 3
/**<
* \brief Finish the coding operation

View File

@ -176,7 +176,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
|| (strm->next_out == NULL && strm->avail_out != 0)
|| strm->internal == NULL
|| strm->internal->next.code == NULL
|| (unsigned int)(action) > LZMA_FINISH
|| (unsigned int)(action) > LZMA_ACTION_MAX
|| !strm->internal->supported_actions[action])
return LZMA_PROG_ERROR;
@ -211,6 +211,10 @@ lzma_code(lzma_stream *strm, lzma_action action)
case LZMA_FINISH:
strm->internal->sequence = ISEQ_FINISH;
break;
case LZMA_FULL_BARRIER:
strm->internal->sequence = ISEQ_FULL_BARRIER;
break;
}
break;
@ -238,6 +242,13 @@ lzma_code(lzma_stream *strm, lzma_action action)
break;
case ISEQ_FULL_BARRIER:
if (action != LZMA_FULL_BARRIER
|| strm->internal->avail_in != strm->avail_in)
return LZMA_PROG_ERROR;
break;
case ISEQ_END:
return LZMA_STREAM_END;
@ -288,7 +299,9 @@ lzma_code(lzma_stream *strm, lzma_action action)
case LZMA_STREAM_END:
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|| strm->internal->sequence == ISEQ_FULL_FLUSH)
|| strm->internal->sequence == ISEQ_FULL_FLUSH
|| strm->internal->sequence
== ISEQ_FULL_BARRIER)
strm->internal->sequence = ISEQ_RUN;
else
strm->internal->sequence = ISEQ_END;

View File

@ -78,6 +78,10 @@
| LZMA_CONCATENATED )
/// Largest valid lzma_action value as unsigned integer.
#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER))
/// Special return value (lzma_ret) to indicate that a timeout was reached
/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
@ -207,6 +211,7 @@ struct lzma_internal_s {
ISEQ_SYNC_FLUSH,
ISEQ_FULL_FLUSH,
ISEQ_FINISH,
ISEQ_FULL_BARRIER,
ISEQ_END,
ISEQ_ERROR,
} sequence;
@ -217,7 +222,7 @@ struct lzma_internal_s {
size_t avail_in;
/// Indicates which lzma_action values are allowed by next.code.
bool supported_actions[4];
bool supported_actions[LZMA_ACTION_MAX + 1];
/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
/// made (no input consumed and no output produced by next.code).

View File

@ -146,11 +146,12 @@ stream_encode(lzma_coder *coder, const lzma_allocator *allocator,
}
case SEQ_BLOCK_ENCODE: {
static const lzma_action convert[4] = {
static const lzma_action convert[LZMA_ACTION_MAX + 1] = {
LZMA_RUN,
LZMA_SYNC_FLUSH,
LZMA_FINISH,
LZMA_FINISH,
LZMA_FINISH,
};
const lzma_ret ret = coder->block_encoder.code(
@ -324,6 +325,7 @@ lzma_stream_encoder(lzma_stream *strm,
strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
strm->internal->supported_actions[LZMA_FINISH] = true;
return LZMA_OK;