OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/balsa/simple_buffer.h" | 5 #include "net/tools/balsa/simple_buffer.h" |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 | 7 |
8 // Some of the following member functions are marked inlined, even though they | 8 // Some of the following member functions are marked inlined, even though they |
9 // are virtual. This may seem counter-intuitive, since virtual functions are | 9 // are virtual. This may seem counter-intuitive, since virtual functions are |
10 // generally not eligible for inlining. Profiling results indicate that these | 10 // generally not eligible for inlining. Profiling results indicate that these |
11 // large amount of runtime is spent on virtual function dispatch on these | 11 // large amount of runtime is spent on virtual function dispatch on these |
12 // simple functions. They are virtual because of the interface this class | 12 // simple functions. They are virtual because of the interface this class |
13 // inherits from. However, it is very unlikely that anyone will sub-class | 13 // inherits from. However, it is very unlikely that anyone will sub-class |
14 // SimpleBuffer and change their implementation. To get rid of this baggage, | 14 // SimpleBuffer and change their implementation. To get rid of this baggage, |
15 // internal implementation (e.g., Write) explicitly use SimpleBuffer:: to | 15 // internal implementation (e.g., Write) explicitly use SimpleBuffer:: to |
16 // qualify the method calls, thus disabling the virtual dispatch and enable | 16 // qualify the method calls, thus disabling the virtual dispatch and enable |
17 // inlining. | 17 // inlining. |
18 | 18 |
19 namespace net { | 19 namespace net { |
20 | 20 |
21 static const int kInitialSimpleBufferSize = 10; | 21 static const int kInitialSimpleBufferSize = 10; |
22 | 22 |
23 SimpleBuffer::SimpleBuffer() | 23 SimpleBuffer::SimpleBuffer() |
24 : storage_(new char[kInitialSimpleBufferSize]), | 24 : storage_(new char[kInitialSimpleBufferSize]), |
25 write_idx_(0), | 25 write_idx_(0), |
26 read_idx_(0), | 26 read_idx_(0), |
27 storage_size_(kInitialSimpleBufferSize) { | 27 storage_size_(kInitialSimpleBufferSize) { |
28 } | 28 } |
29 | 29 |
30 SimpleBuffer::SimpleBuffer(int size) | 30 SimpleBuffer::SimpleBuffer(int size) |
31 : write_idx_(0), | 31 : write_idx_(0), read_idx_(0), storage_size_(size) { |
32 read_idx_(0), | |
33 storage_size_(size) { | |
34 // Callers may try to allocate overly large blocks, but negative sizes are | 32 // Callers may try to allocate overly large blocks, but negative sizes are |
35 // obviously wrong. | 33 // obviously wrong. |
36 CHECK_GE(size, 0); | 34 CHECK_GE(size, 0); |
37 storage_ = new char[size]; | 35 storage_ = new char[size]; |
38 } | 36 } |
39 | 37 |
40 SimpleBuffer::~SimpleBuffer() { | 38 SimpleBuffer::~SimpleBuffer() { |
41 delete[] storage_; | 39 delete[] storage_; |
42 } | 40 } |
43 | 41 |
44 | |
45 //////////////////////////////////////////////////////////////////////////////// | 42 //////////////////////////////////////////////////////////////////////////////// |
46 | 43 |
47 int SimpleBuffer::ReadableBytes() const { | 44 int SimpleBuffer::ReadableBytes() const { |
48 return write_idx_ - read_idx_; | 45 return write_idx_ - read_idx_; |
49 } | 46 } |
50 | 47 |
51 //////////////////////////////////////////////////////////////////////////////// | 48 //////////////////////////////////////////////////////////////////////////////// |
52 | 49 |
53 std::string SimpleBuffer::str() const { | 50 std::string SimpleBuffer::str() const { |
54 std::string s; | 51 std::string s; |
55 char * readable_ptr; | 52 char* readable_ptr; |
56 int readable_size; | 53 int readable_size; |
57 GetReadablePtr(&readable_ptr, &readable_size); | 54 GetReadablePtr(&readable_ptr, &readable_size); |
58 s.append(readable_ptr, readable_ptr + readable_size); | 55 s.append(readable_ptr, readable_ptr + readable_size); |
59 return s; | 56 return s; |
60 } | 57 } |
61 | 58 |
62 //////////////////////////////////////////////////////////////////////////////// | 59 //////////////////////////////////////////////////////////////////////////////// |
63 | 60 |
64 int SimpleBuffer::BufferSize() const { | 61 int SimpleBuffer::BufferSize() const { |
65 return storage_size_; | 62 return storage_size_; |
(...skipping 29 matching lines...) Expand all Loading... |
95 memcpy(storage_ + write_idx_, bytes, size); | 92 memcpy(storage_ + write_idx_, bytes, size); |
96 SimpleBuffer::AdvanceWritablePtr(size); | 93 SimpleBuffer::AdvanceWritablePtr(size); |
97 return size; | 94 return size; |
98 } | 95 } |
99 | 96 |
100 //////////////////////////////////////////////////////////////////////////////// | 97 //////////////////////////////////////////////////////////////////////////////// |
101 | 98 |
102 // stores a pointer into the simple buffer in *ptr, | 99 // stores a pointer into the simple buffer in *ptr, |
103 // and stores the number of characters which are allowed | 100 // and stores the number of characters which are allowed |
104 // to be written in *size. | 101 // to be written in *size. |
105 inline void SimpleBuffer::GetWritablePtr(char **ptr, int* size) const { | 102 inline void SimpleBuffer::GetWritablePtr(char** ptr, int* size) const { |
106 *ptr = storage_ + write_idx_; | 103 *ptr = storage_ + write_idx_; |
107 *size = SimpleBuffer::BytesFree(); | 104 *size = SimpleBuffer::BytesFree(); |
108 } | 105 } |
109 | 106 |
110 //////////////////////////////////////////////////////////////////////////////// | 107 //////////////////////////////////////////////////////////////////////////////// |
111 | 108 |
112 // stores a pointer into the simple buffer in *ptr, | 109 // stores a pointer into the simple buffer in *ptr, |
113 // and stores the number of characters which are allowed | 110 // and stores the number of characters which are allowed |
114 // to be read in *size. | 111 // to be read in *size. |
115 void SimpleBuffer::GetReadablePtr(char **ptr, int* size) const { | 112 void SimpleBuffer::GetReadablePtr(char** ptr, int* size) const { |
116 *ptr = storage_ + read_idx_; | 113 *ptr = storage_ + read_idx_; |
117 *size = write_idx_ - read_idx_; | 114 *size = write_idx_ - read_idx_; |
118 } | 115 } |
119 | 116 |
120 //////////////////////////////////////////////////////////////////////////////// | 117 //////////////////////////////////////////////////////////////////////////////// |
121 | 118 |
122 // returns the number of bytes read into 'bytes' | 119 // returns the number of bytes read into 'bytes' |
123 int SimpleBuffer::Read(char* bytes, int size) { | 120 int SimpleBuffer::Read(char* bytes, int size) { |
124 char * read_ptr = NULL; | 121 char* read_ptr = NULL; |
125 int read_size = 0; | 122 int read_size = 0; |
126 GetReadablePtr(&read_ptr, &read_size); | 123 GetReadablePtr(&read_ptr, &read_size); |
127 if (read_size > size) { | 124 if (read_size > size) { |
128 read_size = size; | 125 read_size = size; |
129 } | 126 } |
130 memcpy(bytes, read_ptr, read_size); | 127 memcpy(bytes, read_ptr, read_size); |
131 AdvanceReadablePtr(read_size); | 128 AdvanceReadablePtr(read_size); |
132 return read_size; | 129 return read_size; |
133 } | 130 } |
134 | 131 |
135 //////////////////////////////////////////////////////////////////////////////// | 132 //////////////////////////////////////////////////////////////////////////////// |
136 | 133 |
137 // removes all data from the simple buffer | 134 // removes all data from the simple buffer |
138 void SimpleBuffer::Clear() { | 135 void SimpleBuffer::Clear() { |
139 read_idx_ = write_idx_ = 0; | 136 read_idx_ = write_idx_ = 0; |
140 } | 137 } |
141 | 138 |
142 //////////////////////////////////////////////////////////////////////////////// | 139 //////////////////////////////////////////////////////////////////////////////// |
143 | 140 |
144 // Attempts to reserve a contiguous block of buffer space by either reclaiming | 141 // Attempts to reserve a contiguous block of buffer space by either reclaiming |
145 // old data that is already read, and reallocate large storage as needed. | 142 // old data that is already read, and reallocate large storage as needed. |
146 bool SimpleBuffer::Reserve(int size) { | 143 bool SimpleBuffer::Reserve(int size) { |
147 if (size > 0 && BytesFree() < size) { | 144 if (size > 0 && BytesFree() < size) { |
148 char * read_ptr = NULL; | 145 char* read_ptr = NULL; |
149 int read_size = 0; | 146 int read_size = 0; |
150 GetReadablePtr(&read_ptr, &read_size); | 147 GetReadablePtr(&read_ptr, &read_size); |
151 | 148 |
152 if (read_size + size <= BufferSize()) { | 149 if (read_size + size <= BufferSize()) { |
153 // Can reclaim space from already read bytes by shifting | 150 // Can reclaim space from already read bytes by shifting |
154 memmove(storage_, read_ptr, read_size); | 151 memmove(storage_, read_ptr, read_size); |
155 read_idx_ = 0; | 152 read_idx_ = 0; |
156 write_idx_ = read_size; | 153 write_idx_ = read_size; |
157 CHECK_GE(BytesFree(), size); | 154 CHECK_GE(BytesFree(), size); |
158 } else { | 155 } else { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 // amount of data specified here is expected to | 196 // amount of data specified here is expected to |
200 // already be resident (as if it was Written) | 197 // already be resident (as if it was Written) |
201 inline void SimpleBuffer::AdvanceWritablePtr(int amount_to_advance) { | 198 inline void SimpleBuffer::AdvanceWritablePtr(int amount_to_advance) { |
202 write_idx_ += amount_to_advance; | 199 write_idx_ += amount_to_advance; |
203 if (write_idx_ > storage_size_) { | 200 if (write_idx_ > storage_size_) { |
204 write_idx_ = storage_size_; | 201 write_idx_ = storage_size_; |
205 } | 202 } |
206 } | 203 } |
207 | 204 |
208 } // namespace net | 205 } // namespace net |
OLD | NEW |