Coverage for /Syzygy/block_graph/block_graph_serializer.h

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

Coverage information generated Fri Jul 29 11:00:21 2016.