Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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/dartutils.h" | |
| 6 #include "bin/filter.h" | |
| 7 #include "bin/io_buffer.h" | |
| 8 | |
| 9 #include "include/dart_api.h" | |
| 10 | |
| 11 const int kZlibFlagMemUsage = 8; | |
| 12 const int kZLibFlagWindowBits = 15; | |
| 13 const int kZLibFlagUseGZipHeader = 16; | |
| 14 const int kZLibFlagAcceptAnyHeader = 32; | |
| 15 | |
| 16 const intptr_t kFilterBufferLength = 64 * KB; | |
| 17 | |
| 18 static const int kFilterPointerNativeField = 0; | |
| 19 | |
| 20 Filter* GetFilter(Dart_Handle filter_obj) { | |
| 21 Filter* filter; | |
| 22 Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter); | |
| 23 if (Dart_IsError(result)) { | |
| 24 Dart_PropagateError(result); | |
| 25 } | |
| 26 if (filter == NULL) { | |
| 27 Dart_ThrowException(DartUtils::NewInternalError( | |
| 28 "Failed to get destroyed filter")); | |
|
Søren Gjesse
2013/03/06 11:09:53
You actually got a destroyed filter :-). How about
Anders Johnsen
2013/03/06 11:37:24
You are right, changed :)
| |
| 29 } | |
| 30 return filter; | |
| 31 } | |
| 32 | |
| 33 void EndFilter(Dart_Handle filter_obj, Filter* filter) { | |
| 34 Filter::SetFilterPointerNativeField(filter_obj, NULL); | |
| 35 delete filter; | |
| 36 } | |
| 37 | |
| 38 void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) { | |
| 39 Dart_EnterScope(); | |
| 40 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); | |
| 41 Filter* filter = new ZLibInflateFilter(); | |
| 42 if (filter == NULL || !filter->Init()) { | |
| 43 delete filter; | |
| 44 Dart_ThrowException(DartUtils::NewInternalError( | |
| 45 "Failed to create ZLibInflateFilter")); | |
| 46 } | |
| 47 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); | |
| 48 if (Dart_IsError(result)) { | |
| 49 delete filter; | |
| 50 Dart_PropagateError(result); | |
| 51 } | |
| 52 Dart_ExitScope(); | |
| 53 } | |
| 54 | |
| 55 void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) { | |
| 56 Dart_EnterScope(); | |
| 57 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); | |
| 58 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1); | |
| 59 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2); | |
| 60 bool gzip; | |
| 61 if (Dart_IsError(Dart_BooleanValue(gzip_obj, &gzip))) { | |
| 62 Dart_ThrowException(DartUtils::NewInternalError( | |
| 63 "Failed to get 'gzip' parameter")); | |
| 64 } | |
| 65 int64_t level; | |
| 66 if (Dart_IsError(Dart_IntegerToInt64(level_obj, &level))) { | |
| 67 Dart_ThrowException(DartUtils::NewInternalError( | |
| 68 "Failed to get 'level' parameter")); | |
| 69 } | |
| 70 Filter* filter = new ZLibDeflateFilter(gzip, level); | |
| 71 if (filter == NULL || !filter->Init()) { | |
| 72 delete filter; | |
| 73 Dart_ThrowException(DartUtils::NewInternalError( | |
| 74 "Failed to create ZLibDeflateFilter")); | |
| 75 } | |
| 76 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); | |
| 77 if (Dart_IsError(result)) { | |
| 78 delete filter; | |
| 79 Dart_PropagateError(result); | |
| 80 } | |
| 81 Dart_ExitScope(); | |
| 82 } | |
| 83 | |
| 84 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) { | |
| 85 Dart_EnterScope(); | |
| 86 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); | |
| 87 Filter* filter = GetFilter(filter_obj); | |
| 88 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1); | |
| 89 intptr_t length; | |
| 90 Dart_TypedData_Type type; | |
| 91 uint8_t* buffer = NULL; | |
| 92 Dart_Handle result = Dart_TypedDataAcquireData( | |
| 93 data_obj, &type, reinterpret_cast<void**>(&buffer), &length); | |
| 94 if (!Dart_IsError(result)) { | |
| 95 uint8_t* zlib_buffer = new uint8_t[length]; | |
| 96 if (zlib_buffer == NULL) { | |
| 97 Dart_TypedDataReleaseData(data_obj); | |
| 98 Dart_ThrowException(DartUtils::NewInternalError( | |
| 99 "Failed to allocate buffer for zlib")); | |
| 100 } | |
| 101 memmove(zlib_buffer, buffer, length); | |
| 102 Dart_TypedDataReleaseData(data_obj); | |
| 103 buffer = zlib_buffer; | |
| 104 } else { | |
| 105 if (Dart_IsError(Dart_ListLength(data_obj, &length))) { | |
| 106 Dart_ThrowException(DartUtils::NewInternalError( | |
| 107 "Failed to get list length")); | |
| 108 } | |
| 109 buffer = new uint8_t[length]; | |
| 110 if (Dart_IsError(Dart_ListGetAsBytes(data_obj, 0, buffer, length))) { | |
| 111 delete[] buffer; | |
| 112 Dart_ThrowException(DartUtils::NewInternalError( | |
| 113 "Failed to get list bytes")); | |
| 114 } | |
| 115 } | |
| 116 // Process will take ownership of buffer, if successful. | |
| 117 if (!filter->Process(buffer, length)) { | |
| 118 delete[] buffer; | |
| 119 EndFilter(filter_obj, filter); | |
| 120 Dart_ThrowException(DartUtils::NewInternalError( | |
| 121 "Call to Process while still processing data")); | |
| 122 } | |
| 123 Dart_ExitScope(); | |
| 124 } | |
| 125 | |
| 126 | |
| 127 void FUNCTION_NAME(Filter_Processed)(Dart_NativeArguments args) { | |
| 128 Dart_EnterScope(); | |
| 129 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); | |
| 130 Filter* filter = GetFilter(filter_obj); | |
| 131 Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1); | |
| 132 bool flush; | |
| 133 if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) { | |
| 134 Dart_ThrowException(DartUtils::NewInternalError( | |
| 135 "Failed to get 'flush' parameter")); | |
| 136 } | |
| 137 uint8_t buffer[kFilterBufferLength]; | |
| 138 intptr_t read = filter->Processed(buffer, kFilterBufferLength, flush); | |
| 139 if (read < 0) { | |
| 140 // Error, end filter. | |
| 141 EndFilter(filter_obj, filter); | |
| 142 Dart_ThrowException(DartUtils::NewInternalError( | |
| 143 "Filter error, bad data")); | |
| 144 } else if (read == 0) { | |
| 145 Dart_SetReturnValue(args, Dart_Null()); | |
| 146 } else { | |
| 147 uint8_t* io_buffer; | |
| 148 Dart_Handle result = IOBuffer::Allocate(read, &io_buffer); | |
| 149 memmove(io_buffer, buffer, read); | |
| 150 Dart_SetReturnValue(args, result); | |
| 151 } | |
| 152 Dart_ExitScope(); | |
| 153 } | |
| 154 | |
| 155 | |
| 156 void FUNCTION_NAME(Filter_End)(Dart_NativeArguments args) { | |
| 157 Dart_EnterScope(); | |
| 158 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); | |
| 159 Filter* filter = GetFilter(filter_obj); | |
| 160 EndFilter(filter_obj, filter); | |
| 161 Dart_ExitScope(); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 Dart_Handle Filter::SetFilterPointerNativeField(Dart_Handle filter, | |
| 166 Filter* filter_pointer) { | |
| 167 return Dart_SetNativeInstanceField(filter, | |
| 168 kFilterPointerNativeField, | |
| 169 (intptr_t)filter_pointer); | |
| 170 } | |
| 171 | |
| 172 | |
| 173 Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter, | |
| 174 Filter** filter_pointer) { | |
| 175 return Dart_GetNativeInstanceField( | |
| 176 filter, | |
| 177 kFilterPointerNativeField, | |
| 178 reinterpret_cast<intptr_t*>(filter_pointer)); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 ZLibDeflateFilter::~ZLibDeflateFilter() { | |
| 183 delete[] current_buffer; | |
| 184 if (initialized) deflateEnd(&stream); | |
| 185 } | |
| 186 | |
| 187 | |
| 188 bool ZLibDeflateFilter::Init() { | |
| 189 stream.zalloc = Z_NULL; | |
| 190 stream.zfree = Z_NULL; | |
| 191 stream.opaque = Z_NULL; | |
| 192 int result = deflateInit2( | |
| 193 &stream, | |
| 194 level, | |
| 195 Z_DEFLATED, | |
| 196 kZLibFlagWindowBits | (gZip ? kZLibFlagUseGZipHeader : 0), | |
| 197 kZlibFlagMemUsage, | |
| 198 Z_DEFAULT_STRATEGY); | |
| 199 if (result == Z_OK) { | |
| 200 initialized = true; | |
| 201 return true; | |
| 202 } | |
| 203 return false; | |
| 204 } | |
| 205 | |
| 206 | |
| 207 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) { | |
| 208 if (current_buffer != NULL) return false; | |
| 209 stream.avail_in = length; | |
| 210 stream.next_in = current_buffer = data; | |
| 211 return true; | |
| 212 } | |
| 213 | |
| 214 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer, | |
| 215 intptr_t length, | |
| 216 bool flush) { | |
| 217 stream.avail_out = length; | |
| 218 stream.next_out = buffer; | |
| 219 switch (deflate(&stream, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { | |
| 220 case Z_OK: { | |
| 221 intptr_t processed = length - stream.avail_out; | |
| 222 if (processed == 0) { | |
| 223 delete[] current_buffer; | |
| 224 current_buffer = NULL; | |
| 225 return 0; | |
| 226 } else { | |
| 227 // We processed data, should be called again. | |
| 228 return processed; | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 case Z_STREAM_END: | |
| 233 case Z_BUF_ERROR: | |
| 234 // We processed all available input data. | |
| 235 delete[] current_buffer; | |
| 236 current_buffer = NULL; | |
| 237 return 0; | |
| 238 | |
| 239 default: | |
| 240 case Z_STREAM_ERROR: | |
| 241 // An error occoured. | |
| 242 delete[] current_buffer; | |
| 243 current_buffer = NULL; | |
| 244 return -1; | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 | |
| 249 ZLibInflateFilter::~ZLibInflateFilter() { | |
| 250 delete[] current_buffer; | |
| 251 if (initialized) inflateEnd(&stream); | |
| 252 } | |
| 253 | |
| 254 | |
| 255 bool ZLibInflateFilter::Init() { | |
| 256 stream.zalloc = Z_NULL; | |
| 257 stream.zfree = Z_NULL; | |
| 258 stream.opaque = Z_NULL; | |
| 259 int result = inflateInit2(&stream, | |
| 260 kZLibFlagWindowBits | kZLibFlagAcceptAnyHeader); | |
| 261 if (result == Z_OK) { | |
| 262 initialized = true; | |
| 263 return true; | |
| 264 } | |
| 265 return false; | |
| 266 } | |
| 267 | |
| 268 | |
| 269 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) { | |
| 270 if (current_buffer != NULL) return false; | |
| 271 stream.avail_in = length; | |
| 272 stream.next_in = current_buffer = data; | |
| 273 return true; | |
| 274 } | |
| 275 | |
| 276 | |
| 277 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer, | |
| 278 intptr_t length, | |
| 279 bool flush) { | |
| 280 stream.avail_out = length; | |
| 281 stream.next_out = buffer; | |
| 282 switch (inflate(&stream, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { | |
| 283 case Z_OK: { | |
| 284 intptr_t processed = length - stream.avail_out; | |
| 285 if (processed == 0) { | |
| 286 delete[] current_buffer; | |
| 287 current_buffer = NULL; | |
| 288 return 0; | |
| 289 } else { | |
| 290 // We processed data, should be called again. | |
| 291 return processed; | |
| 292 } | |
| 293 } | |
| 294 | |
| 295 case Z_STREAM_END: | |
| 296 case Z_BUF_ERROR: | |
| 297 // We processed all available input data. | |
| 298 delete[] current_buffer; | |
| 299 current_buffer = NULL; | |
| 300 return 0; | |
| 301 | |
| 302 default: | |
| 303 case Z_MEM_ERROR: | |
| 304 case Z_NEED_DICT: | |
| 305 case Z_DATA_ERROR: | |
| 306 case Z_STREAM_ERROR: | |
| 307 // An error occoured. | |
| 308 delete[] current_buffer; | |
| 309 current_buffer = NULL; | |
| 310 return -1; | |
| 311 } | |
| 312 } | |
| 313 | |
| OLD | NEW |