Coverage for /Syzygy/common/buffer_writer.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%990.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Utility class for constructing a buffer of binary data. There are two
  16    :  // implementations provided:
  17    :  //
  18    :  // 1. BufferWriter: for writing to fixed-size preallocated buffers; and,
  19    :  // 2. VectorBufferWriter: for writing to growable std::vector<uint8>-backed
  20    :  //                        buffers.
  21    :  //
  22    :  // Intended usage:
  23    :  //
  24    :  //   uint8 buffer[1024];
  25    :  //   FixedBufferWriter writer(buffer, sizeof(buffer));
  26    :  //   writer.WriteString(some_string);
  27    :  //   writer.AlignUp(sizeof(uint32));
  28    :  //   writer.Write(number_of_elements, array_of_uint32s);
  29    :  //   writer.Write(some_complex_object);
  30    :  
  31    :  #ifndef SYZYGY_COMMON_BUFFER_WRITER_H_
  32    :  #define SYZYGY_COMMON_BUFFER_WRITER_H_
  33    :  
  34    :  #include <vector>
  35    :  
  36    :  #include "base/strings/string_piece.h"
  37    :  
  38    :  namespace common {
  39    :  
  40    :  // A helper class for creating buffers of binary data. This allows writing of
  41    :  // arbitrary binary objects with helpers for controlling alignment, etc. This is
  42    :  // a pure virtual base class, allowing this class to easily be extended for
  43    :  // targeting other growable buffer types. Derived classes need only provide a
  44    :  // constructor and implement the GrowBuffer function.
  45    :  class BufferWriter {
  46    :   public:
  47    :    // Constructor.
  48    :    // @param buffer the initial destination buffer.
  49    :    // @param buffer_length the initial length of the buffer, in bytes.
  50    :    BufferWriter(void* buffer, size_t buffer_length);
  51    :  
  52    :    // @{
  53    :    // Simple accessors and mutators.
  54  E :    size_t pos() const { return pos_; }
  55  E :    void set_pos(size_t pos) { pos_ = pos; }
  56  E :    size_t length() const { return buffer_length_; }
  57    :    // @}
  58    :  
  59    :    // Returns the remaining bytes in the buffer. If we're using an expandable
  60    :    // vector and this returns zero, the next write will cause the vector to
  61    :    // grow.
  62    :    // @returns the number of allocated bytes remaining.
  63    :    size_t RemainingBytes() const;
  64    :  
  65    :    // Advance the write position by @p bytes. This skips over the existing data.
  66    :    // @param bytes the number of bytes to skip.
  67    :    // @returns true if there was sufficient room for the seek, false otherwise.
  68    :    bool Consume(size_t bytes);
  69    :  
  70    :    // Advances the output position to the next multiple of @p bytes.
  71    :    // @param bytes the alignment, which must be a power of two.
  72    :    // @returns true if there was sufficient room for the align, false otherwise.
  73    :    bool Align(size_t bytes);
  74    :  
  75    :    // Determines if the current output position is aligned.
  76    :    // @param bytes the alignment to confirm, which must be a multiple of two.
  77    :    // @returns true if aligned, false otherwise.
  78    :    bool IsAligned(size_t bytes) const;
  79    :  
  80    :    // Writes the given data to the buffer, advancing the write pointer.
  81    :    // @param data_len the data length in bytes.
  82    :    // @param data the buffer of data to write.
  83    :    // @returns true if there was sufficient room for the write, false otherwise.
  84    :    bool Write(size_t data_len, const void* data);
  85    :  
  86    :    // Writes the given data to the buffer, advancing the write pointer. Writes
  87    :    // sizeof(T) * element_count bytes.
  88    :    // @param element_count the number of elements to write.
  89    :    // @param elements the array of elements to write.
  90    :    // @returns true if there was sufficient room for the write, false otherwise.
  91    :    template<typename T> bool Write(size_t element_count, const T* elements);
  92    :  
  93    :    // Writes the given data to the buffer, advancing the write pointer. Writes
  94    :    // sizeof(T) bytes.
  95    :    // @param element the element to write.
  96    :    // @returns true if there was sufficient room for the write, false otherwise.
  97    :    template<typename T> bool Write(const T& element);
  98    :  
  99    :    // @{
 100    :    // Writes the given zero terminated string to the buffer. Writes
 101    :    // (string.size() + 1) * sizeof(string[0]) bytes.
 102    :    // @param string the string to write.
 103    :    // @returns true if there was sufficient room for the write, false otherwise.
 104    :    bool WriteString(const base::StringPiece& string);
 105    :    bool WriteString(const base::StringPiece16& string);
 106    :    // @}
 107    :  
 108    :   protected:
 109    :    // This is intended to be called by the constructors of derived classes.
 110    :    // @param buffer the initial destination buffer.
 111    :    // @param buffer_length the initial length of the buffer, in bytes.
 112    :    void SetBuffer(uint8* buffer, size_t buffer_length);
 113    :  
 114    :    // This function is responsible for ensuring that the buffer has the expected
 115    :    // size. It should return a pointer to the buffer with sufficient size, or
 116    :    // return NULL if the resize is not possible. If the resize causes a
 117    :    // reallocation, this routine is also responsible for copying all data up to
 118    :    // and the current position pos_ into the new buffer. Upon success this is
 119    :    // also responsible for cleaning up the memory used by the old buffer if a
 120    :    // resize was required. Upon failure to resize the old buffer must be
 121    :    // maintained as the BufferWriter will keep a pointer to it.
 122    :    //
 123    :    // NOTE: Implementations of this function should be careful not to cause an
 124    :    //     O(N^2) algorithm. They should generally do something like vector
 125    :    //     and actually double the buffer size when a reallocation is needed.
 126    :    //     Further calls to GrowBuffer can simply return the same buffer as long
 127    :    //     as new_length < the actual allocated length.
 128    :    //
 129    :    // @param new_length the new buffer length requested.
 130    :    // @returns a pointer to the buffer of size at least @p new_length bytes on
 131    :    //     success, a NULL pointer on failure.
 132    :    virtual uint8* GrowBuffer(size_t new_length);
 133    :  
 134    :   private:
 135    :    // This handles overflow checking, determines if the buffer needs to be
 136    :    // grown, delegates to GrowBuffer, and updates internal structures as
 137    :    // necessary. Upon a successful call buffer_ points to a buffer of size at
 138    :    // least @p new_length, and buffer_length_ is set to @p new_length.
 139    :    // @param new_length  the new buffer length requested.
 140    :    // @returns true on success, false otherwise.
 141    :    bool EnsureCanWriteFromCurrentPosition(size_t new_length);
 142    :  
 143    :    uint8* buffer_;
 144    :    size_t buffer_length_;
 145    :    size_t pos_;
 146    :  };
 147    :  
 148    :  class VectorBufferWriter : public BufferWriter {
 149    :   public:
 150    :    // Constructor for writing to an expandable buffer based on a vector.
 151    :    // @param vector the vector to be written to. Writing will start at position
 152    :    //     zero, and once we've exceeded the current size of the vector writes
 153    :    //     will cause it to grow.
 154    :    explicit VectorBufferWriter(std::vector<uint8>* vector);
 155    :  
 156    :   protected:
 157    :    virtual uint8* GrowBuffer(size_t size);
 158    :  
 159    :    std::vector<uint8>* vector_;
 160    :  };
 161    :  
 162    :  template<typename T> bool BufferWriter::Write(size_t element_count,
 163  E :                                                const T* elements) {
 164    :    return Write(element_count * sizeof(T),
 165  E :                 static_cast<const void*>(elements));
 166  E :  }
 167    :  
 168  E :  template<typename T> bool BufferWriter::Write(const T& element) {
 169  E :    return Write(sizeof(T), static_cast<const void*>(&element));
 170  E :  }
 171    :  
 172    :  }  // namespace common
 173    :  
 174    :  #endif  // SYZYGY_COMMON_BUFFER_WRITER_H_

Coverage information generated Thu Jan 14 17:40:38 2016.