1// Copyright (c) 2013 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#ifndef CONTENT_BROWSER_STREAMS_STREAM_H_
6#define CONTENT_BROWSER_STREAMS_STREAM_H_
7
8#include "base/basictypes.h"
9#include "base/memory/ref_counted.h"
10#include "base/memory/weak_ptr.h"
11#include "content/browser/byte_stream.h"
12#include "content/common/content_export.h"
13#include "url/gurl.h"
14
15namespace net {
16class IOBuffer;
17}
18
19namespace content {
20
21class StreamHandle;
22class StreamHandleImpl;
23class StreamReadObserver;
24class StreamRegistry;
25class StreamWriteObserver;
26
27// A stream that sends data from an arbitrary source to an internal URL
28// that can be read by an internal consumer.  It will continue to pull from the
29// original URL as long as there is data available.  It can be read from
30// multiple clients, but only one can be reading at a time. This allows a
31// reader to consume part of the stream, then pass it along to another client
32// to continue processing the stream.
33class CONTENT_EXPORT Stream : public base::RefCountedThreadSafe<Stream> {
34 public:
35  enum StreamState {
36    STREAM_HAS_DATA,
37    STREAM_COMPLETE,
38    STREAM_EMPTY,
39  };
40
41  // Creates a stream.
42  //
43  // Security origin of Streams is checked in Blink (See BlobRegistry,
44  // BlobURL and SecurityOrigin to understand how it works). There's no security
45  // origin check in Chromium side for now.
46  Stream(StreamRegistry* registry,
47         StreamWriteObserver* write_observer,
48         const GURL& url);
49
50  // Sets the reader of this stream. Returns true on success, or false if there
51  // is already a reader.
52  bool SetReadObserver(StreamReadObserver* observer);
53
54  // Removes the read observer.  |observer| must be the current observer.
55  void RemoveReadObserver(StreamReadObserver* observer);
56
57  // Removes the write observer.  |observer| must be the current observer.
58  void RemoveWriteObserver(StreamWriteObserver* observer);
59
60  // Adds the data in |buffer| to the stream.  Takes ownership of |buffer|.
61  void AddData(scoped_refptr<net::IOBuffer> buffer, size_t size);
62  // Adds data of |size| at |data| to the stream. This method creates a copy
63  // of the data, and then passes it to |writer_|.
64  void AddData(const char* data, size_t size);
65
66  // Notifies this stream that it will not be receiving any more data.
67  void Finalize();
68
69  // Reads a maximum of |buf_size| from the stream into |buf|.  Sets
70  // |*bytes_read| to the number of bytes actually read.
71  // Returns STREAM_HAS_DATA if data was read, STREAM_EMPTY if no data was read,
72  // and STREAM_COMPLETE if the stream is finalized and all data has been read.
73  StreamState ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read);
74
75  scoped_ptr<StreamHandle> CreateHandle(const GURL& original_url,
76                                        const std::string& mime_type);
77  void CloseHandle();
78
79  // Indicates whether there is space in the buffer to add more data.
80  bool can_add_data() const { return can_add_data_; }
81
82  const GURL& url() const { return url_; }
83
84 private:
85  friend class base::RefCountedThreadSafe<Stream>;
86
87  virtual ~Stream();
88
89  void OnSpaceAvailable();
90  void OnDataAvailable();
91
92  size_t data_bytes_read_;
93  bool can_add_data_;
94
95  GURL url_;
96
97  scoped_refptr<net::IOBuffer> data_;
98  size_t data_length_;
99
100  scoped_ptr<ByteStreamWriter> writer_;
101  scoped_ptr<ByteStreamReader> reader_;
102
103  StreamRegistry* registry_;
104  StreamReadObserver* read_observer_;
105  StreamWriteObserver* write_observer_;
106
107  StreamHandleImpl* stream_handle_;
108
109  base::WeakPtrFactory<Stream> weak_ptr_factory_;
110  DISALLOW_COPY_AND_ASSIGN(Stream);
111};
112
113}  // namespace content
114
115#endif  // CONTENT_BROWSER_STREAMS_STREAM_H_
116