1 // Copyright (c) 2009 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 NET_BASE_IO_BUFFER_H_ 6 #define NET_BASE_IO_BUFFER_H_ 7 8 #include <string> 9 10 #include "base/pickle.h" 11 #include "base/ref_counted.h" 12 #include "base/scoped_ptr.h" 13 14 namespace net { 15 16 // This is a simple wrapper around a buffer that provides ref counting for 17 // easier asynchronous IO handling. 18 class IOBuffer : public base::RefCountedThreadSafe<IOBuffer> { 19 public: 20 IOBuffer() : data_(NULL) {} 21 explicit IOBuffer(int buffer_size); 22 23 char* data() { return data_; } 24 25 protected: 26 friend class base::RefCountedThreadSafe<IOBuffer>; 27 28 // Only allow derived classes to specify data_. 29 // In all other cases, we own data_, and must delete it at destruction time. 30 explicit IOBuffer(char* data) : data_(data) {} 31 32 virtual ~IOBuffer() { 33 delete[] data_; 34 } 35 36 char* data_; 37 }; 38 39 // This version stores the size of the buffer so that the creator of the object 40 // doesn't have to keep track of that value. 41 // NOTE: This doesn't mean that we want to stop sending the size as an explicit 42 // argument to IO functions. Please keep using IOBuffer* for API declarations. 43 class IOBufferWithSize : public IOBuffer { 44 public: 45 explicit IOBufferWithSize(int size) : IOBuffer(size), size_(size) {} 46 47 int size() const { return size_; } 48 49 private: 50 ~IOBufferWithSize() {} 51 52 int size_; 53 }; 54 55 // This is a read only IOBuffer. The data is stored in a string and 56 // the IOBuffer interface does not provide a proper way to modify it. 57 class StringIOBuffer : public IOBuffer { 58 public: 59 explicit StringIOBuffer(const std::string& s) 60 : IOBuffer(static_cast<char*>(NULL)), 61 string_data_(s) { 62 data_ = const_cast<char*>(string_data_.data()); 63 } 64 65 int size() const { return string_data_.size(); } 66 67 private: 68 ~StringIOBuffer() { 69 // We haven't allocated the buffer, so remove it before the base class 70 // destructor tries to delete[] it. 71 data_ = NULL; 72 } 73 74 std::string string_data_; 75 }; 76 77 // This version wraps an existing IOBuffer and provides convenient functions 78 // to progressively read all the data. 79 class DrainableIOBuffer : public IOBuffer { 80 public: 81 DrainableIOBuffer(IOBuffer* base, int size) 82 : IOBuffer(base->data()), base_(base), size_(size), used_(0) {} 83 84 // DidConsume() changes the |data_| pointer so that |data_| always points 85 // to the first unconsumed byte. 86 void DidConsume(int bytes) { SetOffset(used_ + bytes); } 87 88 // Returns the number of unconsumed bytes. 89 int BytesRemaining() const { return size_ - used_; } 90 91 // Returns the number of consumed bytes. 92 int BytesConsumed() const { return used_; } 93 94 // Seeks to an arbitrary point in the buffer. The notion of bytes consumed 95 // and remaining are updated appropriately. 96 void SetOffset(int bytes); 97 98 int size() const { return size_; } 99 100 private: 101 ~DrainableIOBuffer() { 102 // The buffer is owned by the |base_| instance. 103 data_ = NULL; 104 } 105 106 scoped_refptr<IOBuffer> base_; 107 int size_; 108 int used_; 109 }; 110 111 // This version provides a resizable buffer and a changeable offset. 112 class GrowableIOBuffer : public IOBuffer { 113 public: 114 GrowableIOBuffer() : IOBuffer(), capacity_(0), offset_(0) {} 115 116 // realloc memory to the specified capacity. 117 void SetCapacity(int capacity); 118 int capacity() { return capacity_; } 119 120 // |offset| moves the |data_| pointer, allowing "seeking" in the data. 121 void set_offset(int offset); 122 int offset() { return offset_; } 123 124 int RemainingCapacity() { return capacity_ - offset_; } 125 char* StartOfBuffer() { return real_data_.get(); } 126 127 private: 128 ~GrowableIOBuffer() { data_ = NULL; } 129 130 scoped_ptr_malloc<char> real_data_; 131 int capacity_; 132 int offset_; 133 }; 134 135 // This versions allows a pickle to be used as the storage for a write-style 136 // operation, avoiding an extra data copy. 137 class PickledIOBuffer : public IOBuffer { 138 public: 139 PickledIOBuffer() : IOBuffer() {} 140 141 Pickle* pickle() { return &pickle_; } 142 143 // Signals that we are done writing to the picke and we can use it for a 144 // write-style IO operation. 145 void Done() { 146 data_ = const_cast<char*>(static_cast<const char*>(pickle_.data())); 147 } 148 149 private: 150 ~PickledIOBuffer() { data_ = NULL; } 151 152 Pickle pickle_; 153 }; 154 155 // This class allows the creation of a temporary IOBuffer that doesn't really 156 // own the underlying buffer. Please use this class only as a last resort. 157 // A good example is the buffer for a synchronous operation, where we can be 158 // sure that nobody is keeping an extra reference to this object so the lifetime 159 // of the buffer can be completely managed by its intended owner. 160 class WrappedIOBuffer : public IOBuffer { 161 public: 162 explicit WrappedIOBuffer(const char* data) 163 : IOBuffer(const_cast<char*>(data)) {} 164 165 protected: 166 ~WrappedIOBuffer() { 167 data_ = NULL; 168 } 169 }; 170 171 } // namespace net 172 173 #endif // NET_BASE_IO_BUFFER_H_ 174