• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
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 NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
6 #define NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <vector>
13 
14 #include "base/memory/scoped_refptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "net/base/net_export.h"
17 #include "net/base/upload_data_stream.h"
18 
19 namespace net {
20 
21 class IOBuffer;
22 
23 // Class with a push-based interface for uploading data. Buffers all data until
24 // the request is completed. Not recommended for uploading large amounts of
25 // seekable data, due to this buffering behavior.
26 class NET_EXPORT ChunkedUploadDataStream : public UploadDataStream {
27  public:
28   // Utility class that allows writing data to a particular
29   // ChunkedUploadDataStream. It can outlive the associated
30   // ChunkedUploadDataStream, and the URLRequest it is associated with, and
31   // still be safely used. This allows the consumer to not have to worry about
32   // the lifetime of the ChunkedUploadDataStream, which the owning URLRequest
33   // may delete without warning.
34   //
35   // The writer may only be used on the ChunkedUploadDataStream's thread.
36   class NET_EXPORT Writer {
37    public:
38     Writer(const Writer&) = delete;
39     Writer& operator=(const Writer&) = delete;
40     ~Writer();
41 
42     // Adds data to the stream. |is_done| should be true if this is the last
43     // data to be appended. |data_len| must not be 0 unless |is_done| is true.
44     // Once called with |is_done| being true, must never be called again.
45     // Returns true if write was passed successfully on to the next layer,
46     // though the data may not actually have been written to the underlying
47     // URLRequest.  Returns false if unable to write the data failed because the
48     // underlying ChunkedUploadDataStream was destroyed.
49     bool AppendData(const char* data, int data_len, bool is_done);
50 
51    private:
52     friend class ChunkedUploadDataStream;
53 
54     explicit Writer(base::WeakPtr<ChunkedUploadDataStream> upload_data_stream);
55 
56     const base::WeakPtr<ChunkedUploadDataStream> upload_data_stream_;
57   };
58 
59   explicit ChunkedUploadDataStream(int64_t identifier,
60                                    bool has_null_source = false);
61 
62   ChunkedUploadDataStream(const ChunkedUploadDataStream&) = delete;
63   ChunkedUploadDataStream& operator=(const ChunkedUploadDataStream&) = delete;
64   ~ChunkedUploadDataStream() override;
65 
66   // Creates a Writer for appending data to |this|.  It's generally expected
67   // that only one writer is created per stream, though multiple writers are
68   // allowed.  All writers write to the same stream, and once one of them
69   // appends data with |is_done| being true, no other writers may be used to
70   // append data.
71   std::unique_ptr<Writer> CreateWriter();
72 
73   // Adds data to the stream. |is_done| should be true if this is the last
74   // data to be appended. |data_len| must not be 0 unless |is_done| is true.
75   // Once called with |is_done| being true, must never be called again.
76   // TODO(mmenke):  Consider using IOBuffers instead, to reduce data copies.
77   // TODO(mmenke):  Consider making private, and having all consumers use
78   //     Writers.
79   void AppendData(const char* data, int data_len, bool is_done);
80 
81  private:
82   // UploadDataStream implementation.
83   int InitInternal(const NetLogWithSource& net_log) override;
84   int ReadInternal(IOBuffer* buf, int buf_len) override;
85   void ResetInternal() override;
86 
87   int ReadChunk(IOBuffer* buf, int buf_len);
88 
89   // Index and offset of next element of |upload_data_| to be read.
90   size_t read_index_ = 0;
91   size_t read_offset_ = 0;
92 
93   // True once all data has been appended to the stream.
94   bool all_data_appended_ = false;
95 
96   std::vector<std::unique_ptr<std::vector<char>>> upload_data_;
97 
98   // Buffer to write the next read's data to. Only set when a call to
99   // ReadInternal reads no data.
100   scoped_refptr<IOBuffer> read_buffer_;
101   int read_buffer_len_ = 0;
102 
103   base::WeakPtrFactory<ChunkedUploadDataStream> weak_factory_{this};
104 };
105 
106 }  // namespace net
107 
108 #endif  // NET_BASE_CHUNKED_UPLOAD_DATA_STREAM_H_
109