1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/unknown_field_set.h>
36a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
37b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/logging.h>
38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/common.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
43a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/stl_util.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace {
49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// This global instance is returned by unknown_fields() on any message class
50b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// when the object has no unknown fields. This is necessary because we now
51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// instantiate the UnknownFieldSet dynamically only when required.
52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerUnknownFieldSet* default_unknown_field_set_instance_ = NULL;
53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid DeleteDefaultUnknownFieldSet() {
55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  delete default_unknown_field_set_instance_;
56b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
57b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
58b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid InitDefaultUnknownFieldSet() {
59b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  default_unknown_field_set_instance_ = new UnknownFieldSet();
60b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  internal::OnShutdown(&DeleteDefaultUnknownFieldSet);
61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerGOOGLE_PROTOBUF_DECLARE_ONCE(default_unknown_field_set_once_init_);
64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
66b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst UnknownFieldSet* UnknownFieldSet::default_instance() {
67b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  ::google::protobuf::GoogleOnceInit(&default_unknown_field_set_once_init_,
68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                 &InitDefaultUnknownFieldSet);
69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  return default_unknown_field_set_instance_;
70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleUnknownFieldSet::UnknownFieldSet()
73a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    : fields_(NULL) {}
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleUnknownFieldSet::~UnknownFieldSet() {
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Clear();
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  delete fields_;
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid UnknownFieldSet::ClearFallback() {
81b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ != NULL) {
82b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    for (int i = 0; i < fields_->size(); i++) {
83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      (*fields_)[i].Delete();
84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    }
85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    delete fields_;
86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    fields_ = NULL;
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
90a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid UnknownFieldSet::ClearAndFreeMemory() {
91a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (fields_ != NULL) {
92a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Clear();
93b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
94b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
95b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {
97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  int other_field_count = other.field_count();
98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (other_field_count > 0) {
99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    fields_ = new vector<UnknownField>();
100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    for (int i = 0; i < other_field_count; i++) {
101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      fields_->push_back((*other.fields_)[i]);
102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      fields_->back().DeepCopy((*other.fields_)[i]);
103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    }
104a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
105a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
106a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  int other_field_count = other.field_count();
109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (other_field_count > 0) {
110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    if (fields_ == NULL) fields_ = new vector<UnknownField>();
111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    for (int i = 0; i < other_field_count; i++) {
112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      fields_->push_back((*other.fields_)[i]);
113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      fields_->back().DeepCopy((*other.fields_)[i]);
114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    }
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// A specialized MergeFrom for performance when we are merging from an UFS that
119b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// is temporary and can be destroyed in the process.
120b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) {
121b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  int other_field_count = other->field_count();
122b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (other_field_count > 0) {
123b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    if (fields_ == NULL) fields_ = new vector<UnknownField>();
124b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    for (int i = 0; i < other_field_count; i++) {
125b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      fields_->push_back((*other->fields_)[i]);
126b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      (*other->fields_)[i].Reset();
127b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    }
128b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
129b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  delete other->fields_;
130b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  other->fields_ = NULL;
131b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
132b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnknownFieldSet::SpaceUsedExcludingSelf() const {
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (fields_ == NULL) return 0;
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
137b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < fields_->size(); i++) {
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const UnknownField& field = (*fields_)[i];
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (field.type()) {
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case UnknownField::TYPE_LENGTH_DELIMITED:
142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        total_size += sizeof(*field.length_delimited_.string_value_) +
143a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                      internal::StringSpaceUsedExcludingSelf(
144a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                          *field.length_delimited_.string_value_);
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case UnknownField::TYPE_GROUP:
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_size += field.group_->SpaceUsed();
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default:
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return total_size;
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnknownFieldSet::SpaceUsed() const {
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return sizeof(*this) + SpaceUsedExcludingSelf();
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownFieldSet::AddVarint(int number, uint64 value) {
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownField field;
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.number_ = number;
163a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.SetType(UnknownField::TYPE_VARINT);
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.varint_ = value;
165b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownFieldSet::AddFixed32(int number, uint32 value) {
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownField field;
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.number_ = number;
172a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.SetType(UnknownField::TYPE_FIXED32);
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.fixed32_ = value;
174b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownFieldSet::AddFixed64(int number, uint64 value) {
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownField field;
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.number_ = number;
181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.SetType(UnknownField::TYPE_FIXED64);
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.fixed64_ = value;
183b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring* UnknownFieldSet::AddLengthDelimited(int number) {
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownField field;
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.number_ = number;
190a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
191a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.length_delimited_.string_value_ = new string;
192b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
194a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return field.length_delimited_.string_value_;
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleUnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownField field;
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.number_ = number;
201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  field.SetType(UnknownField::TYPE_GROUP);
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.group_ = new UnknownFieldSet;
203b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return field.group_;
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownFieldSet::AddField(const UnknownField& field) {
209b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ == NULL) fields_ = new vector<UnknownField>();
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  fields_->push_back(field);
211b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  fields_->back().DeepCopy(field);
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid UnknownFieldSet::DeleteSubrange(int start, int num) {
215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Delete the specified fields.
216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < num; ++i) {
217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    (*fields_)[i + start].Delete();
218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Slide down the remaining fields.
220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = start + num; i < fields_->size(); ++i) {
221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    (*fields_)[i - num] = (*fields_)[i];
222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Pop off the # of deleted fields.
224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < num; ++i) {
225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    fields_->pop_back();
226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
227b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (fields_ && fields_->size() == 0) {
228b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    // maintain invariant: never hold fields_ if empty.
229b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    delete fields_;
230b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    fields_ = NULL;
231b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid UnknownFieldSet::DeleteByNumber(int number) {
235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (fields_ == NULL) return;
236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  int left = 0;  // The number of fields left after deletion.
237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < fields_->size(); ++i) {
238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    UnknownField* field = &(*fields_)[i];
239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field->number() == number) {
240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field->Delete();
241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else {
242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (i != left) {
243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        (*fields_)[left] = (*fields_)[i];
244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      ++left;
246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  fields_->resize(left);
249b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (left == 0) {
250b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    // maintain invariant: never hold fields_ if empty.
251b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    delete fields_;
252b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    fields_ = NULL;
253b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownFieldSet other;
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (internal::WireFormat::SkipMessage(input, &other) &&
259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      input->ConsumedEntireMessage()) {
260b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    MergeFromAndDestroy(&other);
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Clear();
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return MergeFromCodedStream(input);
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::CodedInputStream coded_input(input);
274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return (ParseFromCodedStream(&coded_input) &&
275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          coded_input.ConsumedEntireMessage());
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool UnknownFieldSet::ParseFromArray(const void* data, int size) {
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::ArrayInputStream input(data, size);
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return ParseFromZeroCopyStream(&input);
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid UnknownField::Delete() {
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (type()) {
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case UnknownField::TYPE_LENGTH_DELIMITED:
286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      delete length_delimited_.string_value_;
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case UnknownField::TYPE_GROUP:
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      delete group_;
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    default:
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
296b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Reset all owned ptrs, a special function for performance, to avoid double
297b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// owning the ptrs, when we merge from a temporary UnknownFieldSet objects.
298b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid UnknownField::Reset() {
299b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  switch (type()) {
300b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    case UnknownField::TYPE_LENGTH_DELIMITED:
301b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      length_delimited_.string_value_ = NULL;
302b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      break;
303b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    case UnknownField::TYPE_GROUP: {
304b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      group_ = NULL;
305b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      break;
306b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    }
307b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    default:
308b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      break;
309b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
310b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
311b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
312b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid UnknownField::DeepCopy(const UnknownField& other) {
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (type()) {
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case UnknownField::TYPE_LENGTH_DELIMITED:
315a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      length_delimited_.string_value_ = new string(
316a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          *length_delimited_.string_value_);
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case UnknownField::TYPE_GROUP: {
319b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      UnknownFieldSet* group = new UnknownFieldSet();
320b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      group->InternalMergeFrom(*group_);
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      group_ = group;
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    default:
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      break;
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
329a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
330a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid UnknownField::SerializeLengthDelimitedNoTag(
331a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    io::CodedOutputStream* output) const {
332a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
333a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const string& data = *length_delimited_.string_value_;
334a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  output->WriteVarint32(data.size());
335a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  output->WriteRawMaybeAliased(data.data(), data.size());
336a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
337a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
338a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonuint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
339a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
340a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const string& data = *length_delimited_.string_value_;
341a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  target = io::CodedOutputStream::WriteStringToArray(data, target);
343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return target;
344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
348