1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "android_webview/browser/net/input_stream_reader.h" 6 7 #include "android_webview/browser/input_stream.h" 8 #include "base/message_loop/message_loop.h" 9 #include "content/public/browser/browser_thread.h" 10 #include "net/base/net_errors.h" 11 #include "net/http/http_byte_range.h" 12 13 using content::BrowserThread; 14 15 namespace android_webview { 16 17 InputStreamReader::InputStreamReader(android_webview::InputStream* stream) 18 : stream_(stream) { 19 DCHECK(stream); 20 } 21 22 InputStreamReader::~InputStreamReader() { 23 } 24 25 int InputStreamReader::Seek(const net::HttpByteRange& byte_range) { 26 int content_size = 0; 27 net::HttpByteRange verified_byte_range(byte_range); 28 29 int error_code = VerifyRequestedRange(&verified_byte_range, &content_size); 30 if (error_code != net::OK) 31 return error_code; 32 33 error_code = SkipToRequestedRange(verified_byte_range); 34 if (error_code != net::OK) 35 return error_code; 36 37 DCHECK_GE(content_size, 0); 38 return content_size; 39 } 40 41 int InputStreamReader::ReadRawData(net::IOBuffer* dest, int dest_size) { 42 if (!dest_size) 43 return 0; 44 45 DCHECK_GT(dest_size, 0); 46 47 int bytes_read = 0; 48 if (!stream_->Read(dest, dest_size, &bytes_read)) 49 return net::ERR_FAILED; 50 else 51 return bytes_read; 52 } 53 54 int InputStreamReader::VerifyRequestedRange(net::HttpByteRange* byte_range, 55 int* content_size) { 56 DCHECK(content_size); 57 int32_t size = 0; 58 if (!stream_->BytesAvailable(&size)) 59 return net::ERR_FAILED; 60 61 if (size <= 0) 62 return net::OK; 63 64 // Check that the requested range was valid. 65 if (!byte_range->ComputeBounds(size)) 66 return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; 67 68 size = byte_range->last_byte_position() - 69 byte_range->first_byte_position() + 1; 70 DCHECK_GE(size, 0); 71 *content_size = size; 72 73 return net::OK; 74 } 75 76 int InputStreamReader::SkipToRequestedRange( 77 const net::HttpByteRange& byte_range) { 78 // Skip to the start of the requested data. This has to be done in a loop 79 // because the underlying InputStream is not guaranteed to skip the requested 80 // number of bytes. 81 if (byte_range.IsValid() && byte_range.first_byte_position() > 0) { 82 int64_t bytes_to_skip = byte_range.first_byte_position(); 83 do { 84 int64_t skipped = 0; 85 if (!stream_->Skip(bytes_to_skip, &skipped)) 86 return net::ERR_FAILED; 87 88 if (skipped <= 0) 89 return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; 90 DCHECK_LE(skipped, bytes_to_skip); 91 92 bytes_to_skip -= skipped; 93 } while (bytes_to_skip > 0); 94 } 95 return net::OK; 96 } 97 98 } // namespace android_webview 99