diff options
author | Chris Johns <chrisj@rtems.org> | 2012-12-21 17:08:17 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-12-21 17:08:17 +1100 |
commit | 437d1ff26efa1087407f260f4a4dffec4e849848 (patch) | |
tree | 2ef70152eda2bdcf70e54b24737997e20ff9f2de /rld-compression.cpp | |
parent | 9f45219a18a32f59c25bd78669c862c018911719 (diff) |
Decompressor fixes.
Make reading compressed files more robust returning the amount
of data that can be read. Also add >> operartors to get the
data. Add exceptions when a read fails.
Diffstat (limited to 'rld-compression.cpp')
-rw-r--r-- | rld-compression.cpp | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/rld-compression.cpp b/rld-compression.cpp index ece73de..2abeff1 100644 --- a/rld-compression.cpp +++ b/rld-compression.cpp @@ -124,7 +124,7 @@ namespace rld } } - void + size_t compressor::read (void* data_, size_t length) { if (out) @@ -132,10 +132,15 @@ namespace rld uint8_t* data = static_cast <uint8_t*> (data_); + size_t amount = 0; + while (length) { input (); + if (level == 0) + break; + size_t appending; if (length > level) @@ -144,15 +149,19 @@ namespace rld appending = length; ::memcpy (data, buffer, appending); + ::memmove (buffer, buffer + appending, level - appending); data += appending; level -= appending; length -= appending; total += appending; + amount += appending; } + + return amount; } - void + size_t compressor::read (files::image& output_, off_t offset, size_t length) { if (out) @@ -160,10 +169,24 @@ namespace rld output_.seek (offset); + return read (output_, length); + } + + size_t + compressor::read (files::image& output_, size_t length) + { + if (out) + throw rld::error ("Read on write-only", "compression"); + + size_t amount = 0; + while (length) { input (); + if (level == 0) + break; + size_t appending; if (length > level) @@ -173,10 +196,15 @@ namespace rld output_.write (buffer, appending); + ::memmove (buffer, buffer + appending, level - appending); + level -= appending; length -= appending; total += appending; + amount += appending; } + + return amount; } void @@ -197,6 +225,12 @@ namespace rld return total_compressed; } + off_t + compressor::offset () const + { + return total; + } + void compressor::output (bool forced) { @@ -237,21 +271,25 @@ namespace rld { uint8_t header[2]; - image.read (header, 2); - - uint32_t block_size = (((uint32_t) header[0]) << 8) | (uint32_t) header[1]; + if (image.read (header, 2) == 2) + { + uint32_t block_size = + (((uint32_t) header[0]) << 8) | (uint32_t) header[1]; - if (block_size == 0) - throw rld::error ("Block size is invalid (0)", "compression"); + if (block_size == 0) + throw rld::error ("Block size is invalid (0)", "compression"); - total_compressed += 2 + block_size; + total_compressed += 2 + block_size; - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rtl: decomp: block-size=" << block_size << std::endl; + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + std::cout << "rtl: decomp: block-size=" << block_size + << std::endl; - image.read (io, block_size); + if (image.read (io, block_size) != block_size) + throw rld::error ("Read past end", "compression"); - level = ::fastlz_decompress (io, block_size, buffer, size); + level = ::fastlz_decompress (io, block_size, buffer, size); + } } else { |