| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012, 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 #include "bin/dartutils.h" |
| 7 |
| 8 #include "include/dart_api.h" |
| 9 |
| 10 const int kZlibFlagMemUsage = 8; |
| 11 const int kZLibFlagWindowBits = 15; |
| 12 const int kZLibFlagUseGZipHeader = 16; |
| 13 const int kZLibFlagAcceptAnyHeader = 32; |
| 14 |
| 15 const intptr_t kFilterBufferLength = 64 * KB; |
| 16 |
| 17 static const int kFilterPointerNativeField = 0; |
| 18 |
| 19 void DeleteBuffer(void* buffer) { |
| 20 delete[] reinterpret_cast<uint8_t*>(buffer); |
| 21 } |
| 22 |
| 23 Filter* GetFilter(Dart_Handle filter_obj) { |
| 24 Filter* filter; |
| 25 if (Dart_IsError(Filter::GetFilterPointerNativeField(filter_obj, &filter)) |
| 26 || filter == NULL) { |
| 27 Dart_ThrowException(DartUtils::NewInternalError("Failed to get filter")); |
| 28 } |
| 29 return filter; |
| 30 } |
| 31 |
| 32 void EndFilter(Dart_Handle filter_obj, Filter* filter) { |
| 33 Filter::SetFilterPointerNativeField(filter_obj, NULL); |
| 34 delete filter; |
| 35 } |
| 36 |
| 37 void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) { |
| 38 Dart_EnterScope(); |
| 39 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 40 Filter* filter = new ZLibInflateFilter(); |
| 41 if (!filter->Init() || |
| 42 Dart_IsError(Filter::SetFilterPointerNativeField(filter_obj, filter))) { |
| 43 delete filter; |
| 44 Dart_ThrowException(DartUtils::NewInternalError( |
| 45 "Failed to create ZLibInflateFilter")); |
| 46 } |
| 47 Dart_ExitScope(); |
| 48 } |
| 49 |
| 50 void FUNCTION_NAME(Filter_CreateGZipDeflate)(Dart_NativeArguments args) { |
| 51 Dart_EnterScope(); |
| 52 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 53 Filter* filter = new ZLibDeflateFilter(true); |
| 54 if (!filter->Init() || |
| 55 Dart_IsError(Filter::SetFilterPointerNativeField(filter_obj, filter))) { |
| 56 delete filter; |
| 57 Dart_ThrowException(DartUtils::NewInternalError( |
| 58 "Failed to create GZipDeflateFilter")); |
| 59 } |
| 60 Dart_ExitScope(); |
| 61 } |
| 62 |
| 63 void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) { |
| 64 Dart_EnterScope(); |
| 65 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 66 Filter* filter = GetFilter(filter_obj); |
| 67 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1); |
| 68 intptr_t length; |
| 69 if (Dart_IsError(Dart_ListLength(data_obj, &length))) { |
| 70 Dart_ThrowException(DartUtils::NewInternalError( |
| 71 "Failed to get data length")); |
| 72 } |
| 73 uint8_t* data = new uint8_t[length]; |
| 74 if (Dart_IsError(Dart_ListGetAsBytes(data_obj, 0, data, length))) { |
| 75 DeleteBuffer(data); |
| 76 Dart_ThrowException(DartUtils::NewInternalError( |
| 77 "Failed to get data bytes")); |
| 78 } |
| 79 if (!filter->Process(data, length)) { |
| 80 DeleteBuffer(data); |
| 81 Dart_ThrowException(DartUtils::NewInternalError( |
| 82 "Call to Process while still processing data")); |
| 83 } |
| 84 Dart_ExitScope(); |
| 85 } |
| 86 |
| 87 |
| 88 void FUNCTION_NAME(Filter_Processed)(Dart_NativeArguments args) { |
| 89 Dart_EnterScope(); |
| 90 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 91 Filter* filter = GetFilter(filter_obj); |
| 92 Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1); |
| 93 bool flush; |
| 94 if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) { |
| 95 Dart_ThrowException(DartUtils::NewInternalError( |
| 96 "Failed to get 'flush' parameter")); |
| 97 } |
| 98 uint8_t* buffer = new uint8_t[kFilterBufferLength]; |
| 99 intptr_t read = filter->Processed(buffer, kFilterBufferLength, flush); |
| 100 if (read < 0) { |
| 101 // Error, end filter. |
| 102 EndFilter(filter_obj, filter); |
| 103 DeleteBuffer(buffer); |
| 104 Dart_ThrowException(DartUtils::NewInternalError( |
| 105 "Filter error, bad data")); |
| 106 } else if (read == 0) { |
| 107 DeleteBuffer(buffer); |
| 108 Dart_SetReturnValue(args, Dart_Null()); |
| 109 } else { |
| 110 Dart_Handle result = Dart_NewExternalByteArray(buffer, |
| 111 read, |
| 112 buffer, |
| 113 DeleteBuffer); |
| 114 Dart_SetReturnValue(args, result); |
| 115 } |
| 116 Dart_ExitScope(); |
| 117 } |
| 118 |
| 119 |
| 120 void FUNCTION_NAME(Filter_End)(Dart_NativeArguments args) { |
| 121 Dart_EnterScope(); |
| 122 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 123 Filter* filter = GetFilter(filter_obj); |
| 124 EndFilter(filter_obj, filter); |
| 125 Dart_ExitScope(); |
| 126 } |
| 127 |
| 128 |
| 129 Dart_Handle Filter::SetFilterPointerNativeField(Dart_Handle filter, |
| 130 Filter* filter_pointer) { |
| 131 return Dart_SetNativeInstanceField(filter, |
| 132 kFilterPointerNativeField, |
| 133 (intptr_t)filter_pointer); |
| 134 } |
| 135 |
| 136 |
| 137 Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter, |
| 138 Filter** filter_pointer) { |
| 139 return Dart_GetNativeInstanceField( |
| 140 filter, |
| 141 kFilterPointerNativeField, |
| 142 reinterpret_cast<intptr_t*>(filter_pointer)); |
| 143 } |
| 144 |
| 145 |
| 146 ZLibDeflateFilter::~ZLibDeflateFilter() { |
| 147 delete[] current_buffer; |
| 148 deflateEnd(&stream); |
| 149 } |
| 150 |
| 151 |
| 152 bool ZLibDeflateFilter::Init() { |
| 153 stream.zalloc = Z_NULL; |
| 154 stream.zfree = Z_NULL; |
| 155 stream.opaque = Z_NULL; |
| 156 return deflateInit2(&stream, |
| 157 level, |
| 158 Z_DEFLATED, |
| 159 kZLibFlagWindowBits | (gZip ? kZLibFlagUseGZipHeader : 0), |
| 160 kZlibFlagMemUsage, |
| 161 Z_DEFAULT_STRATEGY) == Z_OK; |
| 162 } |
| 163 |
| 164 |
| 165 bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) { |
| 166 if (current_buffer != NULL) return false; |
| 167 stream.avail_in = length; |
| 168 stream.next_in = current_buffer = data; |
| 169 return true; |
| 170 } |
| 171 |
| 172 intptr_t ZLibDeflateFilter::Processed(uint8_t* buffer, |
| 173 intptr_t length, |
| 174 bool flush) { |
| 175 stream.avail_out = length; |
| 176 stream.next_out = buffer; |
| 177 switch (deflate(&stream, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { |
| 178 case Z_OK: |
| 179 // We processed data, should be called again. |
| 180 return length - stream.avail_out; |
| 181 |
| 182 case Z_STREAM_END: |
| 183 case Z_BUF_ERROR: |
| 184 // We processed all available input data. |
| 185 delete[] current_buffer; |
| 186 current_buffer = NULL; |
| 187 return 0; |
| 188 |
| 189 default: |
| 190 case Z_STREAM_ERROR: |
| 191 // An error occoured. |
| 192 delete[] current_buffer; |
| 193 current_buffer = NULL; |
| 194 return -1; |
| 195 } |
| 196 } |
| 197 |
| 198 |
| 199 ZLibInflateFilter::~ZLibInflateFilter() { |
| 200 delete[] current_buffer; |
| 201 inflateEnd(&stream); |
| 202 } |
| 203 |
| 204 |
| 205 bool ZLibInflateFilter::Init() { |
| 206 stream.zalloc = Z_NULL; |
| 207 stream.zfree = Z_NULL; |
| 208 stream.opaque = Z_NULL; |
| 209 return inflateInit2(&stream, |
| 210 kZLibFlagWindowBits | kZLibFlagAcceptAnyHeader) == Z_OK; |
| 211 } |
| 212 |
| 213 |
| 214 bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) { |
| 215 if (current_buffer != NULL) return false; |
| 216 stream.avail_in = length; |
| 217 stream.next_in = current_buffer = data; |
| 218 return true; |
| 219 } |
| 220 |
| 221 |
| 222 intptr_t ZLibInflateFilter::Processed(uint8_t* buffer, |
| 223 intptr_t length, |
| 224 bool flush) { |
| 225 stream.avail_out = length; |
| 226 stream.next_out = buffer; |
| 227 switch (inflate(&stream, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH)) { |
| 228 case Z_OK: |
| 229 // We processed data, should be called again. |
| 230 return length - stream.avail_out; |
| 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_MEM_ERROR: |
| 241 case Z_NEED_DICT: |
| 242 case Z_DATA_ERROR: |
| 243 case Z_STREAM_ERROR: |
| 244 // An error occoured. |
| 245 delete[] current_buffer; |
| 246 current_buffer = NULL; |
| 247 return -1; |
| 248 } |
| 249 } |
| 250 |
| OLD | NEW |