OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "bin/gzip.h" | |
6 | |
7 #include "platform/assert.h" | |
8 #include "platform/globals.h" | |
9 #include "zlib/zlib.h" | |
10 | |
11 namespace dart { | |
12 namespace bin { | |
13 | |
14 void Decompress(const uint8_t* input, | |
15 intptr_t input_len, | |
16 uint8_t** output, | |
17 intptr_t* output_length) { | |
18 ASSERT(input != NULL); | |
19 ASSERT(input_len > 0); | |
20 ASSERT(output != NULL); | |
21 ASSERT(output_length != NULL); | |
22 | |
23 // Initialize output. | |
24 *output = NULL; | |
25 *output_length = 0; | |
26 | |
27 const unsigned int kChunkSize = 256 * 1024; | |
28 uint8_t chunk_out[kChunkSize]; | |
29 z_stream strm; | |
30 strm.zalloc = Z_NULL; | |
31 strm.zfree = Z_NULL; | |
32 strm.opaque = Z_NULL; | |
33 strm.avail_in = 0; | |
34 strm.next_in = 0; | |
35 int ret = inflateInit2(&strm, 32 + MAX_WBITS); | |
36 ASSERT(ret == Z_OK); | |
37 | |
38 unsigned int input_cursor = 0; | |
39 unsigned int output_cursor = 0; | |
40 do { | |
41 // Setup input. | |
42 unsigned int size_in = input_len - input_cursor; | |
43 if (size_in > kChunkSize) { | |
44 size_in = kChunkSize; | |
45 } | |
46 strm.avail_in = size_in; | |
47 strm.next_in = const_cast<uint8_t*>(&input[input_cursor]); | |
48 | |
49 // Inflate until we've exhausted the current input chunk. | |
50 do { | |
51 // Setup output. | |
52 strm.avail_out = kChunkSize; | |
53 strm.next_out = &chunk_out[0]; | |
54 // Inflate. | |
55 ret = inflate(&strm, Z_SYNC_FLUSH); | |
56 // We either hit the end of the stream or made forward progress. | |
57 ASSERT((ret == Z_STREAM_END) || (ret == Z_OK)); | |
58 // Grow output buffer size. | |
59 unsigned int size_out = kChunkSize - strm.avail_out; | |
60 *output_length += size_out; | |
61 *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length)); | |
zra
2017/08/04 05:17:00
This is probably fine when there are only a couple
rmacnak
2017/08/10 21:09:09
Switched to exponential growth, but it doesn't hav
| |
62 // Copy output. | |
63 memmove(&((*output)[output_cursor]), &chunk_out[0], size_out); | |
64 output_cursor += size_out; | |
65 } while (strm.avail_out == 0); | |
66 | |
67 // We've processed size_in bytes. | |
68 input_cursor += size_in; | |
69 | |
70 // We're finished decompressing when zlib tells us. | |
71 } while (ret != Z_STREAM_END); | |
72 | |
73 inflateEnd(&strm); | |
74 } | |
75 | |
76 void Compress(const uint8_t* input, | |
zra
2017/08/04 05:17:00
Is this used anywhere?
rmacnak
2017/08/10 21:09:09
Not anymore, removed.
| |
77 intptr_t input_len, | |
78 uint8_t** output, | |
79 intptr_t* output_length) { | |
80 ASSERT(input != NULL); | |
81 ASSERT(input_len > 0); | |
82 ASSERT(output != NULL); | |
83 ASSERT(output_length != NULL); | |
84 | |
85 // Initialize output. | |
86 *output = NULL; | |
87 *output_length = 0; | |
88 | |
89 const unsigned int kChunkSize = 256 * 1024; | |
90 uint8_t chunk_out[kChunkSize]; | |
91 z_stream strm; | |
92 strm.zalloc = Z_NULL; | |
93 strm.zfree = Z_NULL; | |
94 strm.opaque = Z_NULL; | |
95 strm.avail_in = 0; | |
96 strm.next_in = 0; | |
97 | |
98 int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION); | |
99 ASSERT(ret == Z_OK); | |
100 | |
101 unsigned int input_cursor = 0; | |
102 unsigned int output_cursor = 0; | |
103 do { | |
104 // Setup input. | |
105 unsigned int size_in = input_len - input_cursor; | |
106 bool end = true; | |
107 if (size_in > kChunkSize) { | |
108 size_in = kChunkSize; | |
109 end = false; | |
110 } | |
111 strm.avail_in = size_in; | |
112 strm.next_in = const_cast<uint8_t*>(&input[input_cursor]); | |
113 | |
114 // Deflate until we've exhausted the current input chunk. | |
115 do { | |
116 // Setup output. | |
117 strm.avail_out = kChunkSize; | |
118 strm.next_out = &chunk_out[0]; | |
119 // Deflate. | |
120 ret = deflate(&strm, end ? Z_FINISH : Z_NO_FLUSH); | |
121 // We either hit the end of the stream or made forward progress. | |
122 ASSERT((ret == Z_STREAM_END) || (ret == Z_BUF_ERROR) || (ret == Z_OK)); | |
123 // Grow output buffer size. | |
124 unsigned int size_out = kChunkSize - strm.avail_out; | |
125 *output_length += size_out; | |
126 *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length)); | |
127 // Copy output. | |
128 memmove(&((*output)[output_cursor]), &chunk_out[0], size_out); | |
129 output_cursor += size_out; | |
130 } while (strm.avail_out == 0); | |
131 | |
132 // We've processed size_in bytes. | |
133 input_cursor += size_in; | |
134 | |
135 // We're finished decompressing when zlib tells us. | |
136 } while (ret != Z_STREAM_END); | |
137 | |
138 deflateEnd(&strm); | |
139 } | |
140 | |
141 } // namespace bin | |
142 } // namespace dart | |
OLD | NEW |