1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_BASE_UPLOAD_DATA_STREAM_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_BASE_UPLOAD_DATA_STREAM_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/upload_data.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1269dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#ifdef ANDROID 1369dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#include "android/jni/platform_file_jni.h" 1469dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#endif 1569dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass FileStream; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass IOBuffer; 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass UploadDataStream { 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ~UploadDataStream(); 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns a new instance of UploadDataStream if it can be created and 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // initialized successfully. If not, NULL will be returned and the error 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // code will be set if the output parameter error_code is not empty. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static UploadDataStream* Create(UploadData* data, int* error_code); 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the stream's buffer and buffer length. 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IOBuffer* buf() const { return buf_; } 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t buf_len() const { return buf_len_; } 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO(satish): We should ideally have UploadDataStream expose a Read() 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // method which returns data in a caller provided IOBuffer. That would do away 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // with this method and make the interface cleaner as well with less memmove 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // calls. 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t GetMaxBufferSize() const { return kBufSize; } 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Call to indicate that a portion of the stream's buffer was consumed. This 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // call modifies the stream's buffer so that it contains the next segment of 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the upload data to be consumed. 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void MarkConsumedAndFillBuffer(size_t num_bytes); 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Sets the callback to be invoked when new chunks are available to upload. 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void set_chunk_callback(ChunkCallback* callback) { 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data_->set_chunk_callback(callback); 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the total size of the data stream and the current position. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // size() is not to be used to determine whether the stream has ended 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // because it is possible for the stream to end before its size is reached, 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for example, if the file is truncated. 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 size() const { return total_size_; } 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 position() const { return current_position_; } 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool is_chunked() const { return data_->is_chunked(); } 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns whether there is no more data to read, regardless of whether 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // position < size. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool eof() const { return eof_; } 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Returns whether the data available in buf() includes the last chunk in a 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // chunked data stream. This method returns true once the final chunk has been 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // placed in the IOBuffer returned by buf(), in contrast to eof() which 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // returns true only after the data in buf() has been consumed. 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool IsOnLastChunk() const; 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(UNIT_TEST) 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static void set_merge_chunks(bool merge) { merge_chunks_ = merge; } 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen enum { kBufSize = 16384 }; 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Protects from public access since now we have a static creator function 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which will do both creation and initialization and might return an error. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit UploadDataStream(UploadData* data); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fills the buffer with any remaining data and sets eof_ if there was nothing 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // left to fill the buffer with. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns OK if the operation succeeds. Otherwise error code is returned. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int FillBuf(); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<UploadData> data_; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This buffer is filled with data to be uploaded. The data to be sent is 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // always at the front of the buffer. If we cannot send all of the buffer at 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // once, then we memmove the remaining portion and back-fill the buffer for 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the next "write" call. buf_len_ indicates how much data is in the buffer. 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<IOBuffer> buf_; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t buf_len_; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Index of the upload element to be written to the send buffer next. 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t next_element_; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The byte offset into next_element_'s data buffer if the next element is 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a TYPE_BYTES element. 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t next_element_offset_; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A stream to the currently open file, for next_element_ if the next element 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is a TYPE_FILE element. 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<FileStream> next_element_stream_; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10569dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#ifdef ANDROID 106a01ff25d304217e7ef77ad2d83f48aca73be2c9dKristian Monsen scoped_ptr<android::JavaISWrapper> next_element_java_stream_; 10769dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#endif 10869dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The number of bytes remaining to be read from the currently open file 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // if the next element is of TYPE_FILE. 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 next_element_remaining_; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Size and current read position within the stream. 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 total_size_; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint64 current_position_; 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Whether there is no data left to read. 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool eof_; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO(satish): Remove this once we have a better way to unit test POST 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // requests with chunked uploads. 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static bool merge_chunks_; 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(UploadDataStream); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_UPLOAD_DATA_STREAM_H_ 130