Index: content/browser/renderer_host/websocket_blob_receiver.h |
diff --git a/content/browser/renderer_host/websocket_blob_receiver.h b/content/browser/renderer_host/websocket_blob_receiver.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d4033ed4459e109168e4b3276124a41569967bc5 |
--- /dev/null |
+++ b/content/browser/renderer_host/websocket_blob_receiver.h |
@@ -0,0 +1,143 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef WEBSOCKET_BLOB_RECEIVER_H_ |
+#define WEBSOCKET_BLOB_RECEIVER_H_ |
+ |
+#include <stdint.h> |
+#include <iosfwd> |
+#include <vector> |
+ |
+#include "base/files/file.h" |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
+#include "content/common/content_export.h" |
+ |
+namespace net { |
+class FileStream; |
+class DrainableIOBuffer; |
+} |
+ |
+namespace storage { |
+class BlobDataHandle; |
+class BlobStorageContext; |
+class ShareableFileReference; |
+} |
+ |
+namespace content { |
+ |
+// Reads data from a WebSocket and writes it to a Blob for later access by the |
+// renderer. |
+class CONTENT_EXPORT WebSocketBlobReceiver { |
+ public: |
+ // Interface to be implemented by the client of WebSocketBlobReceiver. None of |
+ // these methods will be called after the WebSocketBlobReceiver object has |
+ // been destroyed. |
+ class Client { |
+ public: |
+ Client() = default; |
+ virtual ~Client() = default; |
+ |
+ // Signals that a Blob has successfully been created. Will be called |
+ // asynchronously after WebSocketBlobReceiver::Finish() returns. The |
+ // owner of the WebSocketBlobReceiver object should delete it after this is |
+ // called. |blob_data_handle| must be copied to keep the Blob alive. |
+ virtual void BlobCreated( |
+ const storage::BlobDataHandle& blob_data_handle) = 0; |
+ |
+ // Signals asynchronously that Blob creation failed. Synchronous failures |
+ // are indicated by AppendData() or Finish() returning net error codes. |
+ // May be called any time after Start() returns. |
+ virtual void BlobFailed(int net_error_code) = 0; |
+ |
+ // Indicates that up to |quota| additional bytes of data may be passed to |
+ // OnNewData(). May be called any time between Start() and Finish(). |
+ virtual void AddFlowControlQuota(int64_t quota) = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(Client); |
+ }; |
+ |
+ // |blob_storage_context| must out-live this object. |client| will be |
+ // destroyed when this object is. |
+ WebSocketBlobReceiver(scoped_ptr<Client> client, |
+ storage::BlobStorageContext* blob_storage_context); |
+ ~WebSocketBlobReceiver(); |
+ |
+ // Prepares to create the Blob. Calls AddFlowControlQuota() asychronously when |
+ // it is ready to accept data. Calls BlobFailed() asynchronously on error. |
+ void Start(); |
+ |
+ // Adds data to the Blob at the end. It is reasonable to call this for small |
+ // amounts of data: a new BlobDataItem is not created for each call. May call |
+ // AddFlowControlQuota() synchronously or asynchronously when it is ready for |
+ // more data. Returns a net::Error code on synchronous error, net::OK on |
+ // synchronous success, or net::ERR_IO_PENDING. |data| must not be larger than |
+ // the unused bytes passed to client_->AddFlowControlQuota() so far. |
+ int AppendData(const std::vector<char>& data); |
+ |
+ // Indicates that AppendData() will not be called again and that the Blob |
+ // should be finalised. Returns a net::Error code on synchronous failure. |
+ // BlobCreated() or BlobFailed() will be called asynchronously after this |
+ // method returns net::ERR_IO_PENDING. |
+ int Finish(); |
+ |
+ private: |
+ class FileInfoHelper; |
+ |
+ enum class State { |
+ NONE = 0, |
+ CREATE_FILE, |
+ CREATE_FILE_COMPLETE, |
+ SEND_QUOTA, |
+ WRITE, |
+ WRITE_COMPLETE, |
+ GET_INFO, |
+ GET_INFO_COMPLETE, |
+ }; |
+ |
+ // Needed to make CHECK_EQ(), etc. work |
+ friend std::ostream& operator<<(std::ostream& os, State state); |
+ |
+ int DoLoop(int result); |
+ void DoLoopAsync(int result); |
+ int DoCreateFile(); |
+ int DoCreateFileComplete(int result); |
+ int DoSendQuota(); |
+ int DoWrite(); |
+ int DoWriteComplete(int result); |
+ int DoGetInfo(); |
+ int DoGetInfoComplete(int result); |
+ |
+ void OnWriteComplete(int result); |
+ |
+ void DidCreateTemporaryFileStream( |
+ base::File::Error error_code, |
+ scoped_ptr<net::FileStream> file_stream, |
+ storage::ShareableFileReference* deletable_file); |
+ |
+ void PrepareWrite(const std::vector<char>& data); |
+ |
+ void DidGetInfo(bool result, const base::File::Info& info); |
+ |
+ const scoped_ptr<Client> client_; |
+ storage::BlobStorageContext* blob_storage_context_; |
+ scoped_ptr<net::FileStream> file_stream_; |
+ scoped_refptr<storage::ShareableFileReference> deletable_file_; |
+ const scoped_refptr<net::DrainableIOBuffer> io_buffer_; |
+ std::vector<char> pending_data_; |
+ int64_t pending_quota_; |
+ State next_state_ = State::NONE; |
+ bool io_in_progress_ = false; |
+ bool finish_called_ = false; |
+ base::WeakPtrFactory<WebSocketBlobReceiver> weak_factory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WebSocketBlobReceiver); |
+}; |
+ |
+} // namespace content |
+ |
+#endif |