diff options
author | Chris Johns <chrisj@rtems.org> | 2014-09-13 12:09:16 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2014-09-13 12:09:16 +1000 |
commit | 87e0e76be5b17d1dd27274d58ac9b58cdf71c0ca (patch) | |
tree | 0d44623ad165fa69cd0946f2baab79339b3e6215 /rtemstoolkit/rld-compression.h | |
parent | 749ddf1ed53c3903823eed031649441a59edd264 (diff) |
Refactor code into the RTEMS Toolkit.
Diffstat (limited to 'rtemstoolkit/rld-compression.h')
-rw-r--r-- | rtemstoolkit/rld-compression.h | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/rtemstoolkit/rld-compression.h b/rtemstoolkit/rld-compression.h new file mode 100644 index 0000000..4710845 --- /dev/null +++ b/rtemstoolkit/rld-compression.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2012, Chris Johns <chrisj@rtems.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** + * @file + * + * @ingroup rtems-ld + * + * @brief RTEMS Linker compression handles compressed images. + * + */ + +#if !defined (_RLD_COMPRESSION_H_) +#define _RLD_COMPRESSION_H_ + +#include <rld-files.h> + +namespace rld +{ + namespace compress + { + /** + * A compressor. + */ + class compressor + { + public: + /** + * Construct the compressor for the given image. + * + * @param image The image to read or write to. + * @param size The size of the input and output buffers. + * @param out The compressor is compressing. + * @param compress Set to false to disable compression. + */ + compressor (files::image& image, + size_t size, + bool out = true, + bool compress = true); + + /** + * Destruct the compressor. + */ + ~compressor (); + + /** + * Write the data to the output buffer and once the image buffer is full + * compress and write the compressed data to the image. + * + * @param data The data to write to the image compressed + * @param length The mount of data in bytes to write. + */ + void write (const void* data, size_t length); + + /** + * Write the section of the input image file to the output buffer and + * once the image buffer is full compress and write the compressed data + * to the image. + * + * @param input The input image. + * @param offset The input image offset to read from. + * @param length The mount of data in bytes to write. + */ + void write (files::image& input, off_t offset, size_t length); + + /** + * Flush the output buffer is data is present. + */ + void flush (); + + /** + * Read the compressed data into the input buffer and return the section + * requested. + * + * @param data Write the decompressed data here. + * @param length The mount of data in bytes to read. + * @return size_t The amount of data read. + */ + size_t read (void* data, size_t length); + + /** + * Read the decompressed data writing it to the image. + * + * @param output_ The output image. + * @param offset The output image offset to write from. + * @param length The mount of data in bytes to read. + * @return size_t The amount of data read. + */ + size_t read (files::image& output_, off_t offset, size_t length); + + /** + * Read the decompressed data writing it to the image. + * + * @param output_ The output image. + * @param length The mount of data in bytes to read. + * @return size_t The amount of data read. + */ + size_t read (files::image& output_, size_t length); + + /** + * The amount of uncompressed data transferred. + * + * @return size_t The amount of data tranferred. + */ + size_t transferred () const; + + /** + * The amount of compressed data transferred. + * + * @return size_t The amount of compressed data tranferred. + */ + size_t compressed () const; + + /** + * The current offset in the stream. + * + * @return off_t The current uncompressed offset. + */ + off_t offset () const; + + private: + + /** + * Output the block of data to the output file with the block header. + * + * @param forced If true output the buffer. + */ + void output (bool forced = false); + + /** + * Input a block of compressed data and decompress it. + */ + void input (); + + files::image& image; //< The image to read or write to or from. + size_t size; //< The size of the buffer. + bool out; //< If true the it is compression. + bool compress; //< If true compress the data. + uint8_t* buffer; //< The decompressed buffer + uint8_t* io; //< The I/O buffer. + size_t level; //< The amount of data in the buffer. + size_t total; //< The amount of uncompressed data + // transferred. + size_t total_compressed; //< The amount of compressed data + // transferred. + }; + + /** + * Compressor template function for writing data to the compressor. + */ + template < typename T > + void write (compressor& comp, const T value) + { + uint8_t bytes[sizeof (T)]; + T v = value; + int b = sizeof (T) - 1; + while (b >= 0) + { + bytes[b--] = (uint8_t) v; + v >>= 8; + } + comp.write (bytes, sizeof (T)); + } + + /** + * Compressor template function for reading data from the compressor. + */ + template < typename T > + T read (compressor& comp) + { + uint8_t bytes[sizeof (T)]; + T v = 0; + uint32_t b = 0; + if (comp.read (bytes, sizeof (T)) != sizeof (T)) + throw rld::error ("Reading of value failed", "compression"); + while (b < sizeof (T)) + { + v = (v << 8) | ((T) bytes[b++]); + } + return v; + } + + } +} + +static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, + const uint64_t value) { + rld::compress::write < uint64_t > (comp, value); + return comp; +} + +static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, + const uint32_t value) { + rld::compress::write < uint32_t > (comp, value); + return comp; +} + +static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp, + const std::string& str) { + comp.write (str.c_str (), str.size ()); + return comp; +} + +static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp, + uint64_t& value) { + value = rld::compress::read < uint64_t > (comp); + return comp; +} + +static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp, + uint32_t& value) { + value = rld::compress::read < uint32_t > (comp); + return comp; +} + +#endif |