Flutter Engine
The Flutter Engine
gzip.cc
Go to the documentation of this file.
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
8#include "platform/assert.h"
9#include "platform/globals.h"
10#include "zlib/zlib.h"
11
12namespace dart {
13namespace bin {
14
15void Decompress(const uint8_t* input,
16 intptr_t input_len,
17 uint8_t** output,
18 intptr_t* output_length) {
19 ASSERT(input != nullptr);
20 ASSERT(input_len > 0);
21 ASSERT(output != nullptr);
22 ASSERT(output_length != nullptr);
23
24 const intptr_t kChunkSize = 256 * 1024;
25
26 // Initialize output.
27 intptr_t output_capacity = input_len * 2;
28 if (output_capacity < kChunkSize) {
29 output_capacity = kChunkSize;
30 }
31 *output = reinterpret_cast<uint8_t*>(malloc(output_capacity));
32
33 uint8_t* chunk_out = reinterpret_cast<uint8_t*>(malloc(kChunkSize));
34 z_stream strm;
35 strm.zalloc = Z_NULL;
36 strm.zfree = Z_NULL;
37 strm.opaque = Z_NULL;
38 strm.avail_in = 0;
39 strm.next_in = Z_NULL;
40 int ret = inflateInit2(&strm, 32 + MAX_WBITS);
41 ASSERT(ret == Z_OK);
42
43 intptr_t input_cursor = 0;
44 intptr_t output_cursor = 0;
45 do {
46 // Setup input.
47 intptr_t size_in = input_len - input_cursor;
48 if (size_in > kChunkSize) {
49 size_in = kChunkSize;
50 }
51 strm.avail_in = size_in;
52 strm.next_in = const_cast<uint8_t*>(&input[input_cursor]);
53
54 // Inflate until we've exhausted the current input chunk.
55 do {
56 // Setup output.
57 strm.avail_out = kChunkSize;
58 strm.next_out = &chunk_out[0];
59 // Inflate.
60 ret = inflate(&strm, Z_SYNC_FLUSH);
61 // We either hit the end of the stream or made forward progress.
62 ASSERT((ret == Z_STREAM_END) || (ret == Z_OK));
63 // Grow output buffer size.
64 intptr_t size_out = kChunkSize - strm.avail_out;
65 if (size_out > (output_capacity - output_cursor)) {
66 output_capacity *= 2;
67 ASSERT(size_out <= (output_capacity - output_cursor));
68 *output = reinterpret_cast<uint8_t*>(realloc(*output, output_capacity));
69 }
70 // Copy output.
71 memmove(&((*output)[output_cursor]), &chunk_out[0], size_out);
72 output_cursor += size_out;
73 } while (strm.avail_out == 0);
74
75 // We've processed size_in bytes.
76 input_cursor += size_in;
77
78 // We're finished decompressing when zlib tells us.
79 } while (ret != Z_STREAM_END);
80
81 inflateEnd(&strm);
82
83 *output_length = output_cursor;
84 free(chunk_out);
85}
86
87} // namespace bin
88} // namespace dart
#define ASSERT(E)
void Decompress(const uint8_t *input, intptr_t input_len, uint8_t **output, intptr_t *output_length)
Definition: gzip.cc:15
Definition: dart_vm.cc:33
void * malloc(size_t size)
Definition: allocation.cc:19
void * realloc(void *ptr, size_t size)
Definition: allocation.cc:27