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