Home | History | Annotate | Download | only in base
      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