Index: src/OFInflateStream.m ================================================================== --- src/OFInflateStream.m +++ src/OFInflateStream.m @@ -104,20 +104,21 @@ static const uint8_t codeLengthsOrder[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static struct of_huffman_tree *fixedLitLenTree, *fixedDistTree; -static bool +static OF_INLINE bool tryReadBits(OFInflateStream *stream, uint16_t *bits, uint8_t count) { uint16_t ret = stream->_savedBits; assert(stream->_savedBitsLength < count); for (uint_fast8_t i = stream->_savedBitsLength; i < count; i++) { if OF_UNLIKELY (stream->_bitIndex == 8) { - if (stream->_bufferIndex < stream->_bufferLength) + if OF_LIKELY (stream->_bufferIndex < + stream->_bufferLength) stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { size_t length = [stream->_stream readIntoBuffer: stream->_buffer Index: src/OFLHAArchive_LHStream.m ================================================================== --- src/OFLHAArchive_LHStream.m +++ src/OFLHAArchive_LHStream.m @@ -42,20 +42,21 @@ STATE_BLOCK_DIST_LENGTH, STATE_BLOCK_DIST_LENGTH_EXTRA, STATE_BLOCK_LEN_DIST_PAIR }; -static bool +static OF_INLINE bool tryReadBits(OFLHAArchive_LHStream *stream, uint16_t *bits, uint8_t count) { uint16_t ret = stream->_savedBits; assert(stream->_savedBitsLength < count); for (uint_fast8_t i = stream->_savedBitsLength; i < count; i++) { if OF_UNLIKELY (stream->_bitIndex == 8) { - if (stream->_bufferIndex < stream->_bufferLength) + if OF_LIKELY (stream->_bufferIndex < + stream->_bufferLength) stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { const size_t bufferLength = OF_LHA_ARCHIVE_LHSTREAM_BUFFER_SIZE; Index: src/huffman_tree.h ================================================================== --- src/huffman_tree.h +++ src/huffman_tree.h @@ -18,28 +18,51 @@ #include #include #import "macros.h" +#import "OFInvalidFormatException.h" + OF_ASSUME_NONNULL_BEGIN struct of_huffman_tree { struct of_huffman_tree *_Nullable leaves[2]; uint16_t value; }; + +static OF_INLINE bool +of_huffman_tree_walk(id _Nullable stream, + bool (*bitReader)(id _Nullable, uint16_t *_Nonnull, uint8_t), + struct of_huffman_tree *_Nonnull *_Nonnull tree, uint16_t *_Nonnull value) +{ + struct of_huffman_tree *iter = *tree; + uint16_t bits; + + while (iter->value == 0xFFFF) { + if OF_UNLIKELY (!bitReader(stream, &bits, 1)) { + *tree = iter; + return false; + } + + if OF_UNLIKELY (iter->leaves[bits] == NULL) + @throw [OFInvalidFormatException exception]; + + iter = iter->leaves[bits]; + } + + *value = iter->value; + return true; +} #ifdef __cplusplus extern "C" { #endif extern struct of_huffman_tree *_Nonnull of_huffman_tree_construct( uint8_t lengths[_Nonnull], uint16_t count); extern struct of_huffman_tree *_Nonnull of_huffman_tree_construct_single( uint16_t value); -extern bool of_huffman_tree_walk(id _Nullable stream, - bool (*bitReader)(id _Nullable, uint16_t *_Nonnull, uint8_t), - struct of_huffman_tree *_Nonnull *_Nonnull tree, uint16_t *_Nonnull value); extern void of_huffman_tree_release(struct of_huffman_tree *_Nonnull tree); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/huffman_tree.m ================================================================== --- src/huffman_tree.m +++ src/huffman_tree.m @@ -132,37 +132,14 @@ tree->value = value; return tree; } -bool -of_huffman_tree_walk(id stream, bool (*bitReader)(id, uint16_t *, uint8_t), - struct of_huffman_tree **tree, uint16_t *value) -{ - struct of_huffman_tree *iter = *tree; - uint16_t bits; - - while (iter->value == 0xFFFF) { - if OF_UNLIKELY (!bitReader(stream, &bits, 1)) { - *tree = iter; - return false; - } - - if OF_UNLIKELY (iter->leaves[bits] == NULL) - @throw [OFInvalidFormatException exception]; - - iter = iter->leaves[bits]; - } - - *value = iter->value; - return true; -} - void of_huffman_tree_release(struct of_huffman_tree *tree) { for (uint_fast8_t i = 0; i < 2; i++) if OF_LIKELY (tree->leaves[i] != NULL) of_huffman_tree_release(tree->leaves[i]); free(tree); }