blob: 3d45002ece09605eb546d7c8c217d556ea31750f [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.
3// http://code.google.com/p/protobuf/
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17// Author: kenton@google.com (Kenton Varda)
18// Based on original Protocol Buffers design by
19// Sanjay Ghemawat, Jeff Dean, and others.
20
21#include <google/protobuf/unknown_field_set.h>
22#include <google/protobuf/stubs/stl_util-inl.h>
temporala0f27fc2008-08-06 01:12:21 +000023#include <google/protobuf/io/coded_stream.h>
24#include <google/protobuf/io/zero_copy_stream.h>
25#include <google/protobuf/io/zero_copy_stream_impl.h>
26#include <google/protobuf/wire_format.h>
temporal40ee5512008-07-10 02:12:20 +000027
28namespace google {
29namespace protobuf {
30
31UnknownFieldSet::UnknownFieldSet()
32 : internal_(NULL) {}
33
34UnknownFieldSet::~UnknownFieldSet() {
35 if (internal_ != NULL) {
36 STLDeleteValues(&internal_->fields_);
37 delete internal_;
38 }
39}
40
41void UnknownFieldSet::Clear() {
42 if (internal_ == NULL) return;
43
44 if (internal_->fields_.size() > kMaxInactiveFields) {
45 STLDeleteValues(&internal_->fields_);
46 } else {
47 // Don't delete the UnknownField objects. Just remove them from the active
48 // set.
49 for (int i = 0; i < internal_->active_fields_.size(); i++) {
50 internal_->active_fields_[i]->Clear();
51 internal_->active_fields_[i]->index_ = -1;
52 }
53 }
54
55 internal_->active_fields_.clear();
56}
57
58void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
59 for (int i = 0; i < other.field_count(); i++) {
60 AddField(other.field(i).number())->MergeFrom(other.field(i));
61 }
62}
63
temporala0f27fc2008-08-06 01:12:21 +000064bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
65
66 UnknownFieldSet other;
67 if (internal::WireFormat::SkipMessage(input, &other) &&
68 input->ConsumedEntireMessage()) {
69 MergeFrom(other);
70 return true;
71 } else {
72 return false;
73 }
74}
75
76bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
77 Clear();
78 return MergeFromCodedStream(input);
79}
80
81bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
82 io::CodedInputStream coded_input(input);
83 return ParseFromCodedStream(&coded_input) &&
84 coded_input.ConsumedEntireMessage();
85}
86
87bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
88 io::ArrayInputStream input(data, size);
89 return ParseFromZeroCopyStream(&input);
90}
91
temporal40ee5512008-07-10 02:12:20 +000092const UnknownField* UnknownFieldSet::FindFieldByNumber(int number) const {
93 if (internal_ == NULL) return NULL;
94
95 map<int, UnknownField*>::iterator iter = internal_->fields_.find(number);
96 if (iter != internal_->fields_.end() && iter->second->index() != -1) {
97 return iter->second;
98 } else {
99 return NULL;
100 }
101}
102
103UnknownField* UnknownFieldSet::AddField(int number) {
104 if (internal_ == NULL) internal_ = new Internal;
105
106 UnknownField** map_slot = &internal_->fields_[number];
107 if (*map_slot == NULL) {
108 *map_slot = new UnknownField(number);
109 }
110
111 UnknownField* field = *map_slot;
112 if (field->index() == -1) {
113 field->index_ = internal_->active_fields_.size();
114 internal_->active_fields_.push_back(field);
115 }
116 return field;
117}
118
119UnknownField::UnknownField(int number)
120 : number_(number),
121 index_(-1) {
122}
123
124UnknownField::~UnknownField() {
125}
126
127void UnknownField::Clear() {
128 clear_varint();
129 clear_fixed32();
130 clear_fixed64();
131 clear_length_delimited();
132 clear_group();
133}
134
135void UnknownField::MergeFrom(const UnknownField& other) {
136 varint_ .MergeFrom(other.varint_ );
137 fixed32_ .MergeFrom(other.fixed32_ );
138 fixed64_ .MergeFrom(other.fixed64_ );
139 length_delimited_.MergeFrom(other.length_delimited_);
140 group_ .MergeFrom(other.group_ );
141}
142
143} // namespace protobuf
144} // namespace google