Coverage for /Syzygy/block_graph/block_hash.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
97.9%46470.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    :  #include "syzygy/block_graph/block_hash.h"
  16    :  
  17    :  namespace block_graph {
  18    :  
  19    :  using base::MD5Context;
  20    :  using base::MD5Final;
  21    :  using base::MD5Init;
  22    :  using base::MD5Update;
  23    :  using base::StringPiece;
  24    :  
  25  E :  void BlockHash::Hash(const BlockGraph::Block* block) {
  26  E :    DCHECK(block != NULL);
  27    :  
  28    :    MD5Context md5_context;
  29  E :    MD5Init(&md5_context);
  30    :  
  31    :    // Hash the block properties: type, size, data_size, reference count.
  32  E :    BlockGraph::BlockType type = block->type();
  33  E :    BlockGraph::Size size = block->size();
  34  E :    BlockGraph::Size data_size = block->data_size();
  35  E :    size_t reference_count = block->references().size();
  36    :    MD5Update(&md5_context,
  37  E :        StringPiece(reinterpret_cast<const char*>(&type), sizeof(type)));
  38    :    MD5Update(&md5_context,
  39  E :        StringPiece(reinterpret_cast<const char*>(&size), sizeof(size)));
  40    :    MD5Update(&md5_context,
  41    :        StringPiece(reinterpret_cast<const char*>(&data_size),
  42  E :                    sizeof(data_size)));
  43    :    MD5Update(&md5_context,
  44    :        StringPiece(reinterpret_cast<const char*>(&reference_count),
  45  E :                          sizeof(data_size)));
  46    :  
  47    :    // Hash the references in order of increasing source offset.
  48    :    BlockGraph::Block::ReferenceMap::const_iterator ref =
  49  E :        block->references().begin();
  50  E :    BlockGraph::Offset last_source_offset = -1;
  51  E :    for (; ref != block->references().end(); ++ref) {
  52  E :      CHECK_LT(last_source_offset, ref->first);
  53  E :      last_source_offset = ref->first;
  54    :  
  55    :      // Hash the reference: source offset, type, size.
  56  E :      BlockGraph::Offset offset = ref->first;
  57  E :      BlockGraph::ReferenceType type = ref->second.type();
  58  E :      BlockGraph::Size size = ref->second.size();
  59    :      MD5Update(&md5_context,
  60  E :          StringPiece(reinterpret_cast<const char*>(&offset), sizeof(offset)));
  61    :      MD5Update(&md5_context,
  62  E :          StringPiece(reinterpret_cast<const char*>(&type), sizeof(type)));
  63    :      MD5Update(&md5_context,
  64  E :          StringPiece(reinterpret_cast<const char*>(&size), sizeof(size)));
  65  E :    }
  66    :  
  67    :    // Hash the data, skipping locations of references.
  68  E :    size_t data_index = 0;
  69  E :    ref = block->references().begin();
  70  E :    for (; ref != block->references().end(); ++ref) {
  71  E :      DCHECK_LE(0, ref->first);
  72  E :      size_t ref_offset = static_cast<size_t>(ref->first);
  73    :  
  74    :      // Have data to hash before this reference?
  75  E :      if (data_index < block->data_size() && data_index < ref_offset) {
  76  E :        size_t data_end = block->data_size();
  77  E :        if (ref_offset < data_end)
  78  E :          data_end = ref_offset;
  79    :  
  80    :        MD5Update(&md5_context,
  81    :            StringPiece(reinterpret_cast<const char*>(
  82  E :                block->data() + data_index), data_end - data_index));
  83    :      }
  84    :  
  85    :      // Skip past this reference.
  86  E :      data_index = ref_offset + ref->second.size();
  87  E :    }
  88    :  
  89    :    // Hash any data after the last reference.
  90  E :    if (data_index < block->data_size()) {
  91    :      MD5Update(&md5_context,
  92    :          StringPiece(reinterpret_cast<const char*>(
  93  E :              block->data() + data_index), block->data_size() - data_index));
  94  E :      data_index = block->data_size();
  95    :    }
  96    :  
  97    :    // Hash any trailing zero bytes in the block. The zeros are implied if the
  98    :    // data size is less than the block size.
  99  E :    while (data_index < block->size()) {
 100    :      static const char kZeros[32] = { 0 };
 101  E :      size_t bytes = block->size() - data_index;
 102  E :      if (bytes > sizeof(kZeros))
 103  i :        bytes = sizeof(kZeros);
 104  E :      MD5Update(&md5_context, StringPiece(kZeros, bytes));
 105  E :      data_index += bytes;
 106  E :    }
 107    :  
 108    :    // Finalize the hash.
 109  E :    MD5Final(&md5_digest, &md5_context);
 110  E :  }
 111    :  
 112    :  }  // namespace block_graph

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