185 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Protocol Buffers - Google's data interchange format
 | 
						|
// Copyright 2008 Google Inc.  All rights reserved.
 | 
						|
// https://developers.google.com/protocol-buffers/
 | 
						|
//
 | 
						|
// Redistribution and use in source and binary forms, with or without
 | 
						|
// modification, are permitted provided that the following conditions are
 | 
						|
// met:
 | 
						|
//
 | 
						|
//     * Redistributions of source code must retain the above copyright
 | 
						|
// notice, this list of conditions and the following disclaimer.
 | 
						|
//     * Redistributions in binary form must reproduce the above
 | 
						|
// copyright notice, this list of conditions and the following disclaimer
 | 
						|
// in the documentation and/or other materials provided with the
 | 
						|
// distribution.
 | 
						|
//     * Neither the name of Google Inc. nor the names of its
 | 
						|
// contributors may be used to endorse or promote products derived from
 | 
						|
// this software without specific prior written permission.
 | 
						|
//
 | 
						|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
						|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
						|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
						|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
						|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
						|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
						|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
						|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 | 
						|
#ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
 | 
						|
#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
 | 
						|
 | 
						|
#include <type_traits>
 | 
						|
#include <google/protobuf/parse_context.h>
 | 
						|
#include <google/protobuf/io/coded_stream.h>
 | 
						|
#include <google/protobuf/map.h>
 | 
						|
#include <google/protobuf/map_entry_lite.h>
 | 
						|
#include <google/protobuf/port.h>
 | 
						|
#include <google/protobuf/wire_format_lite.h>
 | 
						|
 | 
						|
#include <google/protobuf/port_def.inc>
 | 
						|
 | 
						|
#ifdef SWIG
 | 
						|
#error "You cannot SWIG proto headers"
 | 
						|
#endif
 | 
						|
 | 
						|
namespace google {
 | 
						|
namespace protobuf {
 | 
						|
namespace internal {
 | 
						|
 | 
						|
// This class provides access to map field using generated api. It is used for
 | 
						|
// internal generated message implementation only. Users should never use this
 | 
						|
// directly.
 | 
						|
template <typename Derived, typename Key, typename T,
 | 
						|
          WireFormatLite::FieldType key_wire_type,
 | 
						|
          WireFormatLite::FieldType value_wire_type>
 | 
						|
class MapFieldLite {
 | 
						|
  // Define message type for internal repeated field.
 | 
						|
  typedef Derived EntryType;
 | 
						|
 | 
						|
 public:
 | 
						|
  typedef Map<Key, T> MapType;
 | 
						|
  typedef EntryType EntryTypeTrait;
 | 
						|
 | 
						|
  constexpr MapFieldLite() {}
 | 
						|
 | 
						|
  explicit MapFieldLite(Arena* arena) : map_(arena) {}
 | 
						|
 | 
						|
  // Accessors
 | 
						|
  const Map<Key, T>& GetMap() const { return map_; }
 | 
						|
  Map<Key, T>* MutableMap() { return &map_; }
 | 
						|
 | 
						|
  // Convenient methods for generated message implementation.
 | 
						|
  int size() const { return static_cast<int>(map_.size()); }
 | 
						|
  void Clear() { return map_.clear(); }
 | 
						|
  void MergeFrom(const MapFieldLite& other) {
 | 
						|
    for (typename Map<Key, T>::const_iterator it = other.map_.begin();
 | 
						|
         it != other.map_.end(); ++it) {
 | 
						|
      map_[it->first] = it->second;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  void Swap(MapFieldLite* other) { map_.swap(other->map_); }
 | 
						|
  void InternalSwap(MapFieldLite* other) { map_.InternalSwap(other->map_); }
 | 
						|
 | 
						|
  // Used in the implementation of parsing. Caller should take the ownership iff
 | 
						|
  // arena_ is NULL.
 | 
						|
  EntryType* NewEntry() const {
 | 
						|
    return Arena::CreateMessage<EntryType>(map_.arena());
 | 
						|
  }
 | 
						|
  // Used in the implementation of serializing enum value type. Caller should
 | 
						|
  // take the ownership iff arena_ is NULL.
 | 
						|
  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
 | 
						|
    return EntryType::EnumWrap(key, t, map_.arena_);
 | 
						|
  }
 | 
						|
  // Used in the implementation of serializing other value types. Caller should
 | 
						|
  // take the ownership iff arena_ is NULL.
 | 
						|
  EntryType* NewEntryWrapper(const Key& key, const T& t) const {
 | 
						|
    return EntryType::Wrap(key, t, map_.arena_);
 | 
						|
  }
 | 
						|
 | 
						|
  const char* _InternalParse(const char* ptr, ParseContext* ctx) {
 | 
						|
    typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this);
 | 
						|
    return parser._InternalParse(ptr, ctx);
 | 
						|
  }
 | 
						|
 | 
						|
  template <typename UnknownType>
 | 
						|
  const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
 | 
						|
                                      bool (*is_valid)(int), uint32_t field_num,
 | 
						|
                                      InternalMetadata* metadata) {
 | 
						|
    typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this);
 | 
						|
    return parser.template ParseWithEnumValidation<UnknownType>(
 | 
						|
        ptr, ctx, is_valid, field_num, metadata);
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  typedef void DestructorSkippable_;
 | 
						|
 | 
						|
  Map<Key, T> map_;
 | 
						|
 | 
						|
  friend class ::PROTOBUF_NAMESPACE_ID::Arena;
 | 
						|
};
 | 
						|
 | 
						|
template <typename UnknownType, typename T>
 | 
						|
struct EnumParseWrapper {
 | 
						|
  const char* _InternalParse(const char* ptr, ParseContext* ctx) {
 | 
						|
    return map_field->template ParseWithEnumValidation<UnknownType>(
 | 
						|
        ptr, ctx, is_valid, field_num, metadata);
 | 
						|
  }
 | 
						|
  T* map_field;
 | 
						|
  bool (*is_valid)(int);
 | 
						|
  uint32_t field_num;
 | 
						|
  InternalMetadata* metadata;
 | 
						|
};
 | 
						|
 | 
						|
// Helper function because the typenames of maps are horrendous to print. This
 | 
						|
// leverages compiler type deduction, to keep all type data out of the
 | 
						|
// generated code
 | 
						|
template <typename UnknownType, typename T>
 | 
						|
EnumParseWrapper<UnknownType, T> InitEnumParseWrapper(
 | 
						|
    T* map_field, bool (*is_valid)(int), uint32_t field_num,
 | 
						|
    InternalMetadata* metadata) {
 | 
						|
  return EnumParseWrapper<UnknownType, T>{map_field, is_valid, field_num,
 | 
						|
                                          metadata};
 | 
						|
}
 | 
						|
 | 
						|
// True if IsInitialized() is true for value field in all elements of t. T is
 | 
						|
// expected to be message.  It's useful to have this helper here to keep the
 | 
						|
// protobuf compiler from ever having to emit loops in IsInitialized() methods.
 | 
						|
// We want the C++ compiler to inline this or not as it sees fit.
 | 
						|
template <typename Derived, typename Key, typename T,
 | 
						|
          WireFormatLite::FieldType key_wire_type,
 | 
						|
          WireFormatLite::FieldType value_wire_type>
 | 
						|
bool AllAreInitialized(const MapFieldLite<Derived, Key, T, key_wire_type,
 | 
						|
                                          value_wire_type>& field) {
 | 
						|
  const auto& t = field.GetMap();
 | 
						|
  for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
 | 
						|
       ++it) {
 | 
						|
    if (!it->second.IsInitialized()) return false;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
template <typename MEntry>
 | 
						|
struct MapEntryToMapField : MapEntryToMapField<typename MEntry::SuperType> {};
 | 
						|
 | 
						|
template <typename T, typename Key, typename Value,
 | 
						|
          WireFormatLite::FieldType kKeyFieldType,
 | 
						|
          WireFormatLite::FieldType kValueFieldType>
 | 
						|
struct MapEntryToMapField<
 | 
						|
    MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>> {
 | 
						|
  typedef MapFieldLite<
 | 
						|
      MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>, Key, Value,
 | 
						|
      kKeyFieldType, kValueFieldType>
 | 
						|
      MapFieldType;
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace internal
 | 
						|
}  // namespace protobuf
 | 
						|
}  // namespace google
 | 
						|
 | 
						|
#include <google/protobuf/port_undef.inc>
 | 
						|
 | 
						|
#endif  // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
 |