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

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: integrate feedback 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) {
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 window_bits_obj = Dart_GetNativeArgument(args, 1);
73 int64_t window_bits = DartUtils::GetIntegerValue(window_bits_obj);
74 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 2);
75 uint8_t* dictionary = NULL;
76 if (!Dart_IsNull(dict_obj)) {
77 dictionary = copyDictionary(dict_obj);
78 }
79 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3);
80 bool raw;
81 if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) {
82 Dart_ThrowException(DartUtils::NewInternalError(
83 "Failed to get 'raw' parameter"));
84 }
85 Filter* filter = new ZLibInflateFilter(static_cast<int32_t>(window_bits),
86 dictionary, raw);
42 if (filter == NULL || !filter->Init()) { 87 if (filter == NULL || !filter->Init()) {
43 delete filter; 88 delete filter;
89 delete[] dictionary;
44 Dart_ThrowException(DartUtils::NewInternalError( 90 Dart_ThrowException(DartUtils::NewInternalError(
45 "Failed to create ZLibInflateFilter")); 91 "Failed to create ZLibInflateFilter"));
46 } 92 }
47 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); 93 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
48 if (Dart_IsError(result)) { 94 if (Dart_IsError(result)) {
49 delete filter; 95 delete filter;
96 delete[] dictionary;
50 Dart_PropagateError(result); 97 Dart_PropagateError(result);
51 } 98 }
52 } 99 }
53 100
54 void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) { 101 void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) {
55 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); 102 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
56 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1); 103 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1);
104 bool gzip = DartUtils::GetBooleanValue(gzip_obj);
57 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2); 105 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2);
58 bool gzip; 106 int64_t level = DartUtils::GetInt64ValueCheckRange(level_obj, kMinInt32,
59 if (Dart_IsError(Dart_BooleanValue(gzip_obj, &gzip))) { 107 kMaxInt32);
60 Dart_ThrowException(DartUtils::NewInternalError( 108 Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 3);
61 "Failed to get 'gzip' parameter")); 109 int64_t window_bits = DartUtils::GetIntegerValue(window_bits_obj);
110 Dart_Handle mLevel_obj = Dart_GetNativeArgument(args, 4);
111 int64_t mem_level = DartUtils::GetIntegerValue(mLevel_obj);
112 Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5);
113 int64_t strategy = DartUtils::GetIntegerValue(strategy_obj);
114 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 6);
115 uint8_t* dictionary = NULL;
116 if (!Dart_IsNull(dict_obj)) {
117 dictionary = copyDictionary(dict_obj);
62 } 118 }
63 int64_t level = 0; 119 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7);
64 Dart_Handle result = Dart_IntegerToInt64(level_obj, &level); 120 bool raw = DartUtils::GetBooleanValue(raw_obj);
65 if (Dart_IsError(result) || (level < kMinInt32) || (level > kMaxInt32)) { 121 Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level),
66 Dart_ThrowException(DartUtils::NewInternalError( 122 static_cast<int32_t>(window_bits),
67 "Failed to get 'level' parameter")); 123 static_cast<int32_t>(mem_level),
68 } 124 static_cast<int32_t>(strategy),
69 Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level)); 125 dictionary, raw);
70 if (filter == NULL || !filter->Init()) { 126 if (filter == NULL || !filter->Init()) {
71 delete filter; 127 delete filter;
128 delete[] dictionary;
Anders Johnsen 2014/02/07 08:18:04 With the addition of 'delete[] dictionary_' in ~*F
vicb 2014/02/07 08:43:45 fixed
72 Dart_ThrowException(DartUtils::NewInternalError( 129 Dart_ThrowException(DartUtils::NewInternalError(
73 "Failed to create ZLibDeflateFilter")); 130 "Failed to create ZLibDeflateFilter"));
74 } 131 }
75 result = Filter::SetFilterPointerNativeField(filter_obj, filter); 132 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
76 if (Dart_IsError(result)) { 133 if (Dart_IsError(result)) {
77 delete filter; 134 delete filter;
135 delete[] dictionary;
78 Dart_PropagateError(result); 136 Dart_PropagateError(result);
79 } 137 }
80 } 138 }
81 139
82 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) { 140 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) {
83 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); 141 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
84 Filter* filter = GetFilter(filter_obj); 142 Filter* filter = GetFilter(filter_obj);
85 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1); 143 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
86 intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); 144 intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
87 intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3)); 145 intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter, 236 Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter,
179 Filter** filter_pointer) { 237 Filter** filter_pointer) {
180 return Dart_GetNativeInstanceField( 238 return Dart_GetNativeInstanceField(
181 filter, 239 filter,
182 kFilterPointerNativeField, 240 kFilterPointerNativeField,
183 reinterpret_cast<intptr_t*>(filter_pointer)); 241 reinterpret_cast<intptr_t*>(filter_pointer));
184 } 242 }
185 243
186 244
187 ZLibDeflateFilter::~ZLibDeflateFilter() { 245 ZLibDeflateFilter::~ZLibDeflateFilter() {
246 delete[] dictionary_;
188 delete[] current_buffer_; 247 delete[] current_buffer_;
189 if (initialized()) deflateEnd(&stream_); 248 if (initialized()) deflateEnd(&stream_);
190 } 249 }
191 250
192 251
193 bool ZLibDeflateFilter::Init() { 252 bool ZLibDeflateFilter::Init() {
253 int window_bits = window_bits_;
254 if (raw_) {
255 window_bits = -window_bits;
256 } else if (gzip_) {
257 window_bits += kZLibFlagUseGZipHeader;
258 }
259 stream_.next_in = Z_NULL;
194 stream_.zalloc = Z_NULL; 260 stream_.zalloc = Z_NULL;
195 stream_.zfree = Z_NULL; 261 stream_.zfree = Z_NULL;
196 stream_.opaque = Z_NULL; 262 stream_.opaque = Z_NULL;
197 int result = deflateInit2( 263 int result = deflateInit2(&stream_, level_, Z_DEFLATED, window_bits,
198 &stream_, 264 mem_level_, strategy_);
199 level_, 265 if (result != Z_OK) {
200 Z_DEFLATED, 266 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 } 267 }
208 return false; 268 if (dictionary_ != NULL && !gzip_ && !raw_) {
269 result = deflateSetDictionary(&stream_, dictionary_, sizeof(dictionary_));
270 delete[] dictionary_;
271 dictionary_ = NULL;
272 if (result != Z_OK) {
273 return false;
274 }
275 }
276 set_initialized(true);
277 return true;
209 } 278 }
210 279
211 280
212 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) { 281 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) {
213 if (current_buffer_ != NULL) return false; 282 if (current_buffer_ != NULL) return false;
214 stream_.avail_in = length; 283 stream_.avail_in = length;
215 stream_.next_in = current_buffer_ = data; 284 stream_.next_in = current_buffer_ = data;
216 return true; 285 return true;
217 } 286 }
218 287
219 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer, 288 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer,
220 intptr_t length, 289 intptr_t length,
221 bool flush, 290 bool flush,
222 bool end) { 291 bool end) {
223 stream_.avail_out = length; 292 stream_.avail_out = length;
224 stream_.next_out = buffer; 293 stream_.next_out = buffer;
294 bool error = false;
225 switch (deflate(&stream_, 295 switch (deflate(&stream_,
226 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { 296 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
227 case Z_STREAM_END: 297 case Z_STREAM_END:
228 case Z_BUF_ERROR: 298 case Z_BUF_ERROR:
229 case Z_OK: { 299 case Z_OK: {
230 intptr_t processed = length - stream_.avail_out; 300 intptr_t processed = length - stream_.avail_out;
231 if (processed == 0) { 301 if (processed == 0) {
232 delete[] current_buffer_; 302 break;
233 current_buffer_ = NULL;
234 return 0;
235 } else {
236 // We processed data, should be called again.
237 return processed;
238 } 303 }
304 return processed;
239 } 305 }
240 306
241 default: 307 default:
242 case Z_STREAM_ERROR: 308 case Z_STREAM_ERROR:
243 // An error occoured. 309 error = true;
244 delete[] current_buffer_;
245 current_buffer_ = NULL;
246 return -1;
247 } 310 }
311
312 delete[] current_buffer_;
313 current_buffer_ = NULL;
314 // Either 0 Byte processed or error
315 return error ? -1 : 0;
248 } 316 }
249 317
250 318
251 ZLibInflateFilter::~ZLibInflateFilter() { 319 ZLibInflateFilter::~ZLibInflateFilter() {
320 delete[] dictionary_;
252 delete[] current_buffer_; 321 delete[] current_buffer_;
253 if (initialized()) inflateEnd(&stream_); 322 if (initialized()) inflateEnd(&stream_);
254 } 323 }
255 324
256 325
257 bool ZLibInflateFilter::Init() { 326 bool ZLibInflateFilter::Init() {
327 int window_bits = raw_ ?
328 -window_bits_ :
329 window_bits_ | kZLibFlagAcceptAnyHeader;
330
331 stream_.next_in = Z_NULL;
332 stream_.avail_in = 0;
258 stream_.zalloc = Z_NULL; 333 stream_.zalloc = Z_NULL;
259 stream_.zfree = Z_NULL; 334 stream_.zfree = Z_NULL;
260 stream_.opaque = Z_NULL; 335 stream_.opaque = Z_NULL;
261 int result = inflateInit2(&stream_, 336 int result = inflateInit2(&stream_, window_bits);
262 kZLibFlagWindowBits | kZLibFlagAcceptAnyHeader); 337 if (result != Z_OK) {
263 if (result == Z_OK) { 338 return false;
264 set_initialized(true);
265 return true;
266 } 339 }
267 return false; 340 set_initialized(true);
341 return true;
268 } 342 }
269 343
270 344
271 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) { 345 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) {
272 if (current_buffer_ != NULL) return false; 346 if (current_buffer_ != NULL) return false;
273 stream_.avail_in = length; 347 stream_.avail_in = length;
274 stream_.next_in = current_buffer_ = data; 348 stream_.next_in = current_buffer_ = data;
275 return true; 349 return true;
276 } 350 }
277 351
278 352
279 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer, 353 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer,
280 intptr_t length, 354 intptr_t length,
281 bool flush, 355 bool flush,
282 bool end) { 356 bool end) {
283 stream_.avail_out = length; 357 stream_.avail_out = length;
284 stream_.next_out = buffer; 358 stream_.next_out = buffer;
359 bool error = false;
285 switch (inflate(&stream_, 360 switch (inflate(&stream_,
286 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { 361 end ? Z_FINISH : flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) {
287 case Z_STREAM_END: 362 case Z_STREAM_END:
288 case Z_BUF_ERROR: 363 case Z_BUF_ERROR:
289 case Z_OK: { 364 case Z_OK: {
290 intptr_t processed = length - stream_.avail_out; 365 intptr_t processed = length - stream_.avail_out;
291 if (processed == 0) { 366 if (processed == 0) {
292 delete[] current_buffer_; 367 break;
293 current_buffer_ = NULL; 368 }
294 return 0; 369 return processed;
370 }
371
372 case Z_NEED_DICT:
373 if (dictionary_ == NULL) {
374 error = true;
295 } else { 375 } else {
296 // We processed data, should be called again. 376 int result = inflateSetDictionary(&stream_, dictionary_,
297 return processed; 377 sizeof(dictionary_));
378 delete[] dictionary_;
379 dictionary_ = NULL;
380 error = result != Z_OK;
298 } 381 }
299 } 382 if (error) {
383 break;
384 } else {
385 return Processed(buffer, length, flush, end);
386 }
300 387
301 default: 388 default:
302 case Z_MEM_ERROR: 389 case Z_MEM_ERROR:
303 case Z_NEED_DICT:
304 case Z_DATA_ERROR: 390 case Z_DATA_ERROR:
305 case Z_STREAM_ERROR: 391 case Z_STREAM_ERROR:
306 // An error occoured. 392 error = true;
307 delete[] current_buffer_;
308 current_buffer_ = NULL;
309 return -1;
310 } 393 }
394
395 delete[] current_buffer_;
396 current_buffer_ = NULL;
397 // Either 0 Byte processed or error
398 return error ? -1 : 0;
311 } 399 }
312 400
313 } // namespace bin 401 } // namespace bin
314 } // namespace dart 402 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698