Coverage for /Syzygy/block_graph/block_graph_serializer.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%19190.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    :  // Declares a helper class for serializing a block-graph.
  16    :  
  17    :  #ifndef SYZYGY_BLOCK_GRAPH_BLOCK_GRAPH_SERIALIZER_H_
  18    :  #define SYZYGY_BLOCK_GRAPH_BLOCK_GRAPH_SERIALIZER_H_
  19    :  
  20    :  #include "base/basictypes.h"
  21    :  #include "base/callback.h"
  22    :  #include "syzygy/block_graph/block_graph.h"
  23    :  #include "syzygy/core/address.h"
  24    :  
  25    :  namespace block_graph {
  26    :  
  27    :  // A class for serializing a block-graph.
  28    :  class BlockGraphSerializer {
  29    :   public:
  30    :    typedef uint32 Attributes;
  31    :    typedef core::InArchive InArchive;
  32    :    typedef core::OutArchive OutArchive;
  33    :    typedef core::RelativeAddress RelativeAddress;
  34    :  
  35    :    // An enumeration that governs the mode of data serialization.
  36    :    enum DataMode {
  37    :      // In this mode no block data is serialized. The data will be recovered from
  38    :      // an external data source via the LoadBlockDataCallback. While serializing
  39    :      // an optional SaveBlockDataCallback may save any metadata necessary to
  40    :      // recover the original block data.
  41    :      OUTPUT_NO_DATA,
  42    :      DEFAULT_DATA_MODE = OUTPUT_NO_DATA,
  43    :  
  44    :      // In this mode of serialization, only blocks that own their own data will
  45    :      // have the data serialized explicitly. The other block data will be
  46    :      // recovered via LoadBlockDataCallback, and saved via the optional
  47    :      // SaveBlockDataCallback.
  48    :      OUTPUT_OWNED_DATA,
  49    :  
  50    :      // In this mode all block data is serialized directly. The generated
  51    :      // serialization is completely independent of any external data sources.
  52    :      // Even if either of the callbacks are set, they will never be invoked.
  53    :      OUTPUT_ALL_DATA,
  54    :  
  55    :      // This needs to be last.
  56    :      DATA_MODE_MAX,
  57    :    };
  58    :  
  59    :    // Attributes that govern the serializer behaviour.
  60    :    enum AttributesEnum {
  61    :      // The serializer uses default behaviour.
  62    :      DEFAULT_ATTRIBUTES = 0,
  63    :  
  64    :      // If specified then no strings will be written as part of the
  65    :      // serialization (block names, label names). They are useful as debugging
  66    :      // information, but not required by any transforms.
  67    :      OMIT_STRINGS = (1 << 0),
  68    :  
  69    :      // If specified then all labels will be omitted from the serialization.
  70    :      // They are not needed for block level motion, but this will make basic
  71    :      // block disassembly impossible.
  72    :      OMIT_LABELS = (1 << 1),
  73    :  
  74    :      // This needs to be last, and the next unused attributes enum bit.
  75    :      ATTRIBUTES_MAX = (1 << 2),
  76    :    };
  77    :  
  78    :    // Defines the callback used to save data for a block. The callback is given
  79    :    // the following parameters:
  80    :    //
  81    :    //   1. bool data_already_saved
  82    :    //      If this is true the block's contents have been saved explicitly in the
  83    :    //      stream.
  84    :    //   2. const BlockGraph::Block& block
  85    :    //      The block whose data is to be saved.
  86    :    //   3. OutArchive* out_archive
  87    :    //      The output archive. Can be used to write data that will then be used
  88    :    //      by LoadBlockDataCallback.
  89    :    //
  90    :    // If this callback writes any data the matching LoadBlockDataCallback must
  91    :    // read the same data. Otherwise, serialization will lose its synchronization
  92    :    // and derail. This callback is optional, but if present is called for every
  93    :    // single block. It can be used to serialize additional data alongside a
  94    :    // block.
  95    :    typedef base::Callback<bool(bool,
  96    :                                const BlockGraph::Block&,
  97    :                                core::OutArchive*)> SaveBlockDataCallback;
  98    :  
  99    :    // Defines the callback used to load data for a block. The callback is given
 100    :    // the following parameters:
 101    :    //
 102    :    //   1. bool need_to_set_data
 103    :    //      If this is true then the callback is responsible for filling in the
 104    :    //      block's data. Otherwise, it will already have been set by the time of
 105    :    //      this call.
 106    :    //   2. size_t data_size
 107    :    //      The size of the data that was in the block at serialization time.
 108    :    //      Can be ignored if need_to_set_data is false.
 109    :    //   3. BlockGraph::Block* block
 110    :    //      The block whose data is to be retrieved. The block will have all of
 111    :    //      its attributes set. If need_to_set_data is true then data-size will be
 112    :    //      zero and the data pointer will be null.
 113    :    //   4. InArchive* in_archive
 114    :    //      The input archive. Can be used to read data that was written by the
 115    :    //      corresponding SaveBlockDataCallback.
 116    :    //
 117    :    // The callback should read any data set by SaveBlockData. Additionally, if
 118    :    // data_size is non-zero, block->data_size is 0 and the block's data is
 119    :    // currently NULL it should also set the block's data. If the call has failed
 120    :    // it should return false. Upon return it is expected that
 121    :    // block->data_size() == data_size and that block->data() != NULL. It is up to
 122    :    // the callback to ensure that the contents match those that were there at
 123    :    // serialization time.
 124    :    //
 125    :    // If this function is provided it will be called for every single block in
 126    :    // the block-graph. It must be provided if there are any blocks whose data
 127    :    // needs to be set.
 128    :    typedef base::Callback<bool(bool,
 129    :                                size_t,
 130    :                                BlockGraph::Block*,
 131    :                                core::InArchive*)> LoadBlockDataCallback;
 132    :  
 133    :    // Default constructor.
 134  E :    BlockGraphSerializer()
 135    :        : data_mode_(DEFAULT_DATA_MODE), attributes_(DEFAULT_ATTRIBUTES) { }
 136    :  
 137    :    // @name For setting and accessing the data mode.
 138    :    // @{
 139  E :    DataMode data_mode() const { return data_mode_; }
 140  E :    void set_data_mode(DataMode data_mode) { data_mode_ = data_mode; }
 141    :    // @}
 142    :  
 143    :    // @name For setting and accessing attributes.
 144    :    // @{
 145    :    // Adds new attributes, combining them with the existing attributes.
 146    :    // @param attr the attributes to add.
 147  E :    void add_attributes(Attributes attr) { attributes_ |= attr; }
 148    :    // Clears the given attributes, removing them from the existing attributes.
 149    :    // @param attr the attributes to clear.
 150  E :    void clear_attributes(Attributes attr) { attributes_ &= ~attr; }
 151    :    // Sets the attributes wholesale.
 152    :    // @param attr the new attributes to use.
 153  E :    void set_attributes(Attributes attr) { attributes_ = attr; }
 154    :    // @returns the current attributes.
 155  E :    Attributes attributes() const { return attributes_; }
 156    :    // Determines if all the given attributes are set.
 157    :    // @param attr the attributes to check for.
 158    :    // @returns true if all attributes in @p attr are set.
 159  E :    bool has_attributes(Attributes attr) const {
 160  E :      return (attributes_ & attr) == attr;
 161  E :    }
 162    :    // Determines if any of the given attributes are set.
 163    :    // @param attr the attributes to check for.
 164    :    // @returns true if any of the attributes in @p attr are set.
 165  E :    bool has_any_attributes(Attributes attr) const {
 166  E :      return (attributes_ & attr) != 0;
 167  E :    }
 168    :    // @}
 169    :  
 170    :    // Sets a callback to be used by the save function for writing block
 171    :    // data. This is optional, and will only be used by the OUTPUT_NO_DATA or
 172    :    // OUTPUT_OWNED_DATA data modes.
 173    :    // @param save_block_data_callback the callback to be used.
 174    :    void set_save_block_data_callback(
 175  E :        const SaveBlockDataCallback& save_block_data_callback) {
 176    :      save_block_data_callback_ = scoped_ptr<SaveBlockDataCallback>(
 177  E :          new SaveBlockDataCallback(save_block_data_callback));
 178  E :    }
 179    :  
 180    :    // Saves the given block-graph to the provided output archive.
 181    :    // @param block_graph the block-graph to be serialized.
 182    :    // @param out_archive the archive to be written to.
 183    :    // @returns true on success, false otherwise.
 184    :    bool Save(const BlockGraph& block_graph, core::OutArchive* out_archive) const;
 185    :  
 186    :    // Sets a callback to be used by the load function for retrieving block
 187    :    // data. This is optional, but is required to be set prior to calling Load
 188    :    // for any block-graph that was serialized using OUTPUT_NO_DATA or
 189    :    // OUTPUT_OWNED_DATA.
 190    :    // @param load_block_data_callback the callback to be used.
 191    :    void set_load_block_data_callback(
 192  E :        const LoadBlockDataCallback& load_block_data_callback) {
 193    :      load_block_data_callback_ = scoped_ptr<LoadBlockDataCallback>(
 194  E :          new LoadBlockDataCallback(load_block_data_callback));
 195  E :    }
 196    :  
 197    :    // Loads a block-graph from the provided input archive. The data-mode and
 198    :    // attributes used in the serialization will also be updated. If an external
 199    :    // data source is required SetBlockDataCallback must be called prior to Load.
 200    :    // @param block_graph the block-graph to be written to.
 201    :    // @param in_archive the archive to be read from.
 202    :    // @returns true on success, false otherwise.
 203    :    bool Load(BlockGraph* block_graph, core::InArchive* in_archive);
 204    :  
 205    :   protected:
 206    :    // @{
 207    :    // The block-graph is serialized by breaking it down into its constituent
 208    :    // pieces, and saving each of these using the following functions.
 209    :    bool SaveBlockGraphProperties(const BlockGraph& block_graph,
 210    :                                  OutArchive* out_archive) const;
 211    :    bool LoadBlockGraphProperties(uint32 version,
 212    :                                  BlockGraph* block_graph,
 213    :                                  InArchive* in_archive) const;
 214    :  
 215    :    bool SaveBlocks(const BlockGraph& block_graph, OutArchive* out_archive) const;
 216    :    bool LoadBlocks(uint32 version,
 217    :                    BlockGraph* block_graph,
 218    :                    InArchive* in_archive) const;
 219    :  
 220    :    bool SaveBlockGraphReferences(const BlockGraph& block_graph,
 221    :                                  OutArchive* out_archive) const;
 222    :    bool LoadBlockGraphReferences(BlockGraph* block_graph,
 223    :                                  InArchive* in_archive) const;
 224    :  
 225    :    bool SaveBlockProperties(const BlockGraph::Block& block,
 226    :                             OutArchive* out_archive) const;
 227    :    bool LoadBlockProperties(uint32 version,
 228    :                             BlockGraph::Block* block,
 229    :                             InArchive* in_archive) const;
 230    :  
 231    :    bool SaveBlockLabels(const BlockGraph::Block& block,
 232    :                         OutArchive* out_archive) const;
 233    :    bool LoadBlockLabels(BlockGraph::Block* block, InArchive* in_archive) const;
 234    :  
 235    :    bool SaveBlockData(const BlockGraph::Block& block,
 236    :                       OutArchive* out_archive) const;
 237    :    bool LoadBlockData(BlockGraph::Block* block, InArchive* in_archive) const;
 238    :  
 239    :    bool SaveBlockReferences(const BlockGraph::Block& block,
 240    :                             OutArchive* out_archive) const;
 241    :    bool LoadBlockReferences(BlockGraph* block_graph,
 242    :                             BlockGraph::Block* block,
 243    :                             InArchive* in_archive) const;
 244    :  
 245    :    bool SaveReference(const BlockGraph::Reference& ref,
 246    :                       OutArchive* out_archive) const;
 247    :    bool LoadReference(BlockGraph* block_graph,
 248    :                       BlockGraph::Reference* ref,
 249    :                       InArchive* in_archive) const;
 250    :    // @}
 251    :  
 252    :    // @{
 253    :    // Utility functions for loading and saving integer values with a simple
 254    :    // variable-length encoding.
 255    :    bool SaveUint32(uint32 value, OutArchive* out_archive) const;
 256    :    bool LoadUint32(uint32* value, InArchive* in_archive) const;
 257    :    bool SaveInt32(int32 value, OutArchive* out_archive) const;
 258    :    bool LoadInt32(int32* value, InArchive* in_archive) const;
 259    :    // @}
 260    :  
 261    :    // The mode in which the serializer is operating for block data.
 262    :    DataMode data_mode_;
 263    :    // Controls the specifics of how the serialization is performed.
 264    :    Attributes attributes_;
 265    :  
 266    :    // Optional callbacks.
 267    :    scoped_ptr<SaveBlockDataCallback> save_block_data_callback_;
 268    :    scoped_ptr<LoadBlockDataCallback> load_block_data_callback_;
 269    :  
 270    :   private:
 271    :    // A helper function that implements loading of block properties. The
 272    :    // separation to two functions avoids duplication of logging on each
 273    :    // return false branch.
 274    :    bool LoadBlockPropertiesImpl(uint32 version,
 275    :                                 BlockGraph::Block* block,
 276    :                                 InArchive* in_archive) const;
 277    :  };
 278    :  
 279    :  }  // namespace block_graph
 280    :  
 281    :  #endif  // SYZYGY_BLOCK_GRAPH_BLOCK_GRAPH_SERIALIZER_H_

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