• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/base/io_buffer.h"
6 
7 #include "base/check_op.h"
8 #include "base/numerics/safe_math.h"
9 
10 namespace net {
11 
12 // TODO(eroman): IOBuffer is being converted to require buffer sizes and offsets
13 // be specified as "size_t" rather than "int" (crbug.com/488553). To facilitate
14 // this move (since LOTS of code needs to be updated), both "size_t" and "int
15 // are being accepted. When using "size_t" this function ensures that it can be
16 // safely converted to an "int" without truncation.
AssertValidBufferSize(size_t size)17 void IOBuffer::AssertValidBufferSize(size_t size) {
18   base::CheckedNumeric<int>(size).ValueOrDie();
19 }
20 
AssertValidBufferSize(int size)21 void IOBuffer::AssertValidBufferSize(int size) {
22   CHECK_GE(size, 0);
23 }
24 
IOBuffer()25 IOBuffer::IOBuffer() : data_(nullptr) {}
26 
IOBuffer(size_t buffer_size)27 IOBuffer::IOBuffer(size_t buffer_size) {
28   AssertValidBufferSize(buffer_size);
29   data_ = new char[buffer_size];
30 #if BUILDFLAG(IS_IOS)
31   // TODO(crbug.com/1335423): Investigating crashes on iOS.
32   CHECK(data_);
33 #endif  // BUILDFLAG(IS_IOS)
34 }
35 
IOBuffer(char * data)36 IOBuffer::IOBuffer(char* data)
37     : data_(data) {
38 }
39 
~IOBuffer()40 IOBuffer::~IOBuffer() {
41   data_.ClearAndDeleteArray();
42 }
43 
IOBufferWithSize(size_t size)44 IOBufferWithSize::IOBufferWithSize(size_t size) : IOBuffer(size), size_(size) {
45   // Note: Size check is done in superclass' constructor.
46 }
47 
IOBufferWithSize(char * data,size_t size)48 IOBufferWithSize::IOBufferWithSize(char* data, size_t size)
49     : IOBuffer(data), size_(size) {
50   AssertValidBufferSize(size);
51 }
52 
53 IOBufferWithSize::~IOBufferWithSize() = default;
54 
StringIOBuffer(const std::string & s)55 StringIOBuffer::StringIOBuffer(const std::string& s)
56     : IOBuffer(static_cast<char*>(nullptr)), string_data_(s) {
57   AssertValidBufferSize(s.size());
58   data_ = const_cast<char*>(string_data_.data());
59 }
60 
StringIOBuffer(std::unique_ptr<std::string> s)61 StringIOBuffer::StringIOBuffer(std::unique_ptr<std::string> s)
62     : IOBuffer(static_cast<char*>(nullptr)) {
63   AssertValidBufferSize(s->size());
64   string_data_.swap(*s.get());
65   data_ = const_cast<char*>(string_data_.data());
66 }
67 
~StringIOBuffer()68 StringIOBuffer::~StringIOBuffer() {
69   // We haven't allocated the buffer, so remove it before the base class
70   // destructor tries to delete[] it.
71   data_ = nullptr;
72 }
73 
DrainableIOBuffer(scoped_refptr<IOBuffer> base,int size)74 DrainableIOBuffer::DrainableIOBuffer(scoped_refptr<IOBuffer> base, int size)
75     : IOBuffer(base->data()), base_(std::move(base)), size_(size) {
76   AssertValidBufferSize(size);
77 }
78 
DrainableIOBuffer(scoped_refptr<IOBuffer> base,size_t size)79 DrainableIOBuffer::DrainableIOBuffer(scoped_refptr<IOBuffer> base, size_t size)
80     : IOBuffer(base->data()), base_(std::move(base)), size_(size) {
81   AssertValidBufferSize(size);
82 }
83 
DidConsume(int bytes)84 void DrainableIOBuffer::DidConsume(int bytes) {
85   SetOffset(used_ + bytes);
86 }
87 
BytesRemaining() const88 int DrainableIOBuffer::BytesRemaining() const {
89   return size_ - used_;
90 }
91 
92 // Returns the number of consumed bytes.
BytesConsumed() const93 int DrainableIOBuffer::BytesConsumed() const {
94   return used_;
95 }
96 
SetOffset(int bytes)97 void DrainableIOBuffer::SetOffset(int bytes) {
98   DCHECK_GE(bytes, 0);
99   DCHECK_LE(bytes, size_);
100   used_ = bytes;
101   data_ = base_->data() + used_;
102 }
103 
~DrainableIOBuffer()104 DrainableIOBuffer::~DrainableIOBuffer() {
105   // The buffer is owned by the |base_| instance.
106   data_ = nullptr;
107 }
108 
109 GrowableIOBuffer::GrowableIOBuffer() = default;
110 
SetCapacity(int capacity)111 void GrowableIOBuffer::SetCapacity(int capacity) {
112   DCHECK_GE(capacity, 0);
113   // this will get reset in `set_offset`.
114   data_ = nullptr;
115   // realloc will crash if it fails.
116   real_data_.reset(static_cast<char*>(realloc(real_data_.release(), capacity)));
117 
118   capacity_ = capacity;
119   if (offset_ > capacity)
120     set_offset(capacity);
121   else
122     set_offset(offset_);  // The pointer may have changed.
123 }
124 
set_offset(int offset)125 void GrowableIOBuffer::set_offset(int offset) {
126   DCHECK_GE(offset, 0);
127   DCHECK_LE(offset, capacity_);
128   offset_ = offset;
129   data_ = real_data_.get() + offset;
130 }
131 
RemainingCapacity()132 int GrowableIOBuffer::RemainingCapacity() {
133   return capacity_ - offset_;
134 }
135 
StartOfBuffer()136 char* GrowableIOBuffer::StartOfBuffer() {
137   return real_data_.get();
138 }
139 
~GrowableIOBuffer()140 GrowableIOBuffer::~GrowableIOBuffer() {
141   data_ = nullptr;
142 }
143 
PickledIOBuffer()144 PickledIOBuffer::PickledIOBuffer() : IOBuffer() {
145 }
146 
Done()147 void PickledIOBuffer::Done() {
148   data_ = const_cast<char*>(pickle_.data_as_char());
149 }
150 
~PickledIOBuffer()151 PickledIOBuffer::~PickledIOBuffer() {
152   data_ = nullptr;
153 }
154 
WrappedIOBuffer(const char * data)155 WrappedIOBuffer::WrappedIOBuffer(const char* data)
156     : IOBuffer(const_cast<char*>(data)) {
157 }
158 
~WrappedIOBuffer()159 WrappedIOBuffer::~WrappedIOBuffer() {
160   data_ = nullptr;
161 }
162 
163 }  // namespace net
164