blob: 421846215ff69142f51248d55a4f6f363bde8fb9 [file] [log] [blame]
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Contains classes used to keep track of unrecognized fields seen while
// parsing a protocol message.
#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
#include <string>
#include <map>
#include <vector>
#include <google/protobuf/repeated_field.h>
namespace google {
namespace protobuf {
class Message; // message.h
class UnknownField; // below
// An UnknownFieldSet contains fields that were encountered while parsing a
// message but were not defined by its type. Keeping track of these can be
// useful, especially in that they may be written if the message is serialized
// again without being cleared in between. This means that software which
// simply receives messages and forwards them to other servers does not need
// to be updated every time a new field is added to the message definition.
//
// To get the UnknownFieldSet attached to any message, call
// Message::Reflection::GetUnknownFields().
//
// This class is necessarily tied to the protocol buffer wire format, unlike
// the Reflection interface which is independent of any serialization scheme.
class LIBPROTOBUF_EXPORT UnknownFieldSet {
public:
UnknownFieldSet();
~UnknownFieldSet();
// Remove all fields.
void Clear();
// Is this set empty?
inline bool empty() const;
// Merge the contents of some other UnknownFieldSet with this one.
void MergeFrom(const UnknownFieldSet& other);
// Returns the number of fields present in the UnknownFieldSet.
inline int field_count() const;
// Get a field in the set, where 0 <= index < field_count(). The fields
// appear in arbitrary order.
inline const UnknownField& field(int index) const;
// Get a mutable pointer to a field in the set, where
// 0 <= index < field_count(). The fields appear in arbitrary order.
inline UnknownField* mutable_field(int index);
// Find a field by field number. Returns NULL if not found.
const UnknownField* FindFieldByNumber(int number) const;
// Add a field by field number. If the field number already exists, returns
// the existing UnknownField.
UnknownField* AddField(int number);
private:
// "Active" fields are ones which have been added since the last time Clear()
// was called. Inactive fields are objects we are keeping around incase
// they become active again.
struct Internal {
// Contains all UnknownFields that have been allocated for this
// UnknownFieldSet, including ones not currently active. Keyed by
// field number. We intentionally try to reuse UnknownField objects for
// the same field number they were used for originally because this makes
// it more likely that the previously-allocated memory will have the right
// layout.
map<int, UnknownField*> fields_;
// Contains the fields from fields_ that are currently active.
vector<UnknownField*> active_fields_;
};
// We want an UnknownFieldSet to use no more space than a single pointer
// until the first field is added.
Internal* internal_;
// Don't keep more inactive fields than this.
static const int kMaxInactiveFields = 100;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
};
// Represents one field in an UnknownFieldSet.
//
// UnknownFiled's accessors are similar to those that would be produced by the
// protocol compiler for the fields:
// repeated uint64 varint;
// repeated fixed32 fixed32;
// repeated fixed64 fixed64;
// repeated bytes length_delimited;
// repeated UnknownFieldSet group;
// (OK, so the last one isn't actually a valid field type but you get the
// idea.)
class LIBPROTOBUF_EXPORT UnknownField {
public:
~UnknownField();
// Clears all fields.
void Clear();
// Merge the contents of some other UnknownField with this one. For each
// wire type, the values are simply concatenated.
void MergeFrom(const UnknownField& other);
// The field's tag number, as seen on the wire.
inline int number() const;
// The index of this UnknownField within the UknownFieldSet (e.g.
// set.field(field.index()) == field).
inline int index() const;
inline int varint_size () const;
inline int fixed32_size () const;
inline int fixed64_size () const;
inline int length_delimited_size() const;
inline int group_size () const;
inline uint64 varint (int index) const;
inline uint32 fixed32(int index) const;
inline uint64 fixed64(int index) const;
inline const string& length_delimited(int index) const;
inline const UnknownFieldSet& group(int index) const;
inline void set_varint (int index, uint64 value);
inline void set_fixed32(int index, uint32 value);
inline void set_fixed64(int index, uint64 value);
inline void set_length_delimited(int index, const string& value);
inline string* mutable_length_delimited(int index);
inline UnknownFieldSet* mutable_group(int index);
inline void add_varint (uint64 value);
inline void add_fixed32(uint32 value);
inline void add_fixed64(uint64 value);
inline void add_length_delimited(const string& value);
inline string* add_length_delimited();
inline UnknownFieldSet* add_group();
inline void clear_varint ();
inline void clear_fixed32();
inline void clear_fixed64();
inline void clear_length_delimited();
inline void clear_group();
inline const RepeatedField <uint64 >& varint () const;
inline const RepeatedField <uint32 >& fixed32 () const;
inline const RepeatedField <uint64 >& fixed64 () const;
inline const RepeatedPtrField<string >& length_delimited() const;
inline const RepeatedPtrField<UnknownFieldSet>& group () const;
inline RepeatedField <uint64 >* mutable_varint ();
inline RepeatedField <uint32 >* mutable_fixed32 ();
inline RepeatedField <uint64 >* mutable_fixed64 ();
inline RepeatedPtrField<string >* mutable_length_delimited();
inline RepeatedPtrField<UnknownFieldSet>* mutable_group ();
private:
friend class UnknownFieldSet;
UnknownField(int number);
int number_;
int index_;
RepeatedField <uint64 > varint_;
RepeatedField <uint32 > fixed32_;
RepeatedField <uint64 > fixed64_;
RepeatedPtrField<string > length_delimited_;
RepeatedPtrField<UnknownFieldSet> group_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownField);
};
// ===================================================================
// inline implementations
inline bool UnknownFieldSet::empty() const {
return internal_ == NULL || internal_->active_fields_.empty();
}
inline int UnknownFieldSet::field_count() const {
return (internal_ == NULL) ? 0 : internal_->active_fields_.size();
}
inline const UnknownField& UnknownFieldSet::field(int index) const {
return *(internal_->active_fields_[index]);
}
inline UnknownField* UnknownFieldSet::mutable_field(int index) {
return internal_->active_fields_[index];
}
inline int UnknownField::number() const { return number_; }
inline int UnknownField::index () const { return index_; }
inline int UnknownField::varint_size () const {return varint_.size();}
inline int UnknownField::fixed32_size () const {return fixed32_.size();}
inline int UnknownField::fixed64_size () const {return fixed64_.size();}
inline int UnknownField::length_delimited_size() const {
return length_delimited_.size();
}
inline int UnknownField::group_size () const {return group_.size();}
inline uint64 UnknownField::varint (int index) const {
return varint_.Get(index);
}
inline uint32 UnknownField::fixed32(int index) const {
return fixed32_.Get(index);
}
inline uint64 UnknownField::fixed64(int index) const {
return fixed64_.Get(index);
}
inline const string& UnknownField::length_delimited(int index) const {
return length_delimited_.Get(index);
}
inline const UnknownFieldSet& UnknownField::group(int index) const {
return group_.Get(index);
}
inline void UnknownField::set_varint (int index, uint64 value) {
varint_.Set(index, value);
}
inline void UnknownField::set_fixed32(int index, uint32 value) {
fixed32_.Set(index, value);
}
inline void UnknownField::set_fixed64(int index, uint64 value) {
fixed64_.Set(index, value);
}
inline void UnknownField::set_length_delimited(int index, const string& value) {
length_delimited_.Mutable(index)->assign(value);
}
inline string* UnknownField::mutable_length_delimited(int index) {
return length_delimited_.Mutable(index);
}
inline UnknownFieldSet* UnknownField::mutable_group(int index) {
return group_.Mutable(index);
}
inline void UnknownField::add_varint (uint64 value) {
varint_.Add(value);
}
inline void UnknownField::add_fixed32(uint32 value) {
fixed32_.Add(value);
}
inline void UnknownField::add_fixed64(uint64 value) {
fixed64_.Add(value);
}
inline void UnknownField::add_length_delimited(const string& value) {
length_delimited_.Add()->assign(value);
}
inline string* UnknownField::add_length_delimited() {
return length_delimited_.Add();
}
inline UnknownFieldSet* UnknownField::add_group() {
return group_.Add();
}
inline void UnknownField::clear_varint () { varint_.Clear(); }
inline void UnknownField::clear_fixed32() { varint_.Clear(); }
inline void UnknownField::clear_fixed64() { varint_.Clear(); }
inline void UnknownField::clear_length_delimited() {
length_delimited_.Clear();
}
inline void UnknownField::clear_group() { group_.Clear(); }
inline const RepeatedField<uint64>& UnknownField::varint () const {
return varint_;
}
inline const RepeatedField<uint32>& UnknownField::fixed32() const {
return fixed32_;
}
inline const RepeatedField<uint64>& UnknownField::fixed64() const {
return fixed64_;
}
inline const RepeatedPtrField<string>& UnknownField::length_delimited() const {
return length_delimited_;
}
inline const RepeatedPtrField<UnknownFieldSet>& UnknownField::group() const {
return group_;
}
inline RepeatedField<uint64>* UnknownField::mutable_varint () {
return &varint_;
}
inline RepeatedField<uint32>* UnknownField::mutable_fixed32() {
return &fixed32_;
}
inline RepeatedField<uint64>* UnknownField::mutable_fixed64() {
return &fixed64_;
}
inline RepeatedPtrField<string>* UnknownField::mutable_length_delimited() {
return &length_delimited_;
}
inline RepeatedPtrField<UnknownFieldSet>* UnknownField::mutable_group() {
return &group_;
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__