Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: runtime/bin/filter.cc

Issue 130513003: [ZLIB] Add support for windowBits, memLevel, raw (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix dictionary memory management Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/dartutils.h" 5 #include "bin/dartutils.h"
6 #include "bin/filter.h" 6 #include "bin/filter.h"
7 #include "bin/io_buffer.h" 7 #include "bin/io_buffer.h"
8 8
9 #include "include/dart_api.h" 9 #include "include/dart_api.h"
10 10
11
12 namespace dart { 11 namespace dart {
13 namespace bin { 12 namespace bin {
14 13
15 const int kZlibFlagMemUsage = 8;
16 const int kZLibFlagWindowBits = 15;
17 const int kZLibFlagUseGZipHeader = 16; 14 const int kZLibFlagUseGZipHeader = 16;
18 const int kZLibFlagAcceptAnyHeader = 32; 15 const int kZLibFlagAcceptAnyHeader = 32;
19 16
20 static const int kFilterPointerNativeField = 0; 17 static const int kFilterPointerNativeField = 0;
21 18
22 Filter* GetFilter(Dart_Handle filter_obj) { 19 static Filter* GetFilter(Dart_Handle filter_obj) {
23 Filter* filter; 20 Filter* filter;
24 Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter); 21 Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter);
25 if (Dart_IsError(result)) { 22 if (Dart_IsError(result)) {
26 Dart_PropagateError(result); 23 Dart_PropagateError(result);
27 } 24 }
28 if (filter == NULL) { 25 if (filter == NULL) {
29 Dart_ThrowException(DartUtils::NewInternalError("Filter destroyed")); 26 Dart_ThrowException(DartUtils::NewInternalError("Filter destroyed"));
30 } 27 }
31 return filter; 28 return filter;
32 } 29 }
33 30
34 void EndFilter(Dart_Handle filter_obj, Filter* filter) { 31 static void EndFilter(Dart_Handle filter_obj, Filter* filter) {
35 Filter::SetFilterPointerNativeField(filter_obj, NULL); 32 Filter::SetFilterPointerNativeField(filter_obj, NULL);
36 delete filter; 33 delete filter;
37 } 34 }
38 35
36 static uint8_t* copyDictionary(Dart_Handle dictionary_obj) {
37 uint8_t* src = NULL;
38 intptr_t size;
39 Dart_TypedData_Type type;
40
41 if (Dart_IsError(Dart_ListLength(dictionary_obj, &size))) {
42 Dart_ThrowException(DartUtils::NewInternalError(
43 "Failed to get the zlib dictionary length"));
44 }
45
46 uint8_t* dictionary = new uint8_t[size];
47
48 if (dictionary == NULL) {
49 Dart_ThrowException(DartUtils::NewInternalError(
50 "Failed to allocate buffer for the zlib dictionary"));
51 }
52
53 Dart_Handle result = Dart_TypedDataAcquireData(
54 dictionary_obj, &type, reinterpret_cast<void**>(&src), &size);
55 if (!Dart_IsError(result)) {
56 memmove(dictionary, src, size);
57 Dart_TypedDataReleaseData(dictionary_obj);
58 } else {
59 if (Dart_IsError(Dart_ListGetAsBytes(dictionary_obj, 0, dictionary,
60 size))) {
61 delete[] dictionary;
62 Dart_ThrowException(DartUtils::NewInternalError(
63 "Failed to get the zlib dictionary"));
64 }
65 }
66
67 return dictionary;
68 }
69
39 void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) { 70 void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) {
Anders Johnsen 2014/02/04 12:30:45 Please check out the stuff in DartUtils for this m
vicb 2014/02/04 19:55:14 I'll update
40 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); 71 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
41 Filter* filter = new ZLibInflateFilter(); 72 Dart_Handle wBits_obj = Dart_GetNativeArgument(args, 1);
Anders Johnsen 2014/02/04 12:30:45 wBits_obj -> window_bits_obj
vicb 2014/02/04 19:55:14 done
73 int64_t window_bits;
74 if (Dart_IsError(Dart_IntegerToInt64(wBits_obj, &window_bits))) {
75 Dart_ThrowException(DartUtils::NewInternalError(
76 "Failed to get 'windowBits' parameter"));
77 }
78 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 2);
79 uint8_t* dictionary = NULL;
80 if (!Dart_IsNull(dict_obj)) {
81 dictionary = copyDictionary(dict_obj);
82 }
83 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3);
84 bool raw;
85 if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) {
86 Dart_ThrowException(DartUtils::NewInternalError(
87 "Failed to get 'raw' parameter"));
88 }
89 Filter* filter = new ZLibInflateFilter(static_cast<int32_t>(window_bits),
90 dictionary, raw);
42 if (filter == NULL || !filter->Init()) { 91 if (filter == NULL || !filter->Init()) {
43 delete filter; 92 delete filter;
93 delete[] dictionary;
Anders Johnsen 2014/02/04 12:30:45 Double delete if filter failed to init?
vicb 2014/02/04 19:55:14 we throw after delete[]
44 Dart_ThrowException(DartUtils::NewInternalError( 94 Dart_ThrowException(DartUtils::NewInternalError(
45 "Failed to create ZLibInflateFilter")); 95 "Failed to create ZLibInflateFilter"));
46 } 96 }
47 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); 97 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
48 if (Dart_IsError(result)) { 98 if (Dart_IsError(result)) {
49 delete filter; 99 delete filter;
100 delete[] dictionary;
Anders Johnsen 2014/02/04 12:30:45 Double delete, the filter should have ownership he
vicb 2014/02/04 19:55:14 we throw after delete[]
50 Dart_PropagateError(result); 101 Dart_PropagateError(result);
51 } 102 }
52 } 103 }
53 104
54 void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) { 105 void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) {
55 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); 106 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
56 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1); 107 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1);
57 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2);
58 bool gzip; 108 bool gzip;
59 if (Dart_IsError(Dart_BooleanValue(gzip_obj, &gzip))) { 109 if (Dart_IsError(Dart_BooleanValue(gzip_obj, &gzip))) {
Anders Johnsen 2014/02/04 12:30:45 Not your code, but it would be great if you could
60 Dart_ThrowException(DartUtils::NewInternalError( 110 Dart_ThrowException(DartUtils::NewInternalError(
61 "Failed to get 'gzip' parameter")); 111 "Failed to get 'gzip' parameter"));
62 } 112 }
63 int64_t level = 0; 113 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2);
114 int64_t level;
64 Dart_Handle result = Dart_IntegerToInt64(level_obj, &level); 115 Dart_Handle result = Dart_IntegerToInt64(level_obj, &level);
65 if (Dart_IsError(result) || (level < kMinInt32) || (level > kMaxInt32)) { 116 if (Dart_IsError(result) || (level < kMinInt32) || (level > kMaxInt32)) {
66 Dart_ThrowException(DartUtils::NewInternalError( 117 Dart_ThrowException(DartUtils::NewInternalError(
67 "Failed to get 'level' parameter")); 118 "Failed to get 'level' parameter"));
68 } 119 }
69 Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level)); 120 Dart_Handle wBits_obj = Dart_GetNativeArgument(args, 3);
121 int64_t window_bits;
122 if (Dart_IsError(Dart_IntegerToInt64(wBits_obj, &window_bits))) {
123 Dart_ThrowException(DartUtils::NewInternalError(
124 "Failed to get 'windowBits' parameter"));
125 }
126 Dart_Handle mLevel_obj = Dart_GetNativeArgument(args, 4);
127 int64_t mem_level;
128 if (Dart_IsError(Dart_IntegerToInt64(mLevel_obj, &mem_level))) {
129 Dart_ThrowException(DartUtils::NewInternalError(
130 "Failed to get 'memLevel' parameter"));
131 }
132 Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5);
133 int64_t strategy;
134 if (Dart_IsError(Dart_IntegerToInt64(strategy_obj, &strategy))) {
135 Dart_ThrowException(DartUtils::NewInternalError(
136 "Failed to get 'strategy' parameter"));
137 }
138 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 6);
139 uint8_t* dictionary = NULL;
140 if (!Dart_IsNull(dict_obj)) {
141 dictionary = copyDictionary(dict_obj);
142 }
143 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7);
144 bool raw;
145 if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) {
146 Dart_ThrowException(DartUtils::NewInternalError(
147 "Failed to get 'raw' parameter"));
148 }
149 Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level),
150 static_cast<int32_t>(window_bits),
151 static_cast<int32_t>(mem_level),
152 static_cast<int32_t>(strategy),
153 dictionary, raw);
70 if (filter == NULL || !filter->Init()) { 154 if (filter == NULL || !filter->Init()) {
71 delete filter; 155 delete filter;
156 delete[] dictionary;
Anders Johnsen 2014/02/04 12:30:45 Same memory issue here and below.
vicb 2014/02/04 19:55:14 same answer
72 Dart_ThrowException(DartUtils::NewInternalError( 157 Dart_ThrowException(DartUtils::NewInternalError(
73 "Failed to create ZLibDeflateFilter")); 158 "Failed to create ZLibDeflateFilter"));
74 } 159 }
75 result = Filter::SetFilterPointerNativeField(filter_obj, filter); 160 result = Filter::SetFilterPointerNativeField(filter_obj, filter);
76 if (Dart_IsError(result)) { 161 if (Dart_IsError(result)) {
77 delete filter; 162 delete filter;
163 delete[] dictionary;
78 Dart_PropagateError(result); 164 Dart_PropagateError(result);
79 } 165 }
80 } 166 }
81 167
82 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) { 168 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) {
83 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); 169 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
84 Filter* filter = GetFilter(filter_obj); 170 Filter* filter = GetFilter(filter_obj);
85 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1); 171 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
86 intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); 172 intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
87 intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3)); 173 intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } 270 }
185 271
186 272
187 ZLibDeflateFilter::~ZLibDeflateFilter() { 273 ZLibDeflateFilter::~ZLibDeflateFilter() {
188 delete[] current_buffer_; 274 delete[] current_buffer_;
189 if (initialized()) deflateEnd(&stream_); 275 if (initialized()) deflateEnd(&stream_);
190 } 276 }
191 277
192 278
193 bool ZLibDeflateFilter::Init() { 279 bool ZLibDeflateFilter::Init() {
280 int window_bits = window_bits_;
281 if (raw_) {
282 window_bits = -window_bits;
283 } else if (gzip_) {
284 window_bits += kZLibFlagUseGZipHeader;
285 }
286 stream_.next_in = Z_NULL;
194 stream_.zalloc = Z_NULL; 287 stream_.zalloc = Z_NULL;
195 stream_.zfree = Z_NULL; 288 stream_.zfree = Z_NULL;
196 stream_.opaque = Z_NULL; 289 stream_.opaque = Z_NULL;
197 int result = deflateInit2( 290 int result = deflateInit2(&stream_, level_, Z_DEFLATED, window_bits,
198 &stream_, 291 mem_level_, strategy_);
199 level_, 292 if (result != Z_OK) {
200 Z_DEFLATED, 293 return false;
201 kZLibFlagWindowBits | (gzip_ ? kZLibFlagUseGZipHeader : 0),
202 kZlibFlagMemUsage,
203 Z_DEFAULT_STRATEGY);
204 if (result == Z_OK) {
205 set_initialized(true);
206 return true;
207 } 294 }
208 return false; 295 if (dictionary_ != NULL && !gzip_ && !raw_) {
296 result = deflateSetDictionary(&stream_, dictionary_, sizeof(dictionary_));
297 delete[] dictionary_;
298 dictionary_ = NULL;
299 if (result != Z_OK) {
300 return false;
301 }
302 }
303 set_initialized(true);
304 return true;
209 } 305 }
210 306
211 307
212 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) { 308 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) {
213 if (current_buffer_ != NULL) return false; 309 if (current_buffer_ != NULL) return false;
214 stream_.avail_in = length; 310 stream_.avail_in = length;
215 stream_.next_in = current_buffer_ = data; 311 stream_.next_in = current_buffer_ = data;
216 return true; 312 return true;
217 } 313 }
218 314
219 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer, 315 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer,
220 intptr_t length, 316 intptr_t length,
221 bool flush, 317 bool flush,
222 bool end) { 318 bool end) {
223 stream_.avail_out = length; 319 stream_.avail_out = length;
224 stream_.next_out = buffer; 320 stream_.next_out = buffer;
321 bool error = false;
225 switch (deflate(&stream_, 322 switch (deflate(&stream_,
226 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { 323 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
227 case Z_STREAM_END: 324 case Z_STREAM_END:
228 case Z_BUF_ERROR: 325 case Z_BUF_ERROR:
229 case Z_OK: { 326 case Z_OK: {
230 intptr_t processed = length - stream_.avail_out; 327 intptr_t processed = length - stream_.avail_out;
231 if (processed == 0) { 328 if (processed == 0) {
232 delete[] current_buffer_; 329 break;
233 current_buffer_ = NULL;
234 return 0;
235 } else {
236 // We processed data, should be called again.
237 return processed;
238 } 330 }
331 return processed;
239 } 332 }
240 333
241 default: 334 default:
242 case Z_STREAM_ERROR: 335 case Z_STREAM_ERROR:
243 // An error occoured. 336 error = true;
244 delete[] current_buffer_;
245 current_buffer_ = NULL;
246 return -1;
247 } 337 }
338
339 delete[] current_buffer_;
340 current_buffer_ = NULL;
341 // Either 0 Byte processed or either
Anders Johnsen 2014/02/04 12:30:45 // Either 0 bytes processed or error ?
vicb 2014/02/04 19:55:14 oops, right !
342 return error ? -1 : 0;
248 } 343 }
249 344
250 345
251 ZLibInflateFilter::~ZLibInflateFilter() { 346 ZLibInflateFilter::~ZLibInflateFilter() {
Anders Johnsen 2014/02/04 12:30:45 Add delete dictionary_ here as well as in deflate
vicb 2014/02/04 19:55:14 will do. safe as set to null when destroy as part
252 delete[] current_buffer_; 347 delete[] current_buffer_;
253 if (initialized()) inflateEnd(&stream_); 348 if (initialized()) inflateEnd(&stream_);
254 } 349 }
255 350
256 351
257 bool ZLibInflateFilter::Init() { 352 bool ZLibInflateFilter::Init() {
353 int window_bits = raw_ ?
354 -window_bits_ :
355 window_bits_ | kZLibFlagAcceptAnyHeader;
356
357 stream_.next_in = Z_NULL;
358 stream_.avail_in = 0;
258 stream_.zalloc = Z_NULL; 359 stream_.zalloc = Z_NULL;
259 stream_.zfree = Z_NULL; 360 stream_.zfree = Z_NULL;
260 stream_.opaque = Z_NULL; 361 stream_.opaque = Z_NULL;
261 int result = inflateInit2(&stream_, 362 int result = inflateInit2(&stream_, window_bits);
262 kZLibFlagWindowBits | kZLibFlagAcceptAnyHeader); 363 if (result != Z_OK) {
263 if (result == Z_OK) { 364 return false;
264 set_initialized(true);
265 return true;
266 } 365 }
267 return false; 366 set_initialized(true);
367 return true;
268 } 368 }
269 369
270 370
271 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) { 371 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) {
272 if (current_buffer_ != NULL) return false; 372 if (current_buffer_ != NULL) return false;
273 stream_.avail_in = length; 373 stream_.avail_in = length;
274 stream_.next_in = current_buffer_ = data; 374 stream_.next_in = current_buffer_ = data;
275 return true; 375 return true;
276 } 376 }
277 377
278 378
279 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer, 379 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer,
280 intptr_t length, 380 intptr_t length,
281 bool flush, 381 bool flush,
282 bool end) { 382 bool end) {
283 stream_.avail_out = length; 383 stream_.avail_out = length;
284 stream_.next_out = buffer; 384 stream_.next_out = buffer;
385 bool error = false;
285 switch (inflate(&stream_, 386 switch (inflate(&stream_,
286 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { 387 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
287 case Z_STREAM_END: 388 case Z_STREAM_END:
288 case Z_BUF_ERROR: 389 case Z_BUF_ERROR:
289 case Z_OK: { 390 case Z_OK: {
290 intptr_t processed = length - stream_.avail_out; 391 intptr_t processed = length - stream_.avail_out;
291 if (processed == 0) { 392 if (processed == 0) {
292 delete[] current_buffer_; 393 break;
293 current_buffer_ = NULL; 394 }
294 return 0; 395 return processed;
396 }
397
398 case Z_NEED_DICT:
399 if (dictionary_ == NULL) {
400 error = true;
295 } else { 401 } else {
296 // We processed data, should be called again. 402 int result = inflateSetDictionary(&stream_, dictionary_,
297 return processed; 403 sizeof(dictionary_));
404 delete[] dictionary_;
405 dictionary_ = NULL;
406 error = result != Z_OK;
298 } 407 }
299 } 408 if (error) {
409 break;
410 } else {
411 return Processed(buffer, length, flush, end);
412 }
300 413
301 default: 414 default:
302 case Z_MEM_ERROR: 415 case Z_MEM_ERROR:
303 case Z_NEED_DICT:
304 case Z_DATA_ERROR: 416 case Z_DATA_ERROR:
305 case Z_STREAM_ERROR: 417 case Z_STREAM_ERROR:
306 // An error occoured. 418 error = true;
307 delete[] current_buffer_;
308 current_buffer_ = NULL;
309 return -1;
310 } 419 }
420
421 delete[] current_buffer_;
422 current_buffer_ = NULL;
423 // Either 0 Byte processed or either
Anders Johnsen 2014/02/04 12:30:45 Comment.
424 return error ? -1 : 0;
311 } 425 }
312 426
313 } // namespace bin 427 } // namespace bin
314 } // namespace dart 428 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698