blob: 22054f3d88bd42e79f9ca99a85eb23204db7258a [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2011 The Chromium Authors
[email protected]319d9e6f2009-02-18 19:47:212// 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
Hans Wennborg0924470b2020-04-27 21:08:057#include "base/check_op.h"
eroman23ba60b2015-05-27 00:09:398#include "base/numerics/safe_math.h"
[email protected]319d9e6f2009-02-18 19:47:219
10namespace net {
11
eroman23ba60b2015-05-27 00:09:3912// 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.
Victor Vasiliev4d53d202019-12-27 18:47:3617void IOBuffer::AssertValidBufferSize(size_t size) {
eroman23ba60b2015-05-27 00:09:3918 base::CheckedNumeric<int>(size).ValueOrDie();
19}
20
Victor Vasiliev4d53d202019-12-27 18:47:3621void IOBuffer::AssertValidBufferSize(int size) {
eroman23ba60b2015-05-27 00:09:3922 CHECK_GE(size, 0);
23}
24
Raul Tambre94493c652019-03-11 17:18:3525IOBuffer::IOBuffer() : data_(nullptr) {}
[email protected]6d22a972010-07-21 15:47:1926
eroman23ba60b2015-05-27 00:09:3927IOBuffer::IOBuffer(size_t buffer_size) {
28 AssertValidBufferSize(buffer_size);
[email protected]319d9e6f2009-02-18 19:47:2129 data_ = new char[buffer_size];
Nidhi Jajua7a017b2022-10-21 02:43:1630#if BUILDFLAG(IS_IOS)
31 // TODO(crbug.com/1335423): Investigating crashes on iOS.
32 CHECK(data_);
33#endif // BUILDFLAG(IS_IOS)
[email protected]319d9e6f2009-02-18 19:47:2134}
[email protected]c19c7152009-10-14 17:35:3735
[email protected]6d22a972010-07-21 15:47:1936IOBuffer::IOBuffer(char* data)
37 : data_(data) {
38}
39
40IOBuffer::~IOBuffer() {
Arthur Sonzogni53809e572022-02-01 17:51:5441 data_.ClearAndDeleteArray();
[email protected]6d22a972010-07-21 15:47:1942}
43
eroman23ba60b2015-05-27 00:09:3944IOBufferWithSize::IOBufferWithSize(size_t size) : IOBuffer(size), size_(size) {
45 // Note: Size check is done in superclass' constructor.
[email protected]6d22a972010-07-21 15:47:1946}
47
eroman23ba60b2015-05-27 00:09:3948IOBufferWithSize::IOBufferWithSize(char* data, size_t size)
49 : IOBuffer(data), size_(size) {
50 AssertValidBufferSize(size);
[email protected]5ddffb82011-10-14 17:48:0751}
52
Chris Watkins68b15032017-12-01 03:07:1353IOBufferWithSize::~IOBufferWithSize() = default;
[email protected]7e4468d52010-09-22 19:42:0054
[email protected]6d22a972010-07-21 15:47:1955StringIOBuffer::StringIOBuffer(const std::string& s)
Raul Tambre94493c652019-03-11 17:18:3556 : IOBuffer(static_cast<char*>(nullptr)), string_data_(s) {
eroman23ba60b2015-05-27 00:09:3957 AssertValidBufferSize(s.size());
[email protected]6d22a972010-07-21 15:47:1958 data_ = const_cast<char*>(string_data_.data());
59}
60
danakj7f767e62016-04-16 23:20:2361StringIOBuffer::StringIOBuffer(std::unique_ptr<std::string> s)
Raul Tambre94493c652019-03-11 17:18:3562 : IOBuffer(static_cast<char*>(nullptr)) {
eroman23ba60b2015-05-27 00:09:3963 AssertValidBufferSize(s->size());
jkarlinb5ca81a32014-08-26 03:59:2964 string_data_.swap(*s.get());
65 data_ = const_cast<char*>(string_data_.data());
66}
67
[email protected]6d22a972010-07-21 15:47:1968StringIOBuffer::~StringIOBuffer() {
69 // We haven't allocated the buffer, so remove it before the base class
70 // destructor tries to delete[] it.
Raul Tambre94493c652019-03-11 17:18:3571 data_ = nullptr;
[email protected]6d22a972010-07-21 15:47:1972}
73
Victor Costancd439782018-08-30 07:27:5774DrainableIOBuffer::DrainableIOBuffer(scoped_refptr<IOBuffer> base, int size)
Tsuyoshi Horo432981d52022-06-09 09:50:1375 : IOBuffer(base->data()), base_(std::move(base)), size_(size) {
eroman23ba60b2015-05-27 00:09:3976 AssertValidBufferSize(size);
77}
78
Victor Costancd439782018-08-30 07:27:5779DrainableIOBuffer::DrainableIOBuffer(scoped_refptr<IOBuffer> base, size_t size)
Tsuyoshi Horo432981d52022-06-09 09:50:1380 : IOBuffer(base->data()), base_(std::move(base)), size_(size) {
eroman23ba60b2015-05-27 00:09:3981 AssertValidBufferSize(size);
[email protected]6d22a972010-07-21 15:47:1982}
83
[email protected]6d22a972010-07-21 15:47:1984void DrainableIOBuffer::DidConsume(int bytes) {
85 SetOffset(used_ + bytes);
86}
87
88int DrainableIOBuffer::BytesRemaining() const {
89 return size_ - used_;
90}
91
92// Returns the number of consumed bytes.
93int DrainableIOBuffer::BytesConsumed() const {
94 return used_;
95}
96
[email protected]c19c7152009-10-14 17:35:3797void DrainableIOBuffer::SetOffset(int bytes) {
[email protected]52af5d52011-05-05 09:59:2898 DCHECK_GE(bytes, 0);
99 DCHECK_LE(bytes, size_);
[email protected]c19c7152009-10-14 17:35:37100 used_ = bytes;
101 data_ = base_->data() + used_;
102}
103
[email protected]be1a48b2011-01-20 00:12:13104DrainableIOBuffer::~DrainableIOBuffer() {
105 // The buffer is owned by the |base_| instance.
Raul Tambre94493c652019-03-11 17:18:35106 data_ = nullptr;
[email protected]be1a48b2011-01-20 00:12:13107}
108
Tsuyoshi Horoe0235ed62022-06-09 01:42:30109GrowableIOBuffer::GrowableIOBuffer() = default;
[email protected]6d22a972010-07-21 15:47:19110
[email protected]776e1752009-11-10 18:51:34111void GrowableIOBuffer::SetCapacity(int capacity) {
[email protected]52af5d52011-05-05 09:59:28112 DCHECK_GE(capacity, 0);
Paul Semele8088bd2022-08-16 10:33:13113 // this will get reset in `set_offset`.
114 data_ = nullptr;
[email protected]776e1752009-11-10 18:51:34115 // realloc will crash if it fails.
116 real_data_.reset(static_cast<char*>(realloc(real_data_.release(), capacity)));
Paul Semele8088bd2022-08-16 10:33:13117
[email protected]c19c7152009-10-14 17:35:37118 capacity_ = capacity;
[email protected]c19c7152009-10-14 17:35:37119 if (offset_ > capacity)
120 set_offset(capacity);
121 else
122 set_offset(offset_); // The pointer may have changed.
123}
124
125void GrowableIOBuffer::set_offset(int offset) {
[email protected]52af5d52011-05-05 09:59:28126 DCHECK_GE(offset, 0);
127 DCHECK_LE(offset, capacity_);
[email protected]c19c7152009-10-14 17:35:37128 offset_ = offset;
129 data_ = real_data_.get() + offset;
[email protected]84d4cee2009-06-18 23:46:58130}
[email protected]319d9e6f2009-02-18 19:47:21131
[email protected]6d22a972010-07-21 15:47:19132int GrowableIOBuffer::RemainingCapacity() {
133 return capacity_ - offset_;
134}
135
136char* GrowableIOBuffer::StartOfBuffer() {
137 return real_data_.get();
138}
139
[email protected]be1a48b2011-01-20 00:12:13140GrowableIOBuffer::~GrowableIOBuffer() {
Raul Tambre94493c652019-03-11 17:18:35141 data_ = nullptr;
[email protected]be1a48b2011-01-20 00:12:13142}
[email protected]6d22a972010-07-21 15:47:19143
brettwbd4d7112015-06-03 04:29:25144PickledIOBuffer::PickledIOBuffer() : IOBuffer() {
145}
[email protected]6d22a972010-07-21 15:47:19146
147void PickledIOBuffer::Done() {
148 data_ = const_cast<char*>(static_cast<const char*>(pickle_.data()));
149}
150
brettwbd4d7112015-06-03 04:29:25151PickledIOBuffer::~PickledIOBuffer() {
Raul Tambre94493c652019-03-11 17:18:35152 data_ = nullptr;
brettwbd4d7112015-06-03 04:29:25153}
[email protected]6d22a972010-07-21 15:47:19154
155WrappedIOBuffer::WrappedIOBuffer(const char* data)
156 : IOBuffer(const_cast<char*>(data)) {
157}
158
159WrappedIOBuffer::~WrappedIOBuffer() {
Raul Tambre94493c652019-03-11 17:18:35160 data_ = nullptr;
[email protected]6d22a972010-07-21 15:47:19161}
162
[email protected]319d9e6f2009-02-18 19:47:21163} // namespace net