Split ByteBuffer into writer/reader objects.
This allows the reader to reference data, thus avoiding unnecessary
allocations and memory copies.
BUG=webrtc:5155,webrtc:5670
Review URL: https://codereview.webrtc.org/1821083002
Cr-Commit-Position: refs/heads/master@{#12160}
diff --git a/webrtc/base/bytebuffer.cc b/webrtc/base/bytebuffer.cc
index 8bc1f23..cf4ce42 100644
--- a/webrtc/base/bytebuffer.cc
+++ b/webrtc/base/bytebuffer.cc
@@ -22,36 +22,30 @@
static const int DEFAULT_SIZE = 4096;
-ByteBuffer::ByteBuffer() {
- Construct(NULL, DEFAULT_SIZE, ORDER_NETWORK);
+ByteBufferWriter::ByteBufferWriter()
+ : ByteBuffer(ORDER_NETWORK) {
+ Construct(NULL, DEFAULT_SIZE);
}
-ByteBuffer::ByteBuffer(ByteOrder byte_order) {
- Construct(NULL, DEFAULT_SIZE, byte_order);
+ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
+ : ByteBuffer(byte_order) {
+ Construct(NULL, DEFAULT_SIZE);
}
-ByteBuffer::ByteBuffer(const char* bytes, size_t len) {
- Construct(bytes, len, ORDER_NETWORK);
+ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
+ : ByteBuffer(ORDER_NETWORK) {
+ Construct(bytes, len);
}
-ByteBuffer::ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order) {
- Construct(bytes, len, byte_order);
+ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len,
+ ByteOrder byte_order)
+ : ByteBuffer(byte_order) {
+ Construct(bytes, len);
}
-ByteBuffer::ByteBuffer(const char* bytes) {
- Construct(bytes, strlen(bytes), ORDER_NETWORK);
-}
-
-ByteBuffer::ByteBuffer(const Buffer& buf) {
- Construct(buf.data<char>(), buf.size(), ORDER_NETWORK);
-}
-
-void ByteBuffer::Construct(const char* bytes, size_t len,
- ByteOrder byte_order) {
- version_ = 0;
+void ByteBufferWriter::Construct(const char* bytes, size_t len) {
start_ = 0;
size_ = len;
- byte_order_ = byte_order;
bytes_ = new char[size_];
if (bytes) {
@@ -62,128 +56,47 @@
}
}
-ByteBuffer::~ByteBuffer() {
+ByteBufferWriter::~ByteBufferWriter() {
delete[] bytes_;
}
-bool ByteBuffer::ReadUInt8(uint8_t* val) {
- if (!val) return false;
-
- return ReadBytes(reinterpret_cast<char*>(val), 1);
-}
-
-bool ByteBuffer::ReadUInt16(uint16_t* val) {
- if (!val) return false;
-
- uint16_t v;
- if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
- return false;
- } else {
- *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost16(v) : v;
- return true;
- }
-}
-
-bool ByteBuffer::ReadUInt24(uint32_t* val) {
- if (!val) return false;
-
- uint32_t v = 0;
- char* read_into = reinterpret_cast<char*>(&v);
- if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
- ++read_into;
- }
-
- if (!ReadBytes(read_into, 3)) {
- return false;
- } else {
- *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
- return true;
- }
-}
-
-bool ByteBuffer::ReadUInt32(uint32_t* val) {
- if (!val) return false;
-
- uint32_t v;
- if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
- return false;
- } else {
- *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
- return true;
- }
-}
-
-bool ByteBuffer::ReadUInt64(uint64_t* val) {
- if (!val) return false;
-
- uint64_t v;
- if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
- return false;
- } else {
- *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost64(v) : v;
- return true;
- }
-}
-
-bool ByteBuffer::ReadString(std::string* val, size_t len) {
- if (!val) return false;
-
- if (len > Length()) {
- return false;
- } else {
- val->append(bytes_ + start_, len);
- start_ += len;
- return true;
- }
-}
-
-bool ByteBuffer::ReadBytes(char* val, size_t len) {
- if (len > Length()) {
- return false;
- } else {
- memcpy(val, bytes_ + start_, len);
- start_ += len;
- return true;
- }
-}
-
-void ByteBuffer::WriteUInt8(uint8_t val) {
+void ByteBufferWriter::WriteUInt8(uint8_t val) {
WriteBytes(reinterpret_cast<const char*>(&val), 1);
}
-void ByteBuffer::WriteUInt16(uint16_t val) {
- uint16_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork16(val) : val;
+void ByteBufferWriter::WriteUInt16(uint16_t val) {
+ uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
WriteBytes(reinterpret_cast<const char*>(&v), 2);
}
-void ByteBuffer::WriteUInt24(uint32_t val) {
- uint32_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
+void ByteBufferWriter::WriteUInt24(uint32_t val) {
+ uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
char* start = reinterpret_cast<char*>(&v);
- if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
+ if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
++start;
}
WriteBytes(start, 3);
}
-void ByteBuffer::WriteUInt32(uint32_t val) {
- uint32_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
+void ByteBufferWriter::WriteUInt32(uint32_t val) {
+ uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
WriteBytes(reinterpret_cast<const char*>(&v), 4);
}
-void ByteBuffer::WriteUInt64(uint64_t val) {
- uint64_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork64(val) : val;
+void ByteBufferWriter::WriteUInt64(uint64_t val) {
+ uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
WriteBytes(reinterpret_cast<const char*>(&v), 8);
}
-void ByteBuffer::WriteString(const std::string& val) {
+void ByteBufferWriter::WriteString(const std::string& val) {
WriteBytes(val.c_str(), val.size());
}
-void ByteBuffer::WriteBytes(const char* val, size_t len) {
+void ByteBufferWriter::WriteBytes(const char* val, size_t len) {
memcpy(ReserveWriteBuffer(len), val, len);
}
-char* ByteBuffer::ReserveWriteBuffer(size_t len) {
+char* ByteBufferWriter::ReserveWriteBuffer(size_t len) {
if (Length() + len > Capacity())
Resize(Length() + len);
@@ -192,7 +105,7 @@
return start;
}
-void ByteBuffer::Resize(size_t size) {
+void ByteBufferWriter::Resize(size_t size) {
size_t len = std::min(end_ - start_, size);
if (size <= size_) {
// Don't reallocate, just move data backwards
@@ -207,32 +120,133 @@
}
start_ = 0;
end_ = len;
- ++version_;
}
-bool ByteBuffer::Consume(size_t size) {
+void ByteBufferWriter::Clear() {
+ memset(bytes_, 0, size_);
+ start_ = end_ = 0;
+}
+
+
+ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
+ : ByteBuffer(ORDER_NETWORK) {
+ Construct(bytes, len);
+}
+
+ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
+ ByteOrder byte_order)
+ : ByteBuffer(byte_order) {
+ Construct(bytes, len);
+}
+
+ByteBufferReader::ByteBufferReader(const char* bytes)
+ : ByteBuffer(ORDER_NETWORK) {
+ Construct(bytes, strlen(bytes));
+}
+
+ByteBufferReader::ByteBufferReader(const Buffer& buf)
+ : ByteBuffer(ORDER_NETWORK) {
+ Construct(buf.data<char>(), buf.size());
+}
+
+ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
+ : ByteBuffer(buf.Order()) {
+ Construct(buf.Data(), buf.Length());
+}
+
+void ByteBufferReader::Construct(const char* bytes, size_t len) {
+ bytes_ = bytes;
+ size_ = len;
+ start_ = 0;
+ end_ = len;
+}
+
+bool ByteBufferReader::ReadUInt8(uint8_t* val) {
+ if (!val) return false;
+
+ return ReadBytes(reinterpret_cast<char*>(val), 1);
+}
+
+bool ByteBufferReader::ReadUInt16(uint16_t* val) {
+ if (!val) return false;
+
+ uint16_t v;
+ if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
+ return false;
+ } else {
+ *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
+ return true;
+ }
+}
+
+bool ByteBufferReader::ReadUInt24(uint32_t* val) {
+ if (!val) return false;
+
+ uint32_t v = 0;
+ char* read_into = reinterpret_cast<char*>(&v);
+ if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
+ ++read_into;
+ }
+
+ if (!ReadBytes(read_into, 3)) {
+ return false;
+ } else {
+ *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
+ return true;
+ }
+}
+
+bool ByteBufferReader::ReadUInt32(uint32_t* val) {
+ if (!val) return false;
+
+ uint32_t v;
+ if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
+ return false;
+ } else {
+ *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
+ return true;
+ }
+}
+
+bool ByteBufferReader::ReadUInt64(uint64_t* val) {
+ if (!val) return false;
+
+ uint64_t v;
+ if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
+ return false;
+ } else {
+ *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
+ return true;
+ }
+}
+
+bool ByteBufferReader::ReadString(std::string* val, size_t len) {
+ if (!val) return false;
+
+ if (len > Length()) {
+ return false;
+ } else {
+ val->append(bytes_ + start_, len);
+ start_ += len;
+ return true;
+ }
+}
+
+bool ByteBufferReader::ReadBytes(char* val, size_t len) {
+ if (len > Length()) {
+ return false;
+ } else {
+ memcpy(val, bytes_ + start_, len);
+ start_ += len;
+ return true;
+ }
+}
+
+bool ByteBufferReader::Consume(size_t size) {
if (size > Length())
return false;
start_ += size;
return true;
}
-ByteBuffer::ReadPosition ByteBuffer::GetReadPosition() const {
- return ReadPosition(start_, version_);
-}
-
-bool ByteBuffer::SetReadPosition(const ReadPosition &position) {
- if (position.version_ != version_) {
- return false;
- }
- start_ = position.start_;
- return true;
-}
-
-void ByteBuffer::Clear() {
- memset(bytes_, 0, size_);
- start_ = end_ = 0;
- ++version_;
-}
-
} // namespace rtc