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

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

mercurial