Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
filter.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "bin/filter.h"
6
7#include "bin/dartutils.h"
8#include "bin/io_buffer.h"
9
10#include "include/dart_api.h"
11
12namespace dart {
13namespace bin {
14
17
18static constexpr int kFilterPointerNativeField = 0;
19
20static Dart_Handle GetFilter(Dart_Handle filter_obj, Filter** filter) {
21 ASSERT(filter != nullptr);
23 Dart_Handle err = Filter::GetFilterNativeField(filter_obj, &result);
24 if (Dart_IsError(err)) {
25 return err;
26 }
27 if (result == nullptr) {
28 return Dart_NewApiError("Filter was destroyed");
29 }
30
31 *filter = result;
32 return Dart_Null();
33}
34
36 uint8_t** dictionary) {
37 ASSERT(dictionary != nullptr);
38 uint8_t* src = nullptr;
39 intptr_t size;
41
42 Dart_Handle err = Dart_ListLength(dictionary_obj, &size);
43 if (Dart_IsError(err)) {
44 return err;
45 }
46
47 uint8_t* result = new uint8_t[size];
48 if (result == nullptr) {
49 return Dart_NewApiError("Could not allocate new dictionary");
50 }
51
52 err = Dart_TypedDataAcquireData(dictionary_obj, &type,
53 reinterpret_cast<void**>(&src), &size);
54 if (!Dart_IsError(err)) {
55 memmove(result, src, size);
56 Dart_TypedDataReleaseData(dictionary_obj);
57 } else {
58 err = Dart_ListGetAsBytes(dictionary_obj, 0, result, size);
59 if (Dart_IsError(err)) {
60 delete[] result;
61 return err;
62 }
63 }
64
65 *dictionary = result;
66 return Dart_Null();
67}
68
71 Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 1);
72 int64_t window_bits = DartUtils::GetIntegerValue(window_bits_obj);
75 bool raw = DartUtils::GetBooleanValue(raw_obj);
76
77 Dart_Handle err;
78 uint8_t* dictionary = nullptr;
79 intptr_t dictionary_length = 0;
80 if (!Dart_IsNull(dict_obj)) {
81 err = CopyDictionary(dict_obj, &dictionary);
82 if (Dart_IsError(err)) {
84 }
85 ASSERT(dictionary != nullptr);
86 dictionary_length = 0;
87 err = Dart_ListLength(dict_obj, &dictionary_length);
88 if (Dart_IsError(err)) {
89 delete[] dictionary;
91 }
92 }
93
95 static_cast<int32_t>(window_bits), dictionary, dictionary_length, raw);
96 if (filter == nullptr) {
97 delete[] dictionary;
99 Dart_NewApiError("Could not allocate ZLibInflateFilter"));
100 }
101 if (!filter->Init()) {
102 delete filter;
104 DartUtils::NewInternalError("Failed to create ZLibInflateFilter"));
105 }
106 err = Filter::SetFilterAndCreateFinalizer(
107 filter_obj, filter, sizeof(*filter) + dictionary_length);
108 if (Dart_IsError(err)) {
109 delete filter;
111 }
112}
113
115 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
117 bool gzip = DartUtils::GetBooleanValue(gzip_obj);
119 int64_t level =
121 Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 3);
122 int64_t window_bits = DartUtils::GetIntegerValue(window_bits_obj);
123 Dart_Handle mLevel_obj = Dart_GetNativeArgument(args, 4);
124 int64_t mem_level = DartUtils::GetIntegerValue(mLevel_obj);
125 Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5);
126 int64_t strategy = DartUtils::GetIntegerValue(strategy_obj);
129 bool raw = DartUtils::GetBooleanValue(raw_obj);
130
131 Dart_Handle err;
132 uint8_t* dictionary = nullptr;
133 intptr_t dictionary_length = 0;
134 if (!Dart_IsNull(dict_obj)) {
135 err = CopyDictionary(dict_obj, &dictionary);
136 if (Dart_IsError(err)) {
138 }
139 ASSERT(dictionary != nullptr);
140 dictionary_length = 0;
141 err = Dart_ListLength(dict_obj, &dictionary_length);
142 if (Dart_IsError(err)) {
143 delete[] dictionary;
145 }
146 }
147
149 gzip, static_cast<int32_t>(level), static_cast<int32_t>(window_bits),
150 static_cast<int32_t>(mem_level), static_cast<int32_t>(strategy),
151 dictionary, dictionary_length, raw);
152 if (filter == nullptr) {
153 delete[] dictionary;
155 Dart_NewApiError("Could not allocate ZLibDeflateFilter"));
156 }
157 if (!filter->Init()) {
158 delete filter;
160 DartUtils::NewInternalError("Failed to create ZLibDeflateFilter"));
161 }
162 Dart_Handle result = Filter::SetFilterAndCreateFinalizer(
163 filter_obj, filter, sizeof(*filter) + dictionary_length);
164 if (Dart_IsError(result)) {
165 delete filter;
167 }
168}
169
171 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
175 intptr_t chunk_length = end - start;
176 intptr_t length;
178 uint8_t* buffer = nullptr;
179
180 Filter* filter = nullptr;
181 Dart_Handle err = GetFilter(filter_obj, &filter);
182 if (Dart_IsError(err)) {
184 }
185
187 data_obj, &type, reinterpret_cast<void**>(&buffer), &length);
188 if (!Dart_IsError(result)) {
193 "Invalid argument passed to Filter_Process"));
194 }
195 uint8_t* zlib_buffer = new uint8_t[chunk_length];
196 if (zlib_buffer == nullptr) {
198 Dart_PropagateError(Dart_NewApiError("Could not allocate zlib buffer"));
199 }
200
201 memmove(zlib_buffer, buffer + start, chunk_length);
203 buffer = zlib_buffer;
204 } else {
205 err = Dart_ListLength(data_obj, &length);
206 if (Dart_IsError(err)) {
208 }
209 buffer = new uint8_t[chunk_length];
210 if (buffer == nullptr) {
211 Dart_PropagateError(Dart_NewApiError("Could not allocate buffer"));
212 }
213 err = Dart_ListGetAsBytes(data_obj, start, buffer, chunk_length);
214 if (Dart_IsError(err)) {
215 delete[] buffer;
217 }
218 }
219 // Process will take ownership of buffer, if successful.
220 if (!filter->Process(buffer, chunk_length)) {
221 delete[] buffer;
223 "Call to Process while still processing data"));
224 }
225}
226
228 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
230 bool flush = DartUtils::GetBooleanValue(flush_obj);
232 bool end = DartUtils::GetBooleanValue(end_obj);
233
234 Filter* filter = nullptr;
235 Dart_Handle err = GetFilter(filter_obj, &filter);
236 if (Dart_IsError(err)) {
238 }
239
240 intptr_t read = filter->Processed(
241 filter->processed_buffer(), filter->processed_buffer_size(), flush, end);
242 if (read < 0) {
244 DartUtils::NewDartFormatException("Filter error, bad data"));
245 } else if (read == 0) {
247 } else {
248 uint8_t* io_buffer;
250 if (Dart_IsNull(result)) {
252 return;
253 }
254 memmove(io_buffer, filter->processed_buffer(), read);
256 }
257}
258
259static void DeleteFilter(void* isolate_data, void* filter_pointer) {
260 Filter* filter = reinterpret_cast<Filter*>(filter_pointer);
261 delete filter;
262}
263
264Dart_Handle Filter::SetFilterAndCreateFinalizer(Dart_Handle filter,
265 Filter* filter_pointer,
266 intptr_t size) {
267 Dart_Handle err =
269 reinterpret_cast<intptr_t>(filter_pointer));
270 if (Dart_IsError(err)) {
271 return err;
272 }
273 Dart_NewFinalizableHandle(filter, reinterpret_cast<void*>(filter_pointer),
274 size, DeleteFilter);
275 return err;
276}
277
278Dart_Handle Filter::GetFilterNativeField(Dart_Handle filter,
279 Filter** filter_pointer) {
282 reinterpret_cast<intptr_t*>(filter_pointer));
283}
284
286 delete[] dictionary_;
287 delete[] current_buffer_;
288 if (initialized()) {
289 deflateEnd(&stream_);
290 }
291}
292
294 int window_bits = window_bits_;
295 if ((raw_ || gzip_) && (window_bits == 8)) {
296 // zlib deflater does not work with windows size of 8 bits. Old versions
297 // of zlib would silently upgrade window size to 9 bits, newer versions
298 // return Z_STREAM_ERROR if window size is 8 bits but the stream header
299 // is suppressed. To maintain the old behavior upgrade window size here.
300 // This is safe because you can inflate a stream deflated with zlib
301 // using 9-bits with 8-bits window.
302 // For more details see https://crbug.com/691074.
303 window_bits = 9;
304 }
305 if (raw_) {
306 window_bits = -window_bits;
307 } else if (gzip_) {
308 window_bits += kZLibFlagUseGZipHeader;
309 }
310 stream_.next_in = Z_NULL;
311 stream_.zalloc = Z_NULL;
312 stream_.zfree = Z_NULL;
313 stream_.opaque = Z_NULL;
314 int result = deflateInit2(&stream_, level_, Z_DEFLATED, window_bits,
315 mem_level_, strategy_);
316 if (result != Z_OK) {
317 return false;
318 }
319 if ((dictionary_ != nullptr) && !gzip_ && !raw_) {
320 result = deflateSetDictionary(&stream_, dictionary_, dictionary_length_);
321 delete[] dictionary_;
322 dictionary_ = nullptr;
323 if (result != Z_OK) {
324 return false;
325 }
326 }
327 set_initialized(true);
328 return true;
329}
330
331bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) {
332 if (current_buffer_ != nullptr) {
333 return false;
334 }
335 stream_.avail_in = length;
336 stream_.next_in = current_buffer_ = data;
337 return true;
338}
339
341 intptr_t length,
342 bool flush,
343 bool end) {
344 stream_.avail_out = length;
345 stream_.next_out = buffer;
346 bool error = false;
347 switch (deflate(&stream_, end ? Z_FINISH
348 : flush ? Z_SYNC_FLUSH
349 : Z_NO_FLUSH)) {
350 case Z_STREAM_END:
351 case Z_BUF_ERROR:
352 case Z_OK: {
353 intptr_t processed = length - stream_.avail_out;
354 if (processed == 0) {
355 break;
356 }
357 return processed;
358 }
359
360 default:
361 case Z_STREAM_ERROR:
362 error = true;
363 }
364
365 delete[] current_buffer_;
366 current_buffer_ = nullptr;
367 // Either 0 Byte processed or error
368 return error ? -1 : 0;
369}
370
372 delete[] dictionary_;
373 delete[] current_buffer_;
374 if (initialized()) {
375 inflateEnd(&stream_);
376 }
377}
378
380 int window_bits =
381 raw_ ? -window_bits_ : window_bits_ | kZLibFlagAcceptAnyHeader;
382
383 stream_.next_in = Z_NULL;
384 stream_.avail_in = 0;
385 stream_.zalloc = Z_NULL;
386 stream_.zfree = Z_NULL;
387 stream_.opaque = Z_NULL;
388 int result = inflateInit2(&stream_, window_bits);
389 if (result != Z_OK) {
390 return false;
391 }
392 set_initialized(true);
393 return true;
394}
395
396bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) {
397 if (current_buffer_ != nullptr) {
398 return false;
399 }
400 stream_.avail_in = length;
401 stream_.next_in = current_buffer_ = data;
402 return true;
403}
404
406 intptr_t length,
407 bool flush,
408 bool end) {
409 stream_.avail_out = length;
410 stream_.next_out = buffer;
411 bool error = false;
412 int v;
413 switch (v = inflate(&stream_, end ? Z_FINISH
414 : flush ? Z_SYNC_FLUSH
415 : Z_NO_FLUSH)) {
416 case Z_STREAM_END:
417 case Z_BUF_ERROR:
418 case Z_OK: {
419 intptr_t processed = length - stream_.avail_out;
420 if (processed == 0) {
421 break;
422 }
423 return processed;
424 }
425
426 case Z_NEED_DICT:
427 if (dictionary_ == nullptr) {
428 error = true;
429 } else {
430 int result =
431 inflateSetDictionary(&stream_, dictionary_, dictionary_length_);
432 delete[] dictionary_;
433 dictionary_ = nullptr;
434 error = result != Z_OK;
435 }
436 if (error) {
437 break;
438 } else {
439 return Processed(buffer, length, flush, end);
440 }
441
442 default:
443 case Z_MEM_ERROR:
444 case Z_DATA_ERROR:
445 case Z_STREAM_ERROR:
446 error = true;
447 }
448
449 delete[] current_buffer_;
450 current_buffer_ = nullptr;
451 // Either 0 Byte processed or error
452 return error ? -1 : 0;
453}
454
455} // namespace bin
456} // namespace dart
static bool read(SkStream *stream, void *buffer, size_t amount)
#define FUNCTION_NAME(name)
Definition builtin.h:19
static Dart_Handle NewDartFormatException(const char *message)
Definition dartutils.cc:754
static int64_t GetIntegerValue(Dart_Handle value_obj)
Definition dartutils.cc:85
static int64_t GetInt64ValueCheckRange(Dart_Handle value_obj, int64_t lower, int64_t upper)
Definition dartutils.cc:94
static Dart_Handle NewDartOSError()
Definition dartutils.cc:706
static bool GetBooleanValue(Dart_Handle bool_obj)
Definition dartutils.cc:141
static Dart_Handle NewInternalError(const char *message)
Definition dartutils.cc:786
static intptr_t GetIntptrValue(Dart_Handle value_obj)
Definition dartutils.cc:104
virtual intptr_t Processed(uint8_t *buffer, intptr_t length, bool finish, bool end)=0
virtual bool Process(uint8_t *data, intptr_t length)=0
intptr_t processed_buffer_size() const
Definition filter.h:42
bool initialized() const
Definition filter.h:39
uint8_t * processed_buffer()
Definition filter.h:41
void set_initialized(bool value)
Definition filter.h:40
static Dart_Handle Allocate(intptr_t size, uint8_t **buffer)
Definition io_buffer.cc:12
virtual bool Process(uint8_t *data, intptr_t length)
Definition filter.cc:331
virtual intptr_t Processed(uint8_t *buffer, intptr_t length, bool finish, bool end)
Definition filter.cc:340
virtual intptr_t Processed(uint8_t *buffer, intptr_t length, bool finish, bool end)
Definition filter.cc:405
virtual bool Process(uint8_t *data, intptr_t length)
Definition filter.cc:396
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
struct _Dart_NativeArguments * Dart_NativeArguments
Definition dart_api.h:3010
Dart_TypedData_Type
Definition dart_api.h:2603
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
@ Dart_TypedData_kInt8
Definition dart_api.h:2605
#define ASSERT(E)
glong glong end
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
size_t length
void FUNCTION_NAME() Filter_Processed(Dart_NativeArguments args)
Definition filter.cc:227
void FUNCTION_NAME() Filter_Process(Dart_NativeArguments args)
Definition filter.cc:170
static void DeleteFilter(void *isolate_data, void *filter_pointer)
Definition filter.cc:259
const int kZLibFlagAcceptAnyHeader
Definition filter.cc:16
const int kZLibFlagUseGZipHeader
Definition filter.cc:15
static Dart_Handle CopyDictionary(Dart_Handle dictionary_obj, uint8_t **dictionary)
Definition filter.cc:35
static constexpr int kFilterPointerNativeField
Definition filter.cc:18
void FUNCTION_NAME() Filter_CreateZLibDeflate(Dart_NativeArguments args)
Definition filter.cc:114
void FUNCTION_NAME() Filter_CreateZLibInflate(Dart_NativeArguments args)
Definition filter.cc:69
static Dart_Handle GetFilter(Dart_Handle filter_obj, Filter **filter)
Definition filter.cc:20
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
constexpr int32_t kMinInt32
Definition globals.h:482
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
DART_EXPORT Dart_FinalizableHandle Dart_NewFinalizableHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args, Dart_Handle retval)
DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, Dart_TypedData_Type *type, void **data, intptr_t *len)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj, int index, intptr_t value)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, intptr_t offset, uint8_t *native_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object)
constexpr int32_t kMaxInt32
Definition globals.h:483
DART_EXPORT Dart_Handle Dart_NewApiError(const char *error)
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *len)
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_Null()
static int8_t data[kExtLength]