Coverage for /Syzygy/pdb/pdb_stream.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%45450.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    :  #ifndef SYZYGY_PDB_PDB_STREAM_H_
  16    :  #define SYZYGY_PDB_PDB_STREAM_H_
  17    :  
  18    :  #include <stdio.h>
  19    :  #include <vector>
  20    :  
  21    :  #include "base/basictypes.h"
  22    :  #include "base/logging.h"
  23    :  #include "base/memory/ref_counted.h"
  24    :  #include "syzygy/common/buffer_writer.h"
  25    :  
  26    :  namespace pdb {
  27    :  
  28    :  // Forward declaration.
  29    :  class WritablePdbStream;
  30    :  
  31    :  // This class represents a PDB stream. It has a stream-like interface that
  32    :  // allows invoking successive reads through the stream and seeking.
  33    :  class PdbStream : public base::RefCounted<PdbStream> {
  34    :   public:
  35    :    explicit PdbStream(size_t length);
  36    :  
  37    :    // Reads @p count chunks of size sizeof(ItemType) into the destination buffer.
  38    :    // The caller is responsible for ensuring that the destination buffer has
  39    :    // enough space to receive the data. Returns the number of items successfully
  40    :    // read via @p items_read.
  41    :    //
  42    :    // @tparam ItemType the type of item to coerce the data to.
  43    :    // @param dest the destination array.
  44    :    // @param count the number of elements to read.
  45    :    // @param items_read pointer to receive the number of items successfully read.
  46    :    // @returns true on success.
  47    :    template <typename ItemType>
  48    :    bool Read(ItemType* dest, size_t count, size_t* items_read);
  49    :  
  50    :    // Reads @p count chunks of size sizeof(ItemType) into the destination buffer.
  51    :    // The caller is responsible for ensuring that the destination buffer has
  52    :    // enough space to receive the data.
  53    :    //
  54    :    // @tparam ItemType the type of item to coerce the data to.
  55    :    // @param dest the destination array.
  56    :    // @param count the number of elements to read.
  57    :    // @returns true on success.
  58    :    template <typename ItemType>
  59    :    bool Read(ItemType* dest, size_t count);
  60    :  
  61    :    // Reads @p count elements of size sizeof(ItemType) into the provided
  62    :    // vector of elements. Resizes @p dest to the number of elements that were
  63    :    // successfully read.
  64    :    //
  65    :    // @tparam ItemType the type of item to coerce the data to.
  66    :    // @param dest the destination vector.
  67    :    // @param count the number of elements to read.
  68    :    // @returns true if @p dest was populated with @p count elements, false
  69    :    //     otherwise. The number of elements actually read is indicated by the
  70    :    //     length of @p dest.
  71    :    template <typename ItemType>
  72    :    bool Read(std::vector<ItemType>* dest, size_t count);
  73    :  
  74    :    // Fills the provided vector with elements read from this stream. The bytes
  75    :    // remaining in the stream must be an even multiple of sizeof(ItemType).
  76    :    // Resizes @p dest to the number of elements read.
  77    :    //
  78    :    // @tparam ItemType the type of item to coerce the data to.
  79    :    // @param dest the destination vector.
  80    :    // @returns true if the remaining bytes in the stream were read into the
  81    :    //     provided vector, false otherwise. The number of elements actually read
  82    :    //     is indicated by the length of @p dest.
  83    :    template <typename ItemType>
  84    :    bool Read(std::vector<ItemType>* dest);
  85    :  
  86    :    // Reads @p count bytes of data into the destination buffer. The caller is
  87    :    // responsible for ensuring that the destination buffer has enough space to
  88    :    // receive the data. @p bytes_read will hold the number of bytes read. If
  89    :    // there was insufficient data but some bytes were read, returns false and
  90    :    // returns the number of bytes read via @p bytes_read.
  91    :    //
  92    :    // @param dest the buffer to receive the data.
  93    :    // @param count the number of bytes to read.
  94    :    // @param bytes_read pointer that will receive the number of bytes read.
  95    :    // @returns true if all @p count bytes are read, false otherwise.
  96    :    virtual bool ReadBytes(void* dest, size_t count, size_t* bytes_read) = 0;
  97    :  
  98    :    // Returns a pointer to a WritablePdbStream if the underlying object supports
  99    :    // this interface. If this returns non-NULL, it is up to the user to ensure
 100    :    // thread safety; each writer should be used exclusively of any other writer,
 101    :    // and no reader should be used while a writer is in use. Each of the reader
 102    :    // and writer maintains its own cursor, but their view of the data (and its
 103    :    // length) will remain in sync.
 104    :    //
 105    :    // NOTE: This function should act as a factory, with each call returning a
 106    :    //     heap allocated reference counted writer. However, since each
 107    :    //     WritablePdbStream is currently implemented using a BufferWriter, and
 108    :    //     the BufferWriter maintains its own state internally rather than a
 109    :    //     shared state, its possible that one writer causing a resize could
 110    :    //     invalidate the internal data pointer held by another writer. As a
 111    :    //     workaround, there is only a single writer allowed to be allocated
 112    :    //     right now.
 113    :    //
 114    :    // TODO(chrisha): Clean this up to return an interface, which can be wrapped
 115    :    //     in some common stream-writer functionality, reusing BufferWriter.
 116    :    //
 117    :    // @returns a pointer to a WritablePdbStream.
 118  E :    virtual scoped_refptr<WritablePdbStream> GetWritablePdbStream() {
 119  E :      return scoped_refptr<WritablePdbStream>();
 120  E :    }
 121    :  
 122    :    // Sets the current read position.
 123    :    bool Seek(size_t pos);
 124    :  
 125    :    // Gets the stream's length.
 126    :    // @returns the total number of bytes in the stream.
 127  E :    size_t length() const { return length_; }
 128    :  
 129    :    // Gets the stream's read position.
 130    :    // @returns the number of bytes already read.
 131  E :    size_t pos() const { return pos_; }
 132    :  
 133    :    // Gets the number of bytes left to read in the stream.
 134    :    // @returns the number of bytes left.
 135  E :    size_t bytes_left() const { return length_ - pos_; }
 136    :  
 137    :   protected:
 138    :    friend base::RefCounted<PdbStream>;
 139    :  
 140    :    // Protected to enforce use of ref-counted pointers at compile time.
 141    :    virtual ~PdbStream();
 142    :  
 143    :    // Sets the stream's length.
 144  E :    void set_length(size_t length) { length_ = length; }
 145    :  
 146    :   private:
 147    :    // The length of the stream.
 148    :    size_t length_;
 149    :  
 150    :    // The read position within the stream.
 151    :    size_t pos_;
 152    :  
 153    :    DISALLOW_COPY_AND_ASSIGN(PdbStream);
 154    :  };
 155    :  
 156    :  // Represents a writable PDB stream.
 157    :  // TODO(chrisha): For now, this inherits from common::BufferWriter, but a far
 158    :  //     cleaner approach would be to hoist a basic WritableStreamInterface, and
 159    :  //     make BufferWriter accept a pointer to said interface. The same thing
 160    :  //     could be done to the sawbuck BufferParser/BufferReader and PdbStream
 161    :  //     hierarchy.
 162    :  class WritablePdbStream : public base::RefCounted<WritablePdbStream>,
 163    :                            public common::BufferWriter {
 164    :   public:
 165    :    // Constructor.
 166  E :    WritablePdbStream() : common::BufferWriter(NULL, 0) { }
 167    :  
 168    :   protected:
 169    :    friend base::RefCounted<WritablePdbStream>;
 170    :  
 171    :    // Destructor. Protected to enforce use of ref-counted pointers at compile
 172    :    // time.
 173  E :    virtual ~WritablePdbStream() { }
 174    :  
 175    :    // Forwarded from common::BufferWriter.
 176    :    virtual uint8* GrowBuffer(size_t size) = 0;
 177    :  };
 178    :  
 179    :  template <typename ItemType>
 180  E :  bool PdbStream::Read(ItemType* dest, size_t count, size_t* items_read) {
 181  E :    DCHECK(dest != NULL);
 182  E :    DCHECK(items_read != NULL);
 183    :  
 184  E :    size_t byte_size = sizeof(ItemType) * count;
 185  E :    if (byte_size > bytes_left())
 186  E :      return false;
 187    :  
 188  E :    size_t bytes_read = 0;
 189  E :    bool result = ReadBytes(dest, byte_size, &bytes_read);
 190  E :    *items_read = bytes_read / sizeof(ItemType);
 191  E :    return result && *items_read == count;
 192  E :  }
 193    :  
 194    :  template <typename ItemType>
 195  E :  bool PdbStream::Read(ItemType* dest, size_t count) {
 196  E :    DCHECK(dest != NULL);
 197  E :    size_t items_read = 0;
 198  E :    return Read(dest, count, &items_read) && items_read == count;
 199  E :  }
 200    :  
 201    :  template <typename ItemType>
 202  E :  bool PdbStream::Read(std::vector<ItemType>* dest, size_t count) {
 203  E :    DCHECK(dest != NULL);
 204  E :    dest->clear();
 205  E :    if (sizeof(ItemType) * count > bytes_left())
 206  E :      return false;
 207  E :    dest->resize(count);
 208    :  
 209  E :    if (count == 0)
 210  E :      return true;
 211    :  
 212  E :    size_t items_read = 0;
 213  E :    bool result = Read(&dest->at(0), count, &items_read);
 214  E :    dest->resize(items_read);
 215  E :    return result;
 216  E :  }
 217    :  
 218    :  template <typename ItemType>
 219  E :  bool PdbStream::Read(std::vector<ItemType>* dest) {
 220  E :    DCHECK(dest != NULL);
 221  E :    dest->clear();
 222  E :    if ((bytes_left() % sizeof(ItemType)) != 0)
 223  E :      return false;
 224  E :    return Read(dest, bytes_left() / sizeof(ItemType));
 225  E :  }
 226    :  
 227    :  }  // namespace pdb
 228    :  
 229    :  #endif  // SYZYGY_PDB_PDB_STREAM_H_

Coverage information generated Thu Jul 04 09:34:53 2013.