147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_BUFFER_H_
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_BUFFER_H_
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string.h>
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/scoped_ptr.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Basic buffer class, can be grown and shrunk dynamically.
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Unlike std::string/vector, does not initialize data when expanding capacity.
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Buffer {
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer() {
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Construct(NULL, 0, 0);
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer(const void* data, size_t length) {
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Construct(data, length, length);
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer(const void* data, size_t length, size_t capacity) {
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Construct(data, length, capacity);
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer(const Buffer& buf) {
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Construct(buf.data(), buf.length(), buf.length());
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* data() const { return data_.get(); }
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char* data() { return data_.get(); }
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: should this be size(), like STL?
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t length() const { return length_; }
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t capacity() const { return capacity_; }
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer& operator=(const Buffer& buf) {
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (&buf != this) {
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      Construct(buf.data(), buf.length(), buf.length());
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return *this;
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool operator==(const Buffer& buf) const {
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (length_ == buf.length() &&
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            memcmp(data_.get(), buf.data(), length_) == 0);
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool operator!=(const Buffer& buf) const {
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return !operator==(buf);
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void SetData(const void* data, size_t length) {
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(data != NULL || length == 0);
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetLength(length);
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(data_.get(), data, length);
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void AppendData(const void* data, size_t length) {
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(data != NULL || length == 0);
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t old_length = length_;
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetLength(length_ + length);
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(data_.get() + old_length, data, length);
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void SetLength(size_t length) {
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetCapacity(length);
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    length_ = length;
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void SetCapacity(size_t capacity) {
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (capacity > capacity_) {
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      rtc::scoped_ptr<char[]> data(new char[capacity]);
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      memcpy(data.get(), data_.get(), length_);
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      data_.swap(data);
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      capacity_ = capacity;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void TransferTo(Buffer* buf) {
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(buf != NULL);
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buf->data_.reset(data_.release());
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buf->length_ = length_;
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buf->capacity_ = capacity_;
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Construct(NULL, 0, 0);
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected:
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Construct(const void* data, size_t length, size_t capacity) {
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_.reset(new char[capacity_ = capacity]);
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetData(data, length);
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<char[]> data_;
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t length_;
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t capacity_;
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_BASE_BUFFER_H_
103