OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #include "platform/loader/fetch/ResourceError.h" | 43 #include "platform/loader/fetch/ResourceError.h" |
44 #include "platform/loader/fetch/ResourceRequest.h" | 44 #include "platform/loader/fetch/ResourceRequest.h" |
45 #include "platform/loader/fetch/ResourceResponse.h" | 45 #include "platform/loader/fetch/ResourceResponse.h" |
46 #include "platform/wtf/PassRefPtr.h" | 46 #include "platform/wtf/PassRefPtr.h" |
47 #include "platform/wtf/PtrUtil.h" | 47 #include "platform/wtf/PtrUtil.h" |
48 #include "platform/wtf/RefPtr.h" | 48 #include "platform/wtf/RefPtr.h" |
49 #include "platform/wtf/Vector.h" | 49 #include "platform/wtf/Vector.h" |
50 #include "platform/wtf/text/Base64.h" | 50 #include "platform/wtf/text/Base64.h" |
51 #include "platform/wtf/text/StringBuilder.h" | 51 #include "platform/wtf/text/StringBuilder.h" |
52 #include "public/platform/WebURLRequest.h" | 52 #include "public/platform/WebURLRequest.h" |
| 53 #include "v8/include/v8.h" |
53 | 54 |
54 namespace blink { | 55 namespace blink { |
55 | 56 |
56 FileReaderLoader::FileReaderLoader(ReadType read_type, | 57 FileReaderLoader::FileReaderLoader(ReadType read_type, |
57 FileReaderLoaderClient* client) | 58 FileReaderLoaderClient* client) |
58 : read_type_(read_type), | 59 : read_type_(read_type), client_(client) {} |
59 client_(client), | |
60 is_raw_data_converted_(false), | |
61 string_result_(""), | |
62 finished_loading_(false), | |
63 bytes_loaded_(0), | |
64 total_bytes_(-1), | |
65 has_range_(false), | |
66 range_start_(0), | |
67 range_end_(0), | |
68 error_code_(FileError::kOK) {} | |
69 | 60 |
70 FileReaderLoader::~FileReaderLoader() { | 61 FileReaderLoader::~FileReaderLoader() { |
71 Cleanup(); | 62 Cleanup(); |
| 63 UnadjustReportedMemoryUsageToV8(); |
72 if (!url_for_reading_.IsEmpty()) { | 64 if (!url_for_reading_.IsEmpty()) { |
73 BlobRegistry::RevokePublicBlobURL(url_for_reading_); | 65 BlobRegistry::RevokePublicBlobURL(url_for_reading_); |
74 } | 66 } |
75 } | 67 } |
76 | 68 |
77 void FileReaderLoader::Start(ExecutionContext* execution_context, | 69 void FileReaderLoader::Start(ExecutionContext* execution_context, |
78 PassRefPtr<BlobDataHandle> blob_data) { | 70 PassRefPtr<BlobDataHandle> blob_data) { |
79 DCHECK(execution_context); | 71 DCHECK(execution_context); |
80 // The blob is read by routing through the request handling layer given a | 72 // The blob is read by routing through the request handling layer given a |
81 // temporary public url. | 73 // temporary public url. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 loader_->Cancel(); | 128 loader_->Cancel(); |
137 loader_ = nullptr; | 129 loader_ = nullptr; |
138 } | 130 } |
139 | 131 |
140 // If we get any error, we do not need to keep a buffer around. | 132 // If we get any error, we do not need to keep a buffer around. |
141 if (error_code_) { | 133 if (error_code_) { |
142 raw_data_.reset(); | 134 raw_data_.reset(); |
143 string_result_ = ""; | 135 string_result_ = ""; |
144 is_raw_data_converted_ = true; | 136 is_raw_data_converted_ = true; |
145 decoder_.reset(); | 137 decoder_.reset(); |
| 138 array_buffer_result_ = nullptr; |
| 139 UnadjustReportedMemoryUsageToV8(); |
146 } | 140 } |
147 } | 141 } |
148 | 142 |
| 143 void FileReaderLoader::AdjustReportedMemoryUsageToV8(int64_t usage) { |
| 144 if (!usage) |
| 145 return; |
| 146 memory_usage_reported_to_v8_ += usage; |
| 147 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(usage); |
| 148 DCHECK_GE(memory_usage_reported_to_v8_, 0); |
| 149 } |
| 150 |
| 151 void FileReaderLoader::UnadjustReportedMemoryUsageToV8() { |
| 152 if (!memory_usage_reported_to_v8_) |
| 153 return; |
| 154 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 155 -memory_usage_reported_to_v8_); |
| 156 memory_usage_reported_to_v8_ = 0; |
| 157 } |
| 158 |
149 void FileReaderLoader::DidReceiveResponse( | 159 void FileReaderLoader::DidReceiveResponse( |
150 unsigned long, | 160 unsigned long, |
151 const ResourceResponse& response, | 161 const ResourceResponse& response, |
152 std::unique_ptr<WebDataConsumerHandle> handle) { | 162 std::unique_ptr<WebDataConsumerHandle> handle) { |
153 DCHECK(!handle); | 163 DCHECK(!handle); |
154 if (response.HttpStatusCode() != 200) { | 164 if (response.HttpStatusCode() != 200) { |
155 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode())); | 165 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode())); |
156 return; | 166 return; |
157 } | 167 } |
158 | 168 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 | 233 |
224 unsigned bytes_appended = raw_data_->Append(data, data_length); | 234 unsigned bytes_appended = raw_data_->Append(data, data_length); |
225 if (!bytes_appended) { | 235 if (!bytes_appended) { |
226 raw_data_.reset(); | 236 raw_data_.reset(); |
227 bytes_loaded_ = 0; | 237 bytes_loaded_ = 0; |
228 Failed(FileError::kNotReadableErr); | 238 Failed(FileError::kNotReadableErr); |
229 return; | 239 return; |
230 } | 240 } |
231 bytes_loaded_ += bytes_appended; | 241 bytes_loaded_ += bytes_appended; |
232 is_raw_data_converted_ = false; | 242 is_raw_data_converted_ = false; |
| 243 AdjustReportedMemoryUsageToV8(bytes_appended); |
233 | 244 |
234 if (client_) | 245 if (client_) |
235 client_->DidReceiveData(); | 246 client_->DidReceiveData(); |
236 } | 247 } |
237 | 248 |
238 void FileReaderLoader::DidFinishLoading(unsigned long, double) { | 249 void FileReaderLoader::DidFinishLoading(unsigned long, double) { |
239 if (read_type_ != kReadByClient && raw_data_) { | 250 if (read_type_ != kReadByClient && raw_data_) { |
240 raw_data_->ShrinkToFit(); | 251 raw_data_->ShrinkToFit(); |
241 is_raw_data_converted_ = false; | 252 is_raw_data_converted_ = false; |
242 } | 253 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 return FileError::kSecurityErr; | 289 return FileError::kSecurityErr; |
279 case 404: | 290 case 404: |
280 return FileError::kNotFoundErr; | 291 return FileError::kNotFoundErr; |
281 default: | 292 default: |
282 return FileError::kNotReadableErr; | 293 return FileError::kNotReadableErr; |
283 } | 294 } |
284 } | 295 } |
285 | 296 |
286 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { | 297 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { |
287 DCHECK_EQ(read_type_, kReadAsArrayBuffer); | 298 DCHECK_EQ(read_type_, kReadAsArrayBuffer); |
| 299 if (array_buffer_result_) |
| 300 return array_buffer_result_; |
288 | 301 |
289 // If the loading is not started or an error occurs, return an empty result. | 302 // If the loading is not started or an error occurs, return an empty result. |
290 if (!raw_data_ || error_code_) | 303 if (!raw_data_ || error_code_) |
291 return nullptr; | 304 return nullptr; |
292 | 305 |
293 if (array_buffer_result_) | |
294 return array_buffer_result_; | |
295 | |
296 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); | 306 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); |
297 if (finished_loading_) { | 307 if (finished_loading_) { |
298 array_buffer_result_ = result; | 308 array_buffer_result_ = result; |
| 309 AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength()); |
| 310 raw_data_.reset(); |
299 } | 311 } |
300 return result; | 312 return result; |
301 } | 313 } |
302 | 314 |
303 String FileReaderLoader::StringResult() { | 315 String FileReaderLoader::StringResult() { |
304 DCHECK_NE(read_type_, kReadAsArrayBuffer); | 316 DCHECK_NE(read_type_, kReadAsArrayBuffer); |
305 DCHECK_NE(read_type_, kReadByClient); | 317 DCHECK_NE(read_type_, kReadByClient); |
306 | 318 |
307 // If the loading is not started or an error occurs, return an empty result. | 319 if (!raw_data_ || error_code_ || is_raw_data_converted_) |
308 if (!raw_data_ || error_code_) | |
309 return string_result_; | |
310 | |
311 // If already converted from the raw data, return the result now. | |
312 if (is_raw_data_converted_) | |
313 return string_result_; | 320 return string_result_; |
314 | 321 |
315 switch (read_type_) { | 322 switch (read_type_) { |
316 case kReadAsArrayBuffer: | 323 case kReadAsArrayBuffer: |
317 // No conversion is needed. | 324 // No conversion is needed. |
318 break; | 325 return string_result_; |
319 case kReadAsBinaryString: | 326 case kReadAsBinaryString: |
320 string_result_ = raw_data_->ToString(); | 327 SetStringResult(raw_data_->ToString()); |
321 is_raw_data_converted_ = true; | |
322 break; | 328 break; |
323 case kReadAsText: | 329 case kReadAsText: |
324 ConvertToText(); | 330 SetStringResult(ConvertToText()); |
325 break; | 331 break; |
326 case kReadAsDataURL: | 332 case kReadAsDataURL: |
327 // Partial data is not supported when reading as data URL. | 333 // Partial data is not supported when reading as data URL. |
328 if (finished_loading_) | 334 if (finished_loading_) |
329 ConvertToDataURL(); | 335 SetStringResult(ConvertToDataURL()); |
330 break; | 336 break; |
331 default: | 337 default: |
332 NOTREACHED(); | 338 NOTREACHED(); |
333 } | 339 } |
334 | 340 |
| 341 if (finished_loading_) { |
| 342 DCHECK(is_raw_data_converted_); |
| 343 AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength()); |
| 344 raw_data_.reset(); |
| 345 } |
335 return string_result_; | 346 return string_result_; |
336 } | 347 } |
337 | 348 |
338 void FileReaderLoader::ConvertToText() { | 349 void FileReaderLoader::SetStringResult(const String& result) { |
| 350 AdjustReportedMemoryUsageToV8(-1 * string_result_.CharactersSizeInBytes()); |
339 is_raw_data_converted_ = true; | 351 is_raw_data_converted_ = true; |
| 352 string_result_ = result; |
| 353 AdjustReportedMemoryUsageToV8(string_result_.CharactersSizeInBytes()); |
| 354 } |
340 | 355 |
341 if (!bytes_loaded_) { | 356 String FileReaderLoader::ConvertToText() { |
342 string_result_ = ""; | 357 if (!bytes_loaded_) |
343 return; | 358 return ""; |
344 } | |
345 | 359 |
346 // Decode the data. | 360 // Decode the data. |
347 // The File API spec says that we should use the supplied encoding if it is | 361 // The File API spec says that we should use the supplied encoding if it is |
348 // valid. However, we choose to ignore this requirement in order to be | 362 // valid. However, we choose to ignore this requirement in order to be |
349 // consistent with how WebKit decodes the web content: always has the BOM | 363 // consistent with how WebKit decodes the web content: always has the BOM |
350 // override the provided encoding. | 364 // override the provided encoding. |
351 // FIXME: consider supporting incremental decoding to improve the perf. | 365 // FIXME: consider supporting incremental decoding to improve the perf. |
352 StringBuilder builder; | 366 StringBuilder builder; |
353 if (!decoder_) | 367 if (!decoder_) |
354 decoder_ = TextResourceDecoder::Create( | 368 decoder_ = TextResourceDecoder::Create( |
355 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding()); | 369 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding()); |
356 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()), | 370 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()), |
357 raw_data_->ByteLength())); | 371 raw_data_->ByteLength())); |
358 | 372 |
359 if (finished_loading_) | 373 if (finished_loading_) |
360 builder.Append(decoder_->Flush()); | 374 builder.Append(decoder_->Flush()); |
361 | 375 |
362 string_result_ = builder.ToString(); | 376 return builder.ToString(); |
363 } | 377 } |
364 | 378 |
365 void FileReaderLoader::ConvertToDataURL() { | 379 String FileReaderLoader::ConvertToDataURL() { |
366 is_raw_data_converted_ = true; | |
367 | |
368 StringBuilder builder; | 380 StringBuilder builder; |
369 builder.Append("data:"); | 381 builder.Append("data:"); |
370 | 382 |
371 if (!bytes_loaded_) { | 383 if (!bytes_loaded_) |
372 string_result_ = builder.ToString(); | 384 return builder.ToString(); |
373 return; | |
374 } | |
375 | 385 |
376 builder.Append(data_type_); | 386 builder.Append(data_type_); |
377 builder.Append(";base64,"); | 387 builder.Append(";base64,"); |
378 | 388 |
379 Vector<char> out; | 389 Vector<char> out; |
380 Base64Encode(static_cast<const char*>(raw_data_->Data()), | 390 Base64Encode(static_cast<const char*>(raw_data_->Data()), |
381 raw_data_->ByteLength(), out); | 391 raw_data_->ByteLength(), out); |
382 out.push_back('\0'); | 392 out.push_back('\0'); |
383 builder.Append(out.data()); | 393 builder.Append(out.data()); |
384 | 394 |
385 string_result_ = builder.ToString(); | 395 return builder.ToString(); |
386 } | 396 } |
387 | 397 |
388 void FileReaderLoader::SetEncoding(const String& encoding) { | 398 void FileReaderLoader::SetEncoding(const String& encoding) { |
389 if (!encoding.IsEmpty()) | 399 if (!encoding.IsEmpty()) |
390 encoding_ = WTF::TextEncoding(encoding); | 400 encoding_ = WTF::TextEncoding(encoding); |
391 } | 401 } |
392 | 402 |
393 } // namespace blink | 403 } // namespace blink |
OLD | NEW |