1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_BUFFER_H_
12#define WEBRTC_BASE_BUFFER_H_
13
14#include <string.h>
15
16#include "webrtc/base/scoped_ptr.h"
17
18namespace rtc {
19
20// Basic buffer class, can be grown and shrunk dynamically.
21// Unlike std::string/vector, does not initialize data when expanding capacity.
22class Buffer {
23 public:
24  Buffer() {
25    Construct(NULL, 0, 0);
26  }
27  Buffer(const void* data, size_t length) {
28    Construct(data, length, length);
29  }
30  Buffer(const void* data, size_t length, size_t capacity) {
31    Construct(data, length, capacity);
32  }
33  Buffer(const Buffer& buf) {
34    Construct(buf.data(), buf.length(), buf.length());
35  }
36
37  const char* data() const { return data_.get(); }
38  char* data() { return data_.get(); }
39  // TODO: should this be size(), like STL?
40  size_t length() const { return length_; }
41  size_t capacity() const { return capacity_; }
42
43  Buffer& operator=(const Buffer& buf) {
44    if (&buf != this) {
45      Construct(buf.data(), buf.length(), buf.length());
46    }
47    return *this;
48  }
49  bool operator==(const Buffer& buf) const {
50    return (length_ == buf.length() &&
51            memcmp(data_.get(), buf.data(), length_) == 0);
52  }
53  bool operator!=(const Buffer& buf) const {
54    return !operator==(buf);
55  }
56
57  void SetData(const void* data, size_t length) {
58    ASSERT(data != NULL || length == 0);
59    SetLength(length);
60    memcpy(data_.get(), data, length);
61  }
62  void AppendData(const void* data, size_t length) {
63    ASSERT(data != NULL || length == 0);
64    size_t old_length = length_;
65    SetLength(length_ + length);
66    memcpy(data_.get() + old_length, data, length);
67  }
68  void SetLength(size_t length) {
69    SetCapacity(length);
70    length_ = length;
71  }
72  void SetCapacity(size_t capacity) {
73    if (capacity > capacity_) {
74      rtc::scoped_ptr<char[]> data(new char[capacity]);
75      memcpy(data.get(), data_.get(), length_);
76      data_.swap(data);
77      capacity_ = capacity;
78    }
79  }
80
81  void TransferTo(Buffer* buf) {
82    ASSERT(buf != NULL);
83    buf->data_.reset(data_.release());
84    buf->length_ = length_;
85    buf->capacity_ = capacity_;
86    Construct(NULL, 0, 0);
87  }
88
89 protected:
90  void Construct(const void* data, size_t length, size_t capacity) {
91    data_.reset(new char[capacity_ = capacity]);
92    SetData(data, length);
93  }
94
95  scoped_ptr<char[]> data_;
96  size_t length_;
97  size_t capacity_;
98};
99
100}  // namespace rtc
101
102#endif  // WEBRTC_BASE_BUFFER_H_
103