Home | History | Annotate | Download | only in net
      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(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