mozglue/linker/SeekableZStream.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef SeekableZStream_h
     6 #define SeekableZStream_h
     8 #include "Zip.h"
    10 /**
    11  * Seekable compressed stream are created by splitting the original
    12  * decompressed data in small chunks and compress these chunks
    13  * individually.
    14  *
    15  * The seekable compressed file format consists in a header defined below,
    16  * followed by a table of 32-bits words containing the offsets for each
    17  * individual compressed chunk, then followed by the compressed chunks.
    18  */
    20 #pragma pack(1)
    21 struct SeekableZStreamHeader: public Zip::SignedEntity<SeekableZStreamHeader>
    22 {
    23   SeekableZStreamHeader()
    24   : Zip::SignedEntity<SeekableZStreamHeader>(magic)
    25   , totalSize(0), chunkSize(0), dictSize(0), nChunks(0), lastChunkSize(0)
    26   , windowBits(0), filter(0) { }
    28   /* Reuse Zip::SignedEntity to handle the magic number used in the Seekable
    29    * ZStream file format. The magic number is "SeZz". */
    30   static const uint32_t magic = 0x7a5a6553;
    32   /* Total size of the stream, including the 4 magic bytes. */
    33   le_uint32 totalSize;
    35   /* Chunk size */
    36   le_uint16 chunkSize;
    38   /* Size of the dictionary */
    39   le_uint16 dictSize;
    41   /* Number of chunks */
    42   le_uint32 nChunks;
    44   /* Size of last chunk (> 0, <= Chunk size) */
    45   le_uint16 lastChunkSize;
    47   /* windowBits value used when deflating */
    48   signed char windowBits;
    50   /* Filter Id */
    51   unsigned char filter;
    52 };
    53 #pragma pack()
    55 static_assert(sizeof(SeekableZStreamHeader) == 5 * 4,
    56               "SeekableZStreamHeader should be 5 32-bits words");
    58 /**
    59  * Helper class used to decompress Seekable ZStreams.
    60  */
    61 class SeekableZStream {
    62 public:
    63   /* Initialize from the given buffer. Returns whether initialization
    64    * succeeded (true) or failed (false). */
    65   bool Init(const void *buf, size_t length);
    67   /* Decompresses starting from the given chunk. The decompressed data is
    68    * stored at the given location. The given length, in bytes, indicates
    69    * how much data to decompress. If length is 0, then exactly one chunk
    70    * is decompressed.
    71    * Returns whether decompression succeeded (true) or failed (false). */
    72   bool Decompress(void *where, size_t chunk, size_t length = 0);
    74   /* Decompresses the given chunk at the given address. If a length is given,
    75    * only decompresses that amount of data instead of the entire chunk.
    76    * Returns whether decompression succeeded (true) or failed (false). */
    77   bool DecompressChunk(void *where, size_t chunk, size_t length = 0);
    79   /* Returns the uncompressed size of the complete zstream */
    80   const size_t GetUncompressedSize() const
    81   {
    82     return (offsetTable.numElements() - 1) * chunkSize + lastChunkSize;
    83   }
    85   /* Returns the chunk size of the given chunk */
    86   const size_t GetChunkSize(size_t chunk = 0) const {
    87     return (chunk == offsetTable.numElements() - 1) ? lastChunkSize : chunkSize;
    88   }
    90   /* Returns the number of chunks */
    91   const size_t GetChunksNum() const {
    92     return offsetTable.numElements();
    93   }
    95   /**
    96    * Filters used to improve compression rate.
    97    */
    98   enum FilterDirection {
    99     FILTER,
   100     UNFILTER
   101   };
   102   typedef void (*ZStreamFilter)(off_t, FilterDirection,
   103                                   unsigned char *, size_t);
   105   enum FilterId {
   106     NONE,
   107     BCJ_THUMB,
   108     BCJ_ARM,
   109     BCJ_X86,
   110     FILTER_MAX
   111   };
   112   static ZStreamFilter GetFilter(FilterId id);
   114   static ZStreamFilter GetFilter(uint16_t id) {
   115     return GetFilter(static_cast<FilterId>(id));
   116   }
   118 private:
   119   /* RAW Seekable SZtream buffer */
   120   const unsigned char *buffer;
   122   /* Total size of the stream, including the 4 magic bytes. */
   123   uint32_t totalSize;
   125   /* Chunk size */
   126   uint32_t chunkSize;
   128   /* Size of last chunk (> 0, <= Chunk size) */
   129   uint32_t lastChunkSize;
   131   /* windowBits value used when deflating */
   132   int windowBits;
   134   /* Offsets table */
   135   Array<le_uint32> offsetTable;
   137   /* Filter */
   138   ZStreamFilter filter;
   140   /* Deflate dictionary */
   141   Array<unsigned char> dictionary;
   142 };
   144 inline void
   145 operator++(SeekableZStream::FilterId &other)
   146 {
   147   const int orig = static_cast<int>(other);
   148   other = static_cast<SeekableZStream::FilterId>(orig + 1);
   149 }
   151 #endif /* SeekableZStream_h */

mercurial