12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/net/input_stream_reader.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/input_stream.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_byte_range.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace android_webview {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)InputStreamReader::InputStreamReader(android_webview::InputStream* stream)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : stream_(stream) {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream);
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)InputStreamReader::~InputStreamReader() {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int InputStreamReader::Seek(const net::HttpByteRange& byte_range) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int content_size = 0;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::HttpByteRange verified_byte_range(byte_range);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int error_code = VerifyRequestedRange(&verified_byte_range, &content_size);
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error_code != net::OK)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return error_code;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  error_code = SkipToRequestedRange(verified_byte_range);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error_code != net::OK)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return error_code;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(content_size, 0);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return content_size;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int InputStreamReader::ReadRawData(net::IOBuffer* dest, int dest_size) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dest_size)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GT(dest_size, 0);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int bytes_read = 0;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_->Read(dest, dest_size, &bytes_read))
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return net::ERR_FAILED;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bytes_read;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int InputStreamReader::VerifyRequestedRange(net::HttpByteRange* byte_range,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            int* content_size) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(content_size);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int32_t size = 0;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!stream_->BytesAvailable(&size))
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return net::ERR_FAILED;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (size <= 0)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return net::OK;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that the requested range was valid.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!byte_range->ComputeBounds(size))
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size = byte_range->last_byte_position() -
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         byte_range->first_byte_position() + 1;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(size, 0);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *content_size = size;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net::OK;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int InputStreamReader::SkipToRequestedRange(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::HttpByteRange& byte_range) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skip to the start of the requested data. This has to be done in a loop
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // because the underlying InputStream is not guaranteed to skip the requested
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // number of bytes.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (byte_range.IsValid() && byte_range.first_byte_position() > 0) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64_t bytes_to_skip = byte_range.first_byte_position();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    do {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64_t skipped = 0;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!stream_->Skip(bytes_to_skip, &skipped))
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return net::ERR_FAILED;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (skipped <= 0)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_LE(skipped, bytes_to_skip);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bytes_to_skip -= skipped;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } while (bytes_to_skip > 0);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net::OK;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace android_webview
99