1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * libjingle 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Copyright 2004-2010, Google Inc. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Redistribution and use in source and binary forms, with or without 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * modification, are permitted provided that the following conditions are met: 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 1. Redistributions of source code must retain the above copyright notice, 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * this list of conditions and the following disclaimer. 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 2. Redistributions in binary form must reproduce the above copyright notice, 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * this list of conditions and the following disclaimer in the documentation 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * and/or other materials provided with the distribution. 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 3. The name of the author may not be used to endorse or promote products 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * derived from this software without specific prior written permission. 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef TALK_BASE_BUFFER_H_ 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define TALK_BASE_BUFFER_H_ 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <cstring> 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "talk/base/scoped_ptr.h" 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace talk_base { 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Basic buffer class, can be grown and shrunk dynamically. 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Unlike std::string/vector, does not initialize data when expanding capacity. 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Buffer { 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Buffer() { 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(NULL, 0, 0); 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Buffer(const void* data, size_t length) { 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(data, length, length); 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Buffer(const void* data, size_t length, size_t capacity) { 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(data, length, capacity); 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Buffer(const Buffer& buf) { 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(buf.data(), buf.length(), buf.length()); 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* data() const { return data_.get(); } 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen char* data() { return data_.get(); } 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO: should this be size(), like STL? 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t length() const { return length_; } 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t capacity() const { return capacity_; } 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Buffer& operator=(const Buffer& buf) { 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (&buf != this) { 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(buf.data(), buf.length(), buf.length()); 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return *this; 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool operator==(const Buffer& buf) const { 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (length_ == buf.length() && 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen memcmp(data_.get(), buf.data(), length_) == 0); 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool operator!=(const Buffer& buf) const { 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return !operator==(buf); 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void SetData(const void* data, size_t length) { 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT(data != NULL || length == 0); 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetLength(length); 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen memcpy(data_.get(), data, length); 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void AppendData(const void* data, size_t length) { 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT(data != NULL || length == 0); 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t old_length = length_; 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetLength(length_ + length); 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen memcpy(data_.get() + old_length, data, length); 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void SetLength(size_t length) { 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetCapacity(length); 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen length_ = length; 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void SetCapacity(size_t capacity) { 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (capacity > capacity_) { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen talk_base::scoped_array<char> data(new char[capacity]); 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen memcpy(data.get(), data_.get(), length_); 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen data_.swap(data); 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen capacity_ = capacity; 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void TransferTo(Buffer* buf) { 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT(buf != NULL); 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen buf->data_.reset(data_.release()); 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen buf->length_ = length_; 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen buf->capacity_ = capacity_; 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Construct(NULL, 0, 0); 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected: 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void Construct(const void* data, size_t length, size_t capacity) { 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen data_.reset(new char[capacity_ = capacity]); 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetData(data, length); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_array<char> data_; 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t length_; 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t capacity_; 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace talk_base 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // TALK_BASE_BUFFER_H_ 120