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

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