Chromium Code Reviews| 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), |
| 59 client_(client), | 60 client_(client), |
| 60 is_raw_data_converted_(false), | 61 is_raw_data_converted_(false), |
| 61 string_result_(""), | 62 string_result_(""), |
| 62 finished_loading_(false), | 63 finished_loading_(false), |
| 63 bytes_loaded_(0), | 64 bytes_loaded_(0), |
| 64 total_bytes_(-1), | 65 total_bytes_(-1), |
| 65 has_range_(false), | 66 has_range_(false), |
| 66 range_start_(0), | 67 range_start_(0), |
| 67 range_end_(0), | 68 range_end_(0), |
| 68 error_code_(FileError::kOK) {} | 69 error_code_(FileError::kOK) {} |
| 69 | 70 |
| 70 FileReaderLoader::~FileReaderLoader() { | 71 FileReaderLoader::~FileReaderLoader() { |
| 71 Cleanup(); | 72 Cleanup(); |
| 73 UnreportMemoryUsageToV8(); | |
| 72 if (!url_for_reading_.IsEmpty()) { | 74 if (!url_for_reading_.IsEmpty()) { |
| 73 BlobRegistry::RevokePublicBlobURL(url_for_reading_); | 75 BlobRegistry::RevokePublicBlobURL(url_for_reading_); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 void FileReaderLoader::Start(ExecutionContext* execution_context, | 79 void FileReaderLoader::Start(ExecutionContext* execution_context, |
| 78 PassRefPtr<BlobDataHandle> blob_data) { | 80 PassRefPtr<BlobDataHandle> blob_data) { |
| 79 DCHECK(execution_context); | 81 DCHECK(execution_context); |
| 80 // The blob is read by routing through the request handling layer given a | 82 // The blob is read by routing through the request handling layer given a |
| 81 // temporary public url. | 83 // temporary public url. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 loader_->Cancel(); | 138 loader_->Cancel(); |
| 137 loader_ = nullptr; | 139 loader_ = nullptr; |
| 138 } | 140 } |
| 139 | 141 |
| 140 // If we get any error, we do not need to keep a buffer around. | 142 // If we get any error, we do not need to keep a buffer around. |
| 141 if (error_code_) { | 143 if (error_code_) { |
| 142 raw_data_.reset(); | 144 raw_data_.reset(); |
| 143 string_result_ = ""; | 145 string_result_ = ""; |
| 144 is_raw_data_converted_ = true; | 146 is_raw_data_converted_ = true; |
| 145 decoder_.reset(); | 147 decoder_.reset(); |
| 148 array_buffer_result_ = nullptr; | |
| 149 UnreportMemoryUsageToV8(); | |
| 146 } | 150 } |
| 147 } | 151 } |
| 148 | 152 |
| 153 void FileReaderLoader::ReportAdditionalMemoryUsageToV8(int64_t usage) { | |
| 154 if (!usage) | |
| 155 return; | |
| 156 memory_usage_reported_to_v8_ += usage; | |
|
dmurph
2017/04/28 02:33:48
do a bounds check so it doesn't go negative (dchec
michaeln
2017/04/28 23:08:50
Done.
| |
| 157 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(usage); | |
| 158 } | |
| 159 | |
| 160 void FileReaderLoader::UnreportMemoryUsageToV8() { | |
| 161 if (!memory_usage_reported_to_v8_) | |
| 162 return; | |
| 163 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | |
| 164 -memory_usage_reported_to_v8_); | |
| 165 memory_usage_reported_to_v8_ = 0; | |
| 166 } | |
| 167 | |
| 149 void FileReaderLoader::DidReceiveResponse( | 168 void FileReaderLoader::DidReceiveResponse( |
| 150 unsigned long, | 169 unsigned long, |
| 151 const ResourceResponse& response, | 170 const ResourceResponse& response, |
| 152 std::unique_ptr<WebDataConsumerHandle> handle) { | 171 std::unique_ptr<WebDataConsumerHandle> handle) { |
| 153 DCHECK(!handle); | 172 DCHECK(!handle); |
| 154 if (response.HttpStatusCode() != 200) { | 173 if (response.HttpStatusCode() != 200) { |
| 155 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode())); | 174 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode())); |
| 156 return; | 175 return; |
| 157 } | 176 } |
| 158 | 177 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 | 242 |
| 224 unsigned bytes_appended = raw_data_->Append(data, data_length); | 243 unsigned bytes_appended = raw_data_->Append(data, data_length); |
| 225 if (!bytes_appended) { | 244 if (!bytes_appended) { |
| 226 raw_data_.reset(); | 245 raw_data_.reset(); |
| 227 bytes_loaded_ = 0; | 246 bytes_loaded_ = 0; |
| 228 Failed(FileError::kNotReadableErr); | 247 Failed(FileError::kNotReadableErr); |
| 229 return; | 248 return; |
| 230 } | 249 } |
| 231 bytes_loaded_ += bytes_appended; | 250 bytes_loaded_ += bytes_appended; |
| 232 is_raw_data_converted_ = false; | 251 is_raw_data_converted_ = false; |
| 252 ReportAdditionalMemoryUsageToV8(bytes_appended); | |
| 233 | 253 |
| 234 if (client_) | 254 if (client_) |
| 235 client_->DidReceiveData(); | 255 client_->DidReceiveData(); |
| 236 } | 256 } |
| 237 | 257 |
| 238 void FileReaderLoader::DidFinishLoading(unsigned long, double) { | 258 void FileReaderLoader::DidFinishLoading(unsigned long, double) { |
| 239 if (read_type_ != kReadByClient && raw_data_) { | 259 if (read_type_ != kReadByClient && raw_data_) { |
| 240 raw_data_->ShrinkToFit(); | 260 raw_data_->ShrinkToFit(); |
| 241 is_raw_data_converted_ = false; | 261 is_raw_data_converted_ = false; |
| 242 } | 262 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 return FileError::kSecurityErr; | 298 return FileError::kSecurityErr; |
| 279 case 404: | 299 case 404: |
| 280 return FileError::kNotFoundErr; | 300 return FileError::kNotFoundErr; |
| 281 default: | 301 default: |
| 282 return FileError::kNotReadableErr; | 302 return FileError::kNotReadableErr; |
| 283 } | 303 } |
| 284 } | 304 } |
| 285 | 305 |
| 286 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { | 306 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { |
| 287 DCHECK_EQ(read_type_, kReadAsArrayBuffer); | 307 DCHECK_EQ(read_type_, kReadAsArrayBuffer); |
| 308 if (array_buffer_result_) | |
| 309 return array_buffer_result_; | |
| 288 | 310 |
| 289 // If the loading is not started or an error occurs, return an empty result. | 311 // If the loading is not started or an error occurs, return an empty result. |
| 290 if (!raw_data_ || error_code_) | 312 if (!raw_data_ || error_code_) |
| 291 return nullptr; | 313 return nullptr; |
| 292 | 314 |
| 293 if (array_buffer_result_) | |
| 294 return array_buffer_result_; | |
| 295 | |
| 296 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); | 315 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); |
| 297 if (finished_loading_) { | 316 if (finished_loading_) { |
| 298 array_buffer_result_ = result; | 317 array_buffer_result_ = result; |
| 318 ReportAdditionalMemoryUsageToV8(-1 * raw_data_->ByteLength()); | |
|
dmurph
2017/04/28 02:33:48
change to AdjustReportedV8MemoryUsage?
michaeln
2017/04/28 23:08:50
Done.
| |
| 319 raw_data_.reset(); | |
| 299 } | 320 } |
| 300 return result; | 321 return result; |
| 301 } | 322 } |
| 302 | 323 |
| 303 String FileReaderLoader::StringResult() { | 324 String FileReaderLoader::StringResult() { |
| 304 DCHECK_NE(read_type_, kReadAsArrayBuffer); | 325 DCHECK_NE(read_type_, kReadAsArrayBuffer); |
| 305 DCHECK_NE(read_type_, kReadByClient); | 326 DCHECK_NE(read_type_, kReadByClient); |
| 306 | 327 |
| 307 // If the loading is not started or an error occurs, return an empty result. | 328 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_; | 329 return string_result_; |
| 314 | 330 |
| 315 switch (read_type_) { | 331 switch (read_type_) { |
| 316 case kReadAsArrayBuffer: | 332 case kReadAsArrayBuffer: |
| 317 // No conversion is needed. | 333 // No conversion is needed. |
| 318 break; | 334 return string_result_; |
| 319 case kReadAsBinaryString: | 335 case kReadAsBinaryString: |
| 320 string_result_ = raw_data_->ToString(); | 336 SetStringResult(raw_data_->ToString()); |
| 321 is_raw_data_converted_ = true; | |
| 322 break; | 337 break; |
| 323 case kReadAsText: | 338 case kReadAsText: |
| 324 ConvertToText(); | 339 SetStringResult(ConvertToText()); |
|
dmurph
2017/04/28 02:33:48
Do you need a std::move here?
michaeln
2017/04/28 23:08:50
I don't think that would do anything, SetStringRes
| |
| 325 break; | 340 break; |
| 326 case kReadAsDataURL: | 341 case kReadAsDataURL: |
| 327 // Partial data is not supported when reading as data URL. | 342 // Partial data is not supported when reading as data URL. |
| 328 if (finished_loading_) | 343 if (finished_loading_) |
| 329 ConvertToDataURL(); | 344 SetStringResult(ConvertToDataURL()); |
| 330 break; | 345 break; |
| 331 default: | 346 default: |
| 332 NOTREACHED(); | 347 NOTREACHED(); |
| 333 } | 348 } |
| 334 | 349 |
| 350 if (finished_loading_) { | |
| 351 DCHECK(is_raw_data_converted_); | |
| 352 ReportAdditionalMemoryUsageToV8(-1 * raw_data_->ByteLength()); | |
| 353 raw_data_.reset(); | |
| 354 } | |
| 335 return string_result_; | 355 return string_result_; |
| 336 } | 356 } |
| 337 | 357 |
| 338 void FileReaderLoader::ConvertToText() { | 358 void FileReaderLoader::SetStringResult(const String& result) { |
| 359 ReportAdditionalMemoryUsageToV8(-1 * string_result_.CharactersSizeInBytes()); | |
| 339 is_raw_data_converted_ = true; | 360 is_raw_data_converted_ = true; |
| 361 string_result_ = result; | |
| 362 ReportAdditionalMemoryUsageToV8(string_result_.CharactersSizeInBytes()); | |
| 363 } | |
| 340 | 364 |
| 341 if (!bytes_loaded_) { | 365 String FileReaderLoader::ConvertToText() { |
| 342 string_result_ = ""; | 366 if (!bytes_loaded_) |
| 343 return; | 367 return ""; |
| 344 } | |
| 345 | 368 |
| 346 // Decode the data. | 369 // Decode the data. |
| 347 // The File API spec says that we should use the supplied encoding if it is | 370 // 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 | 371 // 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 | 372 // consistent with how WebKit decodes the web content: always has the BOM |
| 350 // override the provided encoding. | 373 // override the provided encoding. |
| 351 // FIXME: consider supporting incremental decoding to improve the perf. | 374 // FIXME: consider supporting incremental decoding to improve the perf. |
| 352 StringBuilder builder; | 375 StringBuilder builder; |
| 353 if (!decoder_) | 376 if (!decoder_) |
| 354 decoder_ = TextResourceDecoder::Create( | 377 decoder_ = TextResourceDecoder::Create( |
| 355 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding()); | 378 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding()); |
| 356 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()), | 379 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()), |
| 357 raw_data_->ByteLength())); | 380 raw_data_->ByteLength())); |
| 358 | 381 |
| 359 if (finished_loading_) | 382 if (finished_loading_) |
| 360 builder.Append(decoder_->Flush()); | 383 builder.Append(decoder_->Flush()); |
| 361 | 384 |
| 362 string_result_ = builder.ToString(); | 385 return builder.ToString(); |
| 363 } | 386 } |
| 364 | 387 |
| 365 void FileReaderLoader::ConvertToDataURL() { | 388 String FileReaderLoader::ConvertToDataURL() { |
| 366 is_raw_data_converted_ = true; | |
| 367 | |
| 368 StringBuilder builder; | 389 StringBuilder builder; |
| 369 builder.Append("data:"); | 390 builder.Append("data:"); |
| 370 | 391 |
| 371 if (!bytes_loaded_) { | 392 if (!bytes_loaded_) |
| 372 string_result_ = builder.ToString(); | 393 return builder.ToString(); |
| 373 return; | |
| 374 } | |
| 375 | 394 |
| 376 builder.Append(data_type_); | 395 builder.Append(data_type_); |
| 377 builder.Append(";base64,"); | 396 builder.Append(";base64,"); |
| 378 | 397 |
| 379 Vector<char> out; | 398 Vector<char> out; |
| 380 Base64Encode(static_cast<const char*>(raw_data_->Data()), | 399 Base64Encode(static_cast<const char*>(raw_data_->Data()), |
| 381 raw_data_->ByteLength(), out); | 400 raw_data_->ByteLength(), out); |
| 382 out.push_back('\0'); | 401 out.push_back('\0'); |
| 383 builder.Append(out.data()); | 402 builder.Append(out.data()); |
| 384 | 403 |
| 385 string_result_ = builder.ToString(); | 404 return builder.ToString(); |
| 386 } | 405 } |
| 387 | 406 |
| 388 void FileReaderLoader::SetEncoding(const String& encoding) { | 407 void FileReaderLoader::SetEncoding(const String& encoding) { |
| 389 if (!encoding.IsEmpty()) | 408 if (!encoding.IsEmpty()) |
| 390 encoding_ = WTF::TextEncoding(encoding); | 409 encoding_ = WTF::TextEncoding(encoding); |
| 391 } | 410 } |
| 392 | 411 |
| 393 } // namespace blink | 412 } // namespace blink |
| OLD | NEW |