Home | History | Annotate | Download | only in quic
      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