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#include "net/base/io_buffer.h"
6
7#include "base/logging.h"
8
9namespace net {
10
11IOBuffer::IOBuffer()
12    : data_(NULL) {
13}
14
15IOBuffer::IOBuffer(int buffer_size) {
16  CHECK_GE(buffer_size, 0);
17  data_ = new char[buffer_size];
18}
19
20IOBuffer::IOBuffer(char* data)
21    : data_(data) {
22}
23
24IOBuffer::~IOBuffer() {
25  delete[] data_;
26  data_ = NULL;
27}
28
29IOBufferWithSize::IOBufferWithSize(int size)
30    : IOBuffer(size),
31      size_(size) {
32}
33
34IOBufferWithSize::IOBufferWithSize(char* data, int size)
35    : IOBuffer(data),
36      size_(size) {
37}
38
39IOBufferWithSize::~IOBufferWithSize() {
40}
41
42StringIOBuffer::StringIOBuffer(const std::string& s)
43    : IOBuffer(static_cast<char*>(NULL)),
44      string_data_(s) {
45  CHECK_LT(s.size(), static_cast<size_t>(INT_MAX));
46  data_ = const_cast<char*>(string_data_.data());
47}
48
49StringIOBuffer::StringIOBuffer(scoped_ptr<std::string> s)
50    : IOBuffer(static_cast<char*>(NULL)) {
51  CHECK_LT(s->size(), static_cast<size_t>(INT_MAX));
52  string_data_.swap(*s.get());
53  data_ = const_cast<char*>(string_data_.data());
54}
55
56StringIOBuffer::~StringIOBuffer() {
57  // We haven't allocated the buffer, so remove it before the base class
58  // destructor tries to delete[] it.
59  data_ = NULL;
60}
61
62DrainableIOBuffer::DrainableIOBuffer(IOBuffer* base, int size)
63    : IOBuffer(base->data()),
64      base_(base),
65      size_(size),
66      used_(0) {
67}
68
69void DrainableIOBuffer::DidConsume(int bytes) {
70  SetOffset(used_ + bytes);
71}
72
73int DrainableIOBuffer::BytesRemaining() const {
74  return size_ - used_;
75}
76
77// Returns the number of consumed bytes.
78int DrainableIOBuffer::BytesConsumed() const {
79  return used_;
80}
81
82void DrainableIOBuffer::SetOffset(int bytes) {
83  DCHECK_GE(bytes, 0);
84  DCHECK_LE(bytes, size_);
85  used_ = bytes;
86  data_ = base_->data() + used_;
87}
88
89DrainableIOBuffer::~DrainableIOBuffer() {
90  // The buffer is owned by the |base_| instance.
91  data_ = NULL;
92}
93
94GrowableIOBuffer::GrowableIOBuffer()
95    : IOBuffer(),
96      capacity_(0),
97      offset_(0) {
98}
99
100void GrowableIOBuffer::SetCapacity(int capacity) {
101  DCHECK_GE(capacity, 0);
102  // realloc will crash if it fails.
103  real_data_.reset(static_cast<char*>(realloc(real_data_.release(), capacity)));
104  capacity_ = capacity;
105  if (offset_ > capacity)
106    set_offset(capacity);
107  else
108    set_offset(offset_);  // The pointer may have changed.
109}
110
111void GrowableIOBuffer::set_offset(int offset) {
112  DCHECK_GE(offset, 0);
113  DCHECK_LE(offset, capacity_);
114  offset_ = offset;
115  data_ = real_data_.get() + offset;
116}
117
118int GrowableIOBuffer::RemainingCapacity() {
119  return capacity_ - offset_;
120}
121
122char* GrowableIOBuffer::StartOfBuffer() {
123  return real_data_.get();
124}
125
126GrowableIOBuffer::~GrowableIOBuffer() {
127  data_ = NULL;
128}
129
130PickledIOBuffer::PickledIOBuffer() : IOBuffer() {}
131
132void PickledIOBuffer::Done() {
133  data_ = const_cast<char*>(static_cast<const char*>(pickle_.data()));
134}
135
136PickledIOBuffer::~PickledIOBuffer() { data_ = NULL; }
137
138WrappedIOBuffer::WrappedIOBuffer(const char* data)
139    : IOBuffer(const_cast<char*>(data)) {
140}
141
142WrappedIOBuffer::~WrappedIOBuffer() {
143  data_ = NULL;
144}
145
146}  // namespace net
147