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