1 // Copyright (c) 2012 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/quic/quic_data_writer.h" 6 7 #include <algorithm> 8 #include <limits> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/logging.h" 13 14 using base::StringPiece; 15 using std::numeric_limits; 16 17 namespace net { 18 19 QuicDataWriter::QuicDataWriter(size_t size) 20 : buffer_(new char[size]), 21 capacity_(size), 22 length_(0) { 23 } 24 25 QuicDataWriter::~QuicDataWriter() { 26 delete[] buffer_; 27 } 28 29 char* QuicDataWriter::take() { 30 char* rv = buffer_; 31 buffer_ = NULL; 32 capacity_ = 0; 33 length_ = 0; 34 return rv; 35 } 36 37 bool QuicDataWriter::WriteUInt8(uint8 value) { 38 return WriteBytes(&value, sizeof(value)); 39 } 40 41 bool QuicDataWriter::WriteUInt16(uint16 value) { 42 return WriteBytes(&value, sizeof(value)); 43 } 44 45 bool QuicDataWriter::WriteUInt32(uint32 value) { 46 return WriteBytes(&value, sizeof(value)); 47 } 48 49 bool QuicDataWriter::WriteUInt48(uint64 value) { 50 uint32 hi = value >> 32; 51 uint32 lo = value & GG_UINT64_C(0x00000000FFFFFFFF); 52 return WriteUInt32(lo) && WriteUInt16(hi); 53 } 54 55 bool QuicDataWriter::WriteUInt64(uint64 value) { 56 return WriteBytes(&value, sizeof(value)); 57 } 58 59 bool QuicDataWriter::WriteUInt128(uint128 value) { 60 return WriteUInt64(Uint128Low64(value)) && WriteUInt64(Uint128High64(value)); 61 } 62 63 bool QuicDataWriter::WriteStringPiece16(StringPiece val) { 64 if (val.length() > numeric_limits<uint16>::max()) { 65 return false; 66 } 67 if (!WriteUInt16(val.size())) { 68 return false; 69 } 70 return WriteBytes(val.data(), val.size()); 71 } 72 73 char* QuicDataWriter::BeginWrite(size_t length) { 74 if (length_ > capacity_) { 75 return NULL; 76 } 77 78 if (capacity_ - length_ < length) { 79 return NULL; 80 } 81 82 #ifdef ARCH_CPU_64_BITS 83 DCHECK_LE(length, numeric_limits<uint32>::max()); 84 #endif 85 86 return buffer_ + length_; 87 } 88 89 bool QuicDataWriter::WriteBytes(const void* data, size_t data_len) { 90 char* dest = BeginWrite(data_len); 91 if (!dest) { 92 return false; 93 } 94 95 memcpy(dest, data, data_len); 96 97 length_ += data_len; 98 return true; 99 } 100 101 bool QuicDataWriter::WriteRepeatedByte(uint8 byte, size_t count) { 102 char* dest = BeginWrite(count); 103 if (!dest) { 104 return false; 105 } 106 107 memset(dest, byte, count); 108 109 length_ += count; 110 return true; 111 } 112 113 void QuicDataWriter::WritePadding() { 114 DCHECK_LE(length_, capacity_); 115 if (length_ > capacity_) { 116 return; 117 } 118 memset(buffer_ + length_, 0x00, capacity_ - length_); 119 length_ = capacity_; 120 } 121 122 bool QuicDataWriter::WriteUInt8ToOffset(uint8 value, size_t offset) { 123 DCHECK_LT(offset, capacity_); 124 size_t latched_length = length_; 125 length_ = offset; 126 bool success = WriteUInt8(value); 127 DCHECK_LE(length_, latched_length); 128 length_ = latched_length; 129 return success; 130 } 131 132 bool QuicDataWriter::WriteUInt32ToOffset(uint32 value, size_t offset) { 133 DCHECK_LT(offset, capacity_); 134 size_t latched_length = length_; 135 length_ = offset; 136 bool success = WriteUInt32(value); 137 DCHECK_LE(length_, latched_length); 138 length_ = latched_length; 139 return success; 140 } 141 142 bool QuicDataWriter::WriteUInt48ToOffset(uint64 value, size_t offset) { 143 DCHECK_LT(offset, capacity_); 144 size_t latched_length = length_; 145 length_ = offset; 146 bool success = WriteUInt48(value); 147 DCHECK_LE(length_, latched_length); 148 length_ = latched_length; 149 return success; 150 } 151 152 } // namespace net 153