Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / base / upload_data_stream.h
index ac14e38..d7df8c9 100644 (file)
@@ -5,10 +5,9 @@
 #ifndef NET_BASE_UPLOAD_DATA_STREAM_H_
 #define NET_BASE_UPLOAD_DATA_STREAM_H_
 
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
+#include "base/basictypes.h"
+#include "base/macros.h"
 #include "base/memory/scoped_vector.h"
-#include "base/memory/weak_ptr.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
 
@@ -18,31 +17,22 @@ class DrainableIOBuffer;
 class IOBuffer;
 class UploadElementReader;
 
-// A class to read all elements from an UploadData object.
+// A class for retrieving all data to be sent as a request body. Supports both
+// chunked and non-chunked uploads.
 class NET_EXPORT UploadDataStream {
  public:
-  // An enum used to construct chunked data stream.
-  enum Chunked { CHUNKED };
+  // |identifier| identifies a particular upload instance, which is used by the
+  // cache to formulate a cache key. This value should be unique across browser
+  // sessions. A value of 0 is used to indicate an unspecified identifier.
+  UploadDataStream(bool is_chunked, int64 identifier);
 
-  // Constructs a non-chunked data stream.
-  UploadDataStream(ScopedVector<UploadElementReader> element_readers,
-                   int64 identifier);
-
-  // Constructs a chunked data stream.
-  UploadDataStream(Chunked chunked, int64 identifier);
-
-  ~UploadDataStream();
-
-  // Creates UploadDataStream with a reader.
-  static UploadDataStream* CreateWithReader(
-      scoped_ptr<UploadElementReader> reader,
-      int64 identifier);
+  virtual ~UploadDataStream();
 
   // Initializes the stream. This function must be called before calling any
   // other method. It is not valid to call any method (other than the
-  // destructor) if Init() returns a failure. This method can be called multiple
-  // times. Calling this method after a Init() success results in resetting the
-  // state.
+  // destructor) if Init() fails. This method can be called multiple times.
+  // Calling this method after an Init() success results in resetting the
+  // state (i.e. the stream is rewound).
   //
   // Does the initialization synchronously and returns the result if possible,
   // otherwise returns ERR_IO_PENDING and runs the callback with the result.
@@ -62,93 +52,88 @@ class NET_EXPORT UploadDataStream {
   // If there's less data to read than we initially observed (i.e. the actual
   // upload data is smaller than size()), zeros are padded to ensure that
   // size() bytes can be read, which can happen for TYPE_FILE payloads.
+  //
+  // Reads are currently not allowed to fail - they must either return
+  // a value >= 0 or ERR_IO_PENDING, and call OnReadCompleted with a
+  // value >= 0.
+  // TODO(mmenke):  Investigate letting reads fail.
   int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
 
-  // Identifies a particular upload instance, which is used by the cache to
-  // formulate a cache key.  This value should be unique across browser
-  // sessions.  A value of 0 is used to indicate an unspecified identifier.
-  int64 identifier() const { return identifier_; }
-
   // Returns the total size of the data stream and the current position.
-  // size() is not to be used to determine whether the stream has ended
-  // because it is possible for the stream to end before its size is reached,
-  // for example, if the file is truncated. When the data is chunked, size()
-  // always returns zero.
+  // When the data is chunked, always returns zero. Must always return the same
+  // value after each call to Initialize().
   uint64 size() const { return total_size_; }
   uint64 position() const { return current_position_; }
 
-  bool is_chunked() const { return is_chunked_; }
-  bool last_chunk_appended() const { return last_chunk_appended_; }
+  // See constructor for description.
+  int64 identifier() const { return identifier_; }
 
-  const ScopedVector<UploadElementReader>& element_readers() const {
-    return element_readers_;
-  }
+  bool is_chunked() const { return is_chunked_; }
 
   // Returns true if all data has been consumed from this upload data
-  // stream.
+  // stream. For chunked uploads, returns false until the first read attempt.
+  // This makes some state machines a little simpler.
   bool IsEOF() const;
 
-  // Returns true if the upload data in the stream is entirely in memory.
-  bool IsInMemory() const;
+  // Cancels all pending callbacks, and resets state. Any IOBuffer currently
+  // being read to is not safe for future use, as it may be in use on another
+  // thread.
+  void Reset();
+
+  // Returns true if the upload data in the stream is entirely in memory, and
+  // all read requests will succeed synchronously. Expected to return false for
+  // chunked requests.
+  virtual bool IsInMemory() const;
 
-  // Adds the given chunk of bytes to be sent with chunked transfer encoding.
-  void AppendChunk(const char* bytes, int bytes_len, bool is_last_chunk);
+  // Returns a list of element readers owned by |this|, if it has any.
+  virtual const ScopedVector<UploadElementReader>*
+      GetElementReaders() const;
 
-  // Resets this instance to the uninitialized state.
-  void Reset();
+ protected:
+  // Must be called by subclasses when InitInternal and ReadInternal complete
+  // asynchronously.
+  void OnInitCompleted(int result);
+  void OnReadCompleted(int result);
+
+  // Must be called before InitInternal completes, for non-chunked uploads.
+  // Must not be called for chunked uploads.
+  void SetSize(uint64 size);
+
+  // Must be called for chunked uploads before the final ReadInternal call
+  // completes. Must not be called for non-chunked uploads.
+  void SetIsFinalChunk();
 
  private:
-  // Runs Init() for all element readers.
-  // This method is used to implement Init().
-  int InitInternal(int start_index, const CompletionCallback& callback);
-
-  // Resumes initialization and runs callback with the result when necessary.
-  void ResumePendingInit(int start_index,
-                         const CompletionCallback& callback,
-                         int previous_result);
-
-  // Reads data from the element readers.
-  // This method is used to implement Read().
-  int ReadInternal(scoped_refptr<DrainableIOBuffer> buf,
-                   const CompletionCallback& callback);
-
-  // Resumes pending read and calls callback with the result when necessary.
-  void ResumePendingRead(scoped_refptr<DrainableIOBuffer> buf,
-                         const CompletionCallback& callback,
-                         int previous_result);
-
-  // Processes result of UploadElementReader::Read(). If |result| indicates
-  // success, updates |buf|'s offset. Otherwise, sets |read_failed_| to true.
-  void ProcessReadResult(scoped_refptr<DrainableIOBuffer> buf,
-                         int result);
-
-  ScopedVector<UploadElementReader> element_readers_;
-
-  // Index of the current upload element (i.e. the element currently being
-  // read). The index is used as a cursor to iterate over elements in
-  // |upload_data_|.
-  size_t element_index_;
-
-  // Size and current read position within the upload data stream.
-  // |total_size_| is set to zero when the data is chunked.
+  // See Init(). If it returns ERR_IO_PENDING, OnInitCompleted must be called
+  // once it completes. If the upload is not chunked, SetSize must be called
+  // before it completes.
+  virtual int InitInternal() = 0;
+
+  // See Read(). For chunked uploads, must call SetIsFinalChunk if this is the
+  // final chunk. For non-chunked uploads, the UploadDataStream determins which
+  // read is the last based on size. Must read 1 or more bytes on every call,
+  // though the final chunk may be 0 bytes, for chunked requests. If it returns
+  // ERR_IO_PENDING, OnInitCompleted must be called once it completes. Must not
+  // return any error, other than ERR_IO_PENDING.
+  virtual int ReadInternal(IOBuffer* buf, int buf_len) = 0;
+
+  // Resets state and cancels any pending callbacks. Guaranteed to be called
+  // before all but the first call to InitInternal.
+  virtual void ResetInternal() = 0;
+
   uint64 total_size_;
   uint64 current_position_;
 
   const int64 identifier_;
 
   const bool is_chunked_;
-  bool last_chunk_appended_;
-
-  // True if an error occcured during read operation.
-  bool read_failed_;
 
   // True if the initialization was successful.
   bool initialized_successfully_;
 
-  // Callback to resume reading chunked data.
-  base::Closure pending_chunked_read_callback_;
+  bool is_eof_;
 
-  base::WeakPtrFactory<UploadDataStream> weak_ptr_factory_;
+  CompletionCallback callback_;
 
   DISALLOW_COPY_AND_ASSIGN(UploadDataStream);
 };