xref: /aosp_15_r20/external/cronet/net/base/io_buffer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_BASE_IO_BUFFER_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_BASE_IO_BUFFER_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <memory>
12*6777b538SAndroid Build Coastguard Worker #include <string>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/containers/heap_array.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/free_deleter.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker namespace net {
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker // IOBuffers are reference counted data buffers used for easier asynchronous
25*6777b538SAndroid Build Coastguard Worker // IO handling.
26*6777b538SAndroid Build Coastguard Worker //
27*6777b538SAndroid Build Coastguard Worker // They are often used as the destination buffers for Read() operations, or as
28*6777b538SAndroid Build Coastguard Worker // the source buffers for Write() operations.
29*6777b538SAndroid Build Coastguard Worker //
30*6777b538SAndroid Build Coastguard Worker // IMPORTANT: Never re-use an IOBuffer after cancelling the IO operation that
31*6777b538SAndroid Build Coastguard Worker //            was using it, since this may lead to memory corruption!
32*6777b538SAndroid Build Coastguard Worker //
33*6777b538SAndroid Build Coastguard Worker // -----------------------
34*6777b538SAndroid Build Coastguard Worker // Ownership of IOBuffers:
35*6777b538SAndroid Build Coastguard Worker // -----------------------
36*6777b538SAndroid Build Coastguard Worker //
37*6777b538SAndroid Build Coastguard Worker // Although IOBuffers are RefCountedThreadSafe, they are not intended to be
38*6777b538SAndroid Build Coastguard Worker // used as a shared buffer, nor should they be used simultaneously across
39*6777b538SAndroid Build Coastguard Worker // threads. The fact that they are reference counted is an implementation
40*6777b538SAndroid Build Coastguard Worker // detail for allowing them to outlive cancellation of asynchronous
41*6777b538SAndroid Build Coastguard Worker // operations.
42*6777b538SAndroid Build Coastguard Worker //
43*6777b538SAndroid Build Coastguard Worker // Instead, think of the underlying |char*| buffer contained by the IOBuffer
44*6777b538SAndroid Build Coastguard Worker // as having exactly one owner at a time.
45*6777b538SAndroid Build Coastguard Worker //
46*6777b538SAndroid Build Coastguard Worker // Whenever you call an asynchronous operation that takes an IOBuffer,
47*6777b538SAndroid Build Coastguard Worker // ownership is implicitly transferred to the called function, until the
48*6777b538SAndroid Build Coastguard Worker // operation has completed (at which point it transfers back to the caller).
49*6777b538SAndroid Build Coastguard Worker //
50*6777b538SAndroid Build Coastguard Worker //     ==> The IOBuffer's data should NOT be manipulated, destroyed, or read
51*6777b538SAndroid Build Coastguard Worker //         until the operation has completed.
52*6777b538SAndroid Build Coastguard Worker //
53*6777b538SAndroid Build Coastguard Worker //     ==> Cancellation does NOT count as completion. If an operation using
54*6777b538SAndroid Build Coastguard Worker //         an IOBuffer is cancelled, the caller should release their
55*6777b538SAndroid Build Coastguard Worker //         reference to this IOBuffer at the time of cancellation since
56*6777b538SAndroid Build Coastguard Worker //         they can no longer use it.
57*6777b538SAndroid Build Coastguard Worker //
58*6777b538SAndroid Build Coastguard Worker // For instance, if you were to call a Read() operation on some class which
59*6777b538SAndroid Build Coastguard Worker // takes an IOBuffer, and then delete that class (which generally will
60*6777b538SAndroid Build Coastguard Worker // trigger cancellation), the IOBuffer which had been passed to Read() should
61*6777b538SAndroid Build Coastguard Worker // never be re-used.
62*6777b538SAndroid Build Coastguard Worker //
63*6777b538SAndroid Build Coastguard Worker // This usage contract is assumed by any API which takes an IOBuffer, even
64*6777b538SAndroid Build Coastguard Worker // though it may not be explicitly mentioned in the function's comments.
65*6777b538SAndroid Build Coastguard Worker //
66*6777b538SAndroid Build Coastguard Worker // -----------------------
67*6777b538SAndroid Build Coastguard Worker // Motivation
68*6777b538SAndroid Build Coastguard Worker // -----------------------
69*6777b538SAndroid Build Coastguard Worker //
70*6777b538SAndroid Build Coastguard Worker // The motivation for transferring ownership during cancellation is
71*6777b538SAndroid Build Coastguard Worker // to make it easier to work with un-cancellable operations.
72*6777b538SAndroid Build Coastguard Worker //
73*6777b538SAndroid Build Coastguard Worker // For instance, let's say under the hood your API called out to the
74*6777b538SAndroid Build Coastguard Worker // operating system's synchronous ReadFile() function on a worker thread.
75*6777b538SAndroid Build Coastguard Worker // When cancelling through our asynchronous interface, we have no way of
76*6777b538SAndroid Build Coastguard Worker // actually aborting the in progress ReadFile(). We must let it keep running,
77*6777b538SAndroid Build Coastguard Worker // and hence the buffer it was reading into must remain alive. Using
78*6777b538SAndroid Build Coastguard Worker // reference counting we can add a reference to the IOBuffer and make sure
79*6777b538SAndroid Build Coastguard Worker // it is not destroyed until after the synchronous operation has completed.
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker // Base class, never instantiated, does not own the buffer.
82*6777b538SAndroid Build Coastguard Worker class NET_EXPORT IOBuffer : public base::RefCountedThreadSafe<IOBuffer> {
83*6777b538SAndroid Build Coastguard Worker  public:
size()84*6777b538SAndroid Build Coastguard Worker   int size() const { return size_; }
85*6777b538SAndroid Build Coastguard Worker 
data()86*6777b538SAndroid Build Coastguard Worker   char* data() { return data_; }
data()87*6777b538SAndroid Build Coastguard Worker   const char* data() const { return data_; }
88*6777b538SAndroid Build Coastguard Worker 
bytes()89*6777b538SAndroid Build Coastguard Worker   uint8_t* bytes() { return reinterpret_cast<uint8_t*>(data()); }
bytes()90*6777b538SAndroid Build Coastguard Worker   const uint8_t* bytes() const {
91*6777b538SAndroid Build Coastguard Worker     return reinterpret_cast<const uint8_t*>(data());
92*6777b538SAndroid Build Coastguard Worker   }
93*6777b538SAndroid Build Coastguard Worker 
span()94*6777b538SAndroid Build Coastguard Worker   base::span<char> span() {
95*6777b538SAndroid Build Coastguard Worker     return base::make_span(data(), static_cast<size_t>(size_));
96*6777b538SAndroid Build Coastguard Worker   }
span()97*6777b538SAndroid Build Coastguard Worker   base::span<const char> span() const {
98*6777b538SAndroid Build Coastguard Worker     return base::make_span(data(), static_cast<size_t>(size_));
99*6777b538SAndroid Build Coastguard Worker   }
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker  protected:
102*6777b538SAndroid Build Coastguard Worker   friend class base::RefCountedThreadSafe<IOBuffer>;
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker   static void AssertValidBufferSize(size_t size);
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   IOBuffer();
107*6777b538SAndroid Build Coastguard Worker   explicit IOBuffer(base::span<char> data);
108*6777b538SAndroid Build Coastguard Worker   explicit IOBuffer(base::span<uint8_t> data);
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   virtual ~IOBuffer();
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   raw_ptr<char, AcrossTasksDanglingUntriaged | AllowPtrArithmetic> data_ =
113*6777b538SAndroid Build Coastguard Worker       nullptr;
114*6777b538SAndroid Build Coastguard Worker   int size_ = 0;
115*6777b538SAndroid Build Coastguard Worker };
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker // Class which owns its buffer and manages its destruction.
118*6777b538SAndroid Build Coastguard Worker class NET_EXPORT IOBufferWithSize : public IOBuffer {
119*6777b538SAndroid Build Coastguard Worker  public:
120*6777b538SAndroid Build Coastguard Worker   IOBufferWithSize();
121*6777b538SAndroid Build Coastguard Worker   explicit IOBufferWithSize(size_t size);
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker  protected:
124*6777b538SAndroid Build Coastguard Worker   ~IOBufferWithSize() override;
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker  private:
127*6777b538SAndroid Build Coastguard Worker   base::HeapArray<char> storage_;
128*6777b538SAndroid Build Coastguard Worker };
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker // This is a read only IOBuffer.  The data is stored in a string and
131*6777b538SAndroid Build Coastguard Worker // the IOBuffer interface does not provide a proper way to modify it.
132*6777b538SAndroid Build Coastguard Worker class NET_EXPORT StringIOBuffer : public IOBuffer {
133*6777b538SAndroid Build Coastguard Worker  public:
134*6777b538SAndroid Build Coastguard Worker   explicit StringIOBuffer(std::string s);
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker  private:
137*6777b538SAndroid Build Coastguard Worker   ~StringIOBuffer() override;
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker   std::string string_data_;
140*6777b538SAndroid Build Coastguard Worker };
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker // This version wraps an existing IOBuffer and provides convenient functions
143*6777b538SAndroid Build Coastguard Worker // to progressively read all the data.
144*6777b538SAndroid Build Coastguard Worker //
145*6777b538SAndroid Build Coastguard Worker // DrainableIOBuffer is useful when you have an IOBuffer that contains data
146*6777b538SAndroid Build Coastguard Worker // to be written progressively, and Write() function takes an IOBuffer rather
147*6777b538SAndroid Build Coastguard Worker // than char*. DrainableIOBuffer can be used as follows:
148*6777b538SAndroid Build Coastguard Worker //
149*6777b538SAndroid Build Coastguard Worker // // payload is the IOBuffer containing the data to be written.
150*6777b538SAndroid Build Coastguard Worker // buf = base::MakeRefCounted<DrainableIOBuffer>(payload, payload_size);
151*6777b538SAndroid Build Coastguard Worker //
152*6777b538SAndroid Build Coastguard Worker // while (buf->BytesRemaining() > 0) {
153*6777b538SAndroid Build Coastguard Worker //   // Write() takes an IOBuffer. If it takes char*, we could
154*6777b538SAndroid Build Coastguard Worker //   // simply use the regular IOBuffer like payload->data() + offset.
155*6777b538SAndroid Build Coastguard Worker //   int bytes_written = Write(buf, buf->BytesRemaining());
156*6777b538SAndroid Build Coastguard Worker //   buf->DidConsume(bytes_written);
157*6777b538SAndroid Build Coastguard Worker // }
158*6777b538SAndroid Build Coastguard Worker //
159*6777b538SAndroid Build Coastguard Worker class NET_EXPORT DrainableIOBuffer : public IOBuffer {
160*6777b538SAndroid Build Coastguard Worker  public:
161*6777b538SAndroid Build Coastguard Worker   DrainableIOBuffer(scoped_refptr<IOBuffer> base, size_t size);
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   // DidConsume() changes the |data_| pointer so that |data_| always points
164*6777b538SAndroid Build Coastguard Worker   // to the first unconsumed byte.
165*6777b538SAndroid Build Coastguard Worker   void DidConsume(int bytes);
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   // Returns the number of unconsumed bytes.
168*6777b538SAndroid Build Coastguard Worker   int BytesRemaining() const;
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker   // Returns the number of consumed bytes.
171*6777b538SAndroid Build Coastguard Worker   int BytesConsumed() const;
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   // Seeks to an arbitrary point in the buffer. The notion of bytes consumed
174*6777b538SAndroid Build Coastguard Worker   // and remaining are updated appropriately.
175*6777b538SAndroid Build Coastguard Worker   void SetOffset(int bytes);
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker  private:
178*6777b538SAndroid Build Coastguard Worker   ~DrainableIOBuffer() override;
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBuffer> base_;
181*6777b538SAndroid Build Coastguard Worker   int used_ = 0;
182*6777b538SAndroid Build Coastguard Worker };
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker // This version provides a resizable buffer and a changeable offset.
185*6777b538SAndroid Build Coastguard Worker //
186*6777b538SAndroid Build Coastguard Worker // GrowableIOBuffer is useful when you read data progressively without
187*6777b538SAndroid Build Coastguard Worker // knowing the total size in advance. GrowableIOBuffer can be used as
188*6777b538SAndroid Build Coastguard Worker // follows:
189*6777b538SAndroid Build Coastguard Worker //
190*6777b538SAndroid Build Coastguard Worker // buf = base::MakeRefCounted<GrowableIOBuffer>();
191*6777b538SAndroid Build Coastguard Worker // buf->SetCapacity(1024);  // Initial capacity.
192*6777b538SAndroid Build Coastguard Worker //
193*6777b538SAndroid Build Coastguard Worker // while (!some_stream->IsEOF()) {
194*6777b538SAndroid Build Coastguard Worker //   // Double the capacity if the remaining capacity is empty.
195*6777b538SAndroid Build Coastguard Worker //   if (buf->RemainingCapacity() == 0)
196*6777b538SAndroid Build Coastguard Worker //     buf->SetCapacity(buf->capacity() * 2);
197*6777b538SAndroid Build Coastguard Worker //   int bytes_read = some_stream->Read(buf, buf->RemainingCapacity());
198*6777b538SAndroid Build Coastguard Worker //   buf->set_offset(buf->offset() + bytes_read);
199*6777b538SAndroid Build Coastguard Worker // }
200*6777b538SAndroid Build Coastguard Worker //
201*6777b538SAndroid Build Coastguard Worker class NET_EXPORT GrowableIOBuffer : public IOBuffer {
202*6777b538SAndroid Build Coastguard Worker  public:
203*6777b538SAndroid Build Coastguard Worker   GrowableIOBuffer();
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   // realloc memory to the specified capacity.
206*6777b538SAndroid Build Coastguard Worker   void SetCapacity(int capacity);
capacity()207*6777b538SAndroid Build Coastguard Worker   int capacity() { return capacity_; }
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker   // |offset| moves the |data_| pointer, allowing "seeking" in the data.
210*6777b538SAndroid Build Coastguard Worker   void set_offset(int offset);
offset()211*6777b538SAndroid Build Coastguard Worker   int offset() { return offset_; }
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker   int RemainingCapacity();
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/329476354): Remove this method, use everything() to access
216*6777b538SAndroid Build Coastguard Worker   // the full buffer.
217*6777b538SAndroid Build Coastguard Worker   char* StartOfBuffer();
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   // Returns the entire buffer, including the bytes before the `offset()`.
220*6777b538SAndroid Build Coastguard Worker   //
221*6777b538SAndroid Build Coastguard Worker   // The `span()` method in the base class only gives the part of the buffer
222*6777b538SAndroid Build Coastguard Worker   // after `offset()`.
223*6777b538SAndroid Build Coastguard Worker   base::span<uint8_t> everything();
224*6777b538SAndroid Build Coastguard Worker   base::span<const uint8_t> everything() const;
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker  private:
227*6777b538SAndroid Build Coastguard Worker   ~GrowableIOBuffer() override;
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   // TODO(329476354): Convert to std::vector, use reserve()+resize() to make
230*6777b538SAndroid Build Coastguard Worker   // exact reallocs, and remove `capacity_`. Possibly with an allocator the
231*6777b538SAndroid Build Coastguard Worker   // default-initializes, if it's important to not initialize the new memory?
232*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<char, base::FreeDeleter> real_data_;
233*6777b538SAndroid Build Coastguard Worker   int capacity_ = 0;
234*6777b538SAndroid Build Coastguard Worker   int offset_ = 0;
235*6777b538SAndroid Build Coastguard Worker };
236*6777b538SAndroid Build Coastguard Worker 
237*6777b538SAndroid Build Coastguard Worker // This versions allows a pickle to be used as the storage for a write-style
238*6777b538SAndroid Build Coastguard Worker // operation, avoiding an extra data copy.
239*6777b538SAndroid Build Coastguard Worker class NET_EXPORT PickledIOBuffer : public IOBuffer {
240*6777b538SAndroid Build Coastguard Worker  public:
241*6777b538SAndroid Build Coastguard Worker   PickledIOBuffer();
242*6777b538SAndroid Build Coastguard Worker 
pickle()243*6777b538SAndroid Build Coastguard Worker   base::Pickle* pickle() { return &pickle_; }
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker   // Signals that we are done writing to the pickle and we can use it for a
246*6777b538SAndroid Build Coastguard Worker   // write-style IO operation.
247*6777b538SAndroid Build Coastguard Worker   void Done();
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker  private:
250*6777b538SAndroid Build Coastguard Worker   ~PickledIOBuffer() override;
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   base::Pickle pickle_;
253*6777b538SAndroid Build Coastguard Worker };
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker // This class allows the creation of a temporary IOBuffer that doesn't really
256*6777b538SAndroid Build Coastguard Worker // own the underlying buffer. Please use this class only as a last resort.
257*6777b538SAndroid Build Coastguard Worker // A good example is the buffer for a synchronous operation, where we can be
258*6777b538SAndroid Build Coastguard Worker // sure that nobody is keeping an extra reference to this object so the lifetime
259*6777b538SAndroid Build Coastguard Worker // of the buffer can be completely managed by its intended owner.
260*6777b538SAndroid Build Coastguard Worker // This is now nearly the same as the base IOBuffer class, except that it
261*6777b538SAndroid Build Coastguard Worker // accepts const data as constructor arguments.
262*6777b538SAndroid Build Coastguard Worker class NET_EXPORT WrappedIOBuffer : public IOBuffer {
263*6777b538SAndroid Build Coastguard Worker  public:
264*6777b538SAndroid Build Coastguard Worker   explicit WrappedIOBuffer(base::span<const char> data);
265*6777b538SAndroid Build Coastguard Worker   explicit WrappedIOBuffer(base::span<const uint8_t> data);
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker  protected:
268*6777b538SAndroid Build Coastguard Worker   ~WrappedIOBuffer() override;
269*6777b538SAndroid Build Coastguard Worker };
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker }  // namespace net
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker #endif  // NET_BASE_IO_BUFFER_H_
274