Coverage for /Syzygy/core/serialization_impl.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
92.8%1281380.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    :  // Contains Serialization implementation details. See 'serialization.h'
  16    :  // for more information. This file is not meant to be included directly,
  17    :  // but is brought in by serialization.h.
  18    :  
  19    :  #ifndef SYZYGY_CORE_SERIALIZATION_IMPL_H_
  20    :  #define SYZYGY_CORE_SERIALIZATION_IMPL_H_
  21    :  
  22    :  #include <iterator>
  23    :  
  24    :  // Forward declare base::Time, defined in "base/time/time.h".
  25    :  namespace base {
  26    :  class Time;
  27    :  }  // namespace base
  28    :  
  29    :  // Forward declare the OMAP struct. This is defined in DbgHelp.h.
  30    :  struct _OMAP;
  31    :  typedef struct _OMAP OMAP;
  32    :  
  33    :  namespace core {
  34    :  
  35    :  namespace internal {
  36    :  
  37    :  // This is for testing type equality.
  38    :  template<typename T1, typename T2> struct TypesAreEqual {
  39    :    enum { Value = 0 };
  40    :  };
  41    :  template<typename T> struct TypesAreEqual<T, T> {
  42    :    enum { Value = 1 };
  43    :  };
  44    :  
  45    :  // This tests that a given type is a signed or unsigned 1-byte type.
  46    :  template<typename T> struct IsByteLike {
  47    :    enum {
  48    :      Value =
  49    :          (TypesAreEqual<T, int8_t>::Value || TypesAreEqual<T, uint8_t>::Value) &&
  50    :          (sizeof(T) == 1)
  51    :    };
  52    :  };
  53    :  
  54    :  // This compares two iterators. It only does so if the iterator type is
  55    :  // not an output iterator.
  56    :  template<typename IteratorTag> struct IteratorsAreEqualFunctor {
  57    :    template<typename Iterator> bool operator()(Iterator it1, Iterator it2) {
  58    :      return it1 == it2;
  59    :    }
  60    :  };
  61    :  template<> struct IteratorsAreEqualFunctor<std::output_iterator_tag> {
  62  i :    template<typename Iterator> bool operator()(Iterator it1, Iterator it2) {
  63  i :      return false;
  64  i :    }
  65    :  };
  66    :  
  67    :  // Serialization for STL containers. This expects the container to implement
  68    :  // 'size', and iterators.
  69    :  template<class Container, class OutArchive> bool SaveContainer(
  70  E :      const Container& container, OutArchive* out_archive) {
  71  E :    DCHECK(out_archive != NULL);
  72    :  
  73  E :    if (!out_archive->Save(container.size()))
  74  i :      return false;
  75    :  
  76  E :    typename Container::const_iterator it = container.begin();
  77  E :    for (; it != container.end(); ++it) {
  78  E :      if (!out_archive->Save(*it))
  79  i :        return false;
  80  E :    }
  81    :  
  82  E :    return true;
  83  E :  }
  84    :  
  85    :  // We use this type traits struct to get the value_type associated with a
  86    :  // given container. We require this to get around the pair<const, non-const>
  87    :  // value_type declaration of std::map.
  88    :  template<class Container> struct ContainerValueType {
  89    :    typedef typename Container::value_type ValueType;
  90    :  };
  91    :  template<typename Key, typename Data, typename Compare, typename Alloc>
  92    :  struct ContainerValueType<std::map<Key, Data, Compare, Alloc> > {
  93    :    typedef std::pair<Key, Data> ValueType;
  94    :  };
  95    :  
  96    :  // Reserves space in a container for the given number of entries, if possible.
  97    :  template<typename Container>
  98    :  struct ReserveContainer {
  99  E :    void operator()(size_t entries, Container* container) {
 100    :      // Do nothing for most containers.
 101  E :    }
 102    :  };
 103    :  // std::vector and std::basic_string both support 'reserve'.
 104    :  template<typename T>
 105    :  struct ReserveContainer<std::vector<T>> {
 106  E :    void operator()(size_t entries, std::vector<T>* vector) {
 107  E :      DCHECK(vector != NULL);
 108  E :      vector->reserve(entries);
 109  E :    }
 110    :  };
 111    :  template<typename Char, typename Traits, typename Alloc>
 112    :  struct ReserveContainer<std::basic_string<Char, Traits, Alloc>> {
 113    :    void operator()(size_t entries,
 114  E :                    std::basic_string<Char, Traits, Alloc>* string) {
 115  E :      DCHECK(string != NULL);
 116  E :      string->reserve(entries);
 117  E :    }
 118    :  };
 119    :  
 120    :  // Loads serialized values into a container via an output iterator.
 121    :  template<typename Container, typename OutputIterator, class InArchive>
 122    :  bool LoadContainer(Container* container,
 123    :                     OutputIterator output_iterator,
 124  E :                     InArchive* in_archive) {
 125  E :    DCHECK(container != NULL);
 126  E :    DCHECK(in_archive != NULL);
 127    :  
 128    :    // Get the value type.
 129    :    typedef ContainerValueType<Container>::ValueType ValueType;
 130    :  
 131  E :    typename Container::size_type size = 0;
 132  E :    if (!in_archive->Load(&size))
 133  i :      return false;
 134    :  
 135    :    // Reserve room for the entries, if the container supports it. This makes
 136    :    // this slightly more efficient.
 137  E :    ReserveContainer<Container>()(size, container);
 138    :  
 139  E :    typename Container::size_type i = 0;
 140  E :    for (; i < size; ++i) {
 141  E :      ValueType value;
 142  E :      if (!in_archive->Load(&value))
 143  i :        return false;
 144  E :      *output_iterator = value;
 145  E :      ++output_iterator;
 146  E :    }
 147    :  
 148  E :    DCHECK_EQ(size, container->size());
 149    :  
 150  E :    return true;
 151  E :  }
 152    :  
 153    :  }  // namespace internal
 154    :  
 155    :  template<typename OutputIterator> bool ByteOutStream<OutputIterator>::Write(
 156  E :      size_t length, const Byte* bytes) {
 157  E :    for (size_t i = 0; i < length; ++i, ++bytes) {
 158  E :      if (have_end_ && IteratorsAreEqual()(iter_, end_))
 159  i :        return false;
 160    :      // The underlying output type has to be able to cope with
 161    :      // assignment from a Byte!
 162  E :      *iter_ = *bytes;
 163  E :      ++iter_;
 164  E :    }
 165  E :    return true;
 166  E :  }
 167    :  
 168    :  template<typename InputIterator> bool ByteInStream<InputIterator>::ReadImpl(
 169  E :      size_t length, Byte* bytes, size_t* bytes_read) {
 170  E :    DCHECK(bytes != NULL);
 171  E :    DCHECK(bytes_read != NULL);
 172    :  
 173  E :    Byte* bytes_start = bytes;
 174  E :    for (size_t i = 0; i < length; ++i, ++bytes) {
 175  E :      if (iter_ == end_)
 176  E :        break;
 177  E :      *bytes = static_cast<Byte>(*iter_);
 178  E :      ++iter_;
 179  E :    }
 180    :  
 181  E :    *bytes_read = static_cast<size_t>(bytes - bytes_start);
 182  E :    return true;
 183  E :  }
 184    :  
 185    :  // Default implementations of core::Save and core::Load.
 186    :  
 187    :  // This delegates to Data::Save.
 188    :  template<class Data, class OutArchive> bool Save(
 189  E :      const Data& data, OutArchive* out_archive) {
 190  E :    DCHECK(out_archive != NULL);
 191  E :    return data.Save(out_archive);
 192  E :  }
 193    :  
 194    :  // This delegates to Data::Load.
 195    :  template<class Data, class InArchive> bool Load(
 196  E :      Data* data, InArchive* in_archive) {
 197  E :    DCHECK(data != NULL);
 198  E :    DCHECK(in_archive != NULL);
 199  E :    return data->Load(in_archive);
 200  E :  }
 201    :  
 202    :  // Implementation of STL Save specializations.
 203    :  
 204    :  template<typename Char, typename Traits, typename Alloc, class OutArchive>
 205    :  bool Save(const std::basic_string<Char, Traits, Alloc>& string,
 206  E :            OutArchive* out_archive) {
 207  E :    DCHECK(out_archive != NULL);
 208  E :    return internal::SaveContainer(string, out_archive);
 209  E :  }
 210    :  
 211    :  template<typename Key, typename Data, typename Compare, typename Alloc,
 212    :           class OutArchive>
 213    :  bool Save(const std::map<Key, Data, Compare, Alloc>& map,
 214  E :            OutArchive* out_archive) {
 215  E :    DCHECK(out_archive != NULL);
 216  E :    return internal::SaveContainer(map, out_archive);
 217  E :  }
 218    :  
 219    :  template<typename Type1, typename Type2, class OutArchive>
 220    :  bool Save(const std::pair<Type1, Type2>& pair,
 221  E :            OutArchive* out_archive) {
 222  E :    DCHECK(out_archive != NULL);
 223  E :    return out_archive->Save(pair.first) && out_archive->Save(pair.second);
 224  E :  }
 225    :  
 226    :  template<typename Key, typename Compare, typename Alloc, class OutArchive>
 227    :  bool Save(const std::set<Key, Compare, Alloc>& set,
 228  E :            OutArchive* out_archive) {
 229  E :    DCHECK(out_archive != NULL);
 230  E :    return internal::SaveContainer(set, out_archive);
 231  E :  }
 232    :  
 233    :  template<typename Type, typename Alloc, class OutArchive>
 234    :  bool Save(const std::vector<Type, Alloc>& vector,
 235  E :            OutArchive* out_archive) {
 236  E :    DCHECK(out_archive != NULL);
 237  E :    return internal::SaveContainer(vector, out_archive);
 238  E :  }
 239    :  
 240    :  // Implementation of STL Load specializations.
 241    :  
 242    :  template<typename Char, typename Traits, typename Alloc, class InArchive>
 243    :  bool Load(std::basic_string<Char, Traits, Alloc>* string,
 244  E :            InArchive* in_archive) {
 245  E :    DCHECK(string != NULL);
 246  E :    DCHECK(in_archive != NULL);
 247  E :    string->clear();
 248  E :    return internal::LoadContainer(string,
 249    :                                   std::back_inserter(*string),
 250    :                                   in_archive);
 251  E :  }
 252    :  
 253    :  template<typename Key, typename Data, typename Compare, typename Alloc,
 254    :           class InArchive>
 255    :  bool Load(std::map<Key, Data, Compare, Alloc>* map,
 256  E :            InArchive* in_archive) {
 257  E :    DCHECK(map != NULL);
 258  E :    DCHECK(in_archive != NULL);
 259  E :    map->clear();
 260  E :    return internal::LoadContainer(map,
 261    :                                   std::inserter(*map, map->begin()),
 262    :                                   in_archive);
 263  E :  }
 264    :  
 265    :  template<typename Type1, typename Type2, class InArchive>
 266    :  bool Load(std::pair<Type1, Type2>* pair,
 267  E :            InArchive* in_archive) {
 268  E :    DCHECK(pair != NULL);
 269  E :    DCHECK(in_archive != NULL);
 270  E :    return in_archive->Load(&(pair->first)) && in_archive->Load(&(pair->second));
 271  E :  }
 272    :  
 273    :  template<typename Key, typename Compare, typename Alloc, class InArchive>
 274    :  bool Load(std::set<Key, Compare, Alloc>* set,
 275  E :            InArchive* in_archive) {
 276  E :    DCHECK(set != NULL);
 277  E :    DCHECK(in_archive != NULL);
 278  E :    set->clear();
 279  E :    return internal::LoadContainer(set,
 280    :                                   std::inserter(*set, set->begin()),
 281    :                                   in_archive);
 282  E :  }
 283    :  
 284    :  template<typename Type, typename Alloc, class InArchive>
 285    :  bool Load(std::vector<Type, Alloc>* vector,
 286  E :            InArchive* in_archive) {
 287  E :    DCHECK(vector != NULL);
 288  E :    DCHECK(in_archive != NULL);
 289  E :    return internal::LoadContainer(vector,
 290    :                                   std::back_inserter(*vector),
 291    :                                   in_archive);
 292  E :  }
 293    :  
 294    :  // Implementation of serialization for C-style arrays.
 295    :  
 296    :  template<typename Type, size_t Length, class OutArchive>
 297  E :  bool Save(const Type (&data)[Length], OutArchive* out_archive) {
 298  E :    DCHECK(out_archive != NULL);
 299  E :    for (size_t i = 0; i < Length; ++i) {
 300  E :      if (!out_archive->Save(data[i]))
 301  i :        return false;
 302  E :    }
 303  E :    return true;
 304  E :  }
 305    :  
 306    :  template<typename Type, size_t Length, class InArchive>
 307  E :  bool Load(Type (*data)[Length], InArchive* in_archive) {
 308  E :    DCHECK(data != NULL);
 309  E :    DCHECK(in_archive != NULL);
 310  E :    for (size_t i = 0; i < Length; ++i) {
 311  E :      if (!in_archive->Load(&((*data)[i])))
 312  i :        return false;
 313  E :    }
 314  E :    return true;
 315  E :  }
 316    :  
 317    :  // Declaration of serialization for base::Time.
 318    :  bool Save(const base::Time& time, OutArchive* out_archive);
 319    :  bool Load(base::Time* time, InArchive* in_archive);
 320    :  
 321    :  // Declaration of OMAP struct serialization.
 322    :  bool Save(const OMAP& omap, OutArchive* out_archive);
 323    :  bool Load(OMAP* omap, InArchive* in_archive);
 324    :  
 325    :  }  // namespace core
 326    :  
 327    :  #endif  // SYZYGY_CORE_SERIALIZATION_IMPL_H_

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