aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/unknown_field_set.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/unknown_field_set.h')
-rw-r--r--src/google/protobuf/unknown_field_set.h152
1 files changed, 136 insertions, 16 deletions
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 55eec6e2..f17012df 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -70,6 +70,13 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
void Clear();
// Is this set empty?
+ //
+ // Note that this is equivalent to field_count() == 0 but is NOT necessarily
+ // equivalent to begin() == end(). The iterator class skips fields which are
+ // themselves empty, so if field_count() is non-zero but field(i)->empty() is
+ // true for all i, then begin() will be equal to end() but empty() will return
+ // false. This inconsistency almost never occurs in practice because typical
+ // code does not add empty fields to an UnknownFieldSet.
inline bool empty() const;
// Merge the contents of some other UnknownFieldSet with this one.
@@ -78,6 +85,117 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Swaps the contents of some other UnknownFieldSet with this one.
inline void Swap(UnknownFieldSet* x);
+ // 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);
+
+ // Computes (an estimate of) the total number of bytes currently used for
+ // storing the unknown fields in memory. Does NOT include
+ // sizeof(*this) in the calculation.
+ int SpaceUsedExcludingSelf() const;
+
+ // Version of SpaceUsed() including sizeof(*this).
+ int SpaceUsed() const;
+
+ // STL-style iteration ---------------------------------------------
+ // These iterate over the non-empty UnknownFields in order by field
+ // number. All iterators are invalidated whenever the UnknownFieldSet
+ // is modified.
+
+ class const_iterator;
+
+ class LIBPROTOBUF_EXPORT iterator {
+ public:
+ iterator() {}
+
+ bool operator==(const iterator& other) {
+ return inner_iterator_ == other.inner_iterator_;
+ }
+ bool operator!=(const iterator& other) {
+ return inner_iterator_ != other.inner_iterator_;
+ }
+
+ UnknownField& operator*() { return *inner_iterator_->second; }
+ UnknownField* operator->() { return inner_iterator_->second; }
+ iterator& operator++() {
+ ++inner_iterator_;
+ AdvanceToNonEmpty();
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator copy(*this);
+ ++*this;
+ return copy;
+ }
+
+ private:
+ friend class UnknownFieldSet;
+ friend class LIBPROTOBUF_EXPORT UnknownFieldSet::const_iterator;
+ iterator(map<int, UnknownField*>::iterator inner_iterator,
+ map<int, UnknownField*>* inner_map)
+ : inner_iterator_(inner_iterator), inner_map_(inner_map) {}
+
+ void AdvanceToNonEmpty();
+
+ map<int, UnknownField*>::iterator inner_iterator_;
+ map<int, UnknownField*>* inner_map_;
+ };
+
+ class LIBPROTOBUF_EXPORT const_iterator {
+ public:
+ const_iterator() {}
+ const_iterator(const iterator& other)
+ : inner_iterator_(other.inner_iterator_), inner_map_(other.inner_map_) {}
+
+ bool operator==(const const_iterator& other) {
+ return inner_iterator_ == other.inner_iterator_;
+ }
+ bool operator!=(const const_iterator& other) {
+ return inner_iterator_ != other.inner_iterator_;
+ }
+
+ UnknownField& operator*() { return *inner_iterator_->second; }
+ UnknownField* operator->() { return inner_iterator_->second; }
+ const_iterator& operator++() {
+ ++inner_iterator_;
+ AdvanceToNonEmpty();
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator copy(*this);
+ ++*this;
+ return copy;
+ }
+
+ private:
+ friend class UnknownFieldSet;
+ const_iterator(map<int, UnknownField*>::const_iterator inner_iterator,
+ const map<int, UnknownField*>* inner_map)
+ : inner_iterator_(inner_iterator), inner_map_(inner_map) {}
+
+ void AdvanceToNonEmpty();
+
+ map<int, UnknownField*>::const_iterator inner_iterator_;
+ const map<int, UnknownField*>* inner_map_;
+ };
+
+ iterator begin();
+ iterator end() {
+ return internal_ == NULL ? kEmptyIterator :
+ iterator(internal_->fields_.end(), &internal_->fields_);
+ }
+ const_iterator begin() const;
+ const_iterator end() const {
+ return internal_ == NULL ? kEmptyConstIterator :
+ const_iterator(internal_->fields_.end(), &internal_->fields_);
+ }
+
+ // Old-style iteration ---------------------------------------------
+ // New code should use begin() and end() rather than these methods.
+
// 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
@@ -87,13 +205,6 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// 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);
-
// Parsing helpers -------------------------------------------------
// These work exactly like the similarly-named methods of Message.
@@ -105,13 +216,6 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
return ParseFromArray(data.data(), data.size());
}
- // Computes (an estimate of) the total number of bytes currently used for
- // storing the unknown fields in memory. Does NOT include
- // sizeof(*this) in the calculation.
- int SpaceUsedExcludingSelf() const;
- // Version of SpaceUsed() including sizeof(*this).
- int SpaceUsed() const;
-
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
@@ -139,6 +243,11 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Don't keep more inactive fields than this.
static const int kMaxInactiveFields = 100;
+ // Used by begin() and end() when internal_ is NULL.
+ static Internal::FieldMap kEmptyMap;
+ static const iterator kEmptyIterator;
+ static const const_iterator kEmptyConstIterator;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
};
@@ -160,6 +269,9 @@ class LIBPROTOBUF_EXPORT UnknownField {
// Clears all fields.
void Clear();
+ // Is this field empty? (I.e. all of the *_size() methods return zero.)
+ inline bool empty() const;
+
// Merge the contents of some other UnknownField with this one. For each
// wire type, the values are simply concatenated.
void MergeFrom(const UnknownField& other);
@@ -256,6 +368,14 @@ inline UnknownField* UnknownFieldSet::mutable_field(int index) {
return internal_->active_fields_[index];
}
+inline bool UnknownField::empty() const {
+ return varint_.size() == 0 &&
+ fixed32_.size() == 0 &&
+ fixed64_.size() == 0 &&
+ length_delimited_.size() == 0 &&
+ group_.size() == 0;
+}
+
inline int UnknownField::number() const { return number_; }
inline int UnknownField::index () const { return index_; }
@@ -322,8 +442,8 @@ inline UnknownFieldSet* UnknownField::add_group() {
}
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_fixed32() { fixed32_.Clear(); }
+inline void UnknownField::clear_fixed64() { fixed64_.Clear(); }
inline void UnknownField::clear_length_delimited() {
length_delimited_.Clear();
}