unknown_field_set.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // Contains classes used to keep track of unrecognized fields seen while
  35. // parsing a protocol message.
  36. #ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
  37. #define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
  38. #include <assert.h>
  39. #include <string>
  40. #include <vector>
  41. #include <google/protobuf/stubs/common.h>
  42. #include <google/protobuf/stubs/logging.h>
  43. #include <google/protobuf/message_lite.h>
  44. namespace google {
  45. namespace protobuf {
  46. namespace io {
  47. class CodedInputStream; // coded_stream.h
  48. class CodedOutputStream; // coded_stream.h
  49. class ZeroCopyInputStream; // zero_copy_stream.h
  50. }
  51. namespace internal {
  52. class InternalMetadataWithArena; // metadata.h
  53. class WireFormat; // wire_format.h
  54. class MessageSetFieldSkipperUsingCord;
  55. // extension_set_heavy.cc
  56. }
  57. class Message; // message.h
  58. class UnknownField; // below
  59. // An UnknownFieldSet contains fields that were encountered while parsing a
  60. // message but were not defined by its type. Keeping track of these can be
  61. // useful, especially in that they may be written if the message is serialized
  62. // again without being cleared in between. This means that software which
  63. // simply receives messages and forwards them to other servers does not need
  64. // to be updated every time a new field is added to the message definition.
  65. //
  66. // To get the UnknownFieldSet attached to any message, call
  67. // Reflection::GetUnknownFields().
  68. //
  69. // This class is necessarily tied to the protocol buffer wire format, unlike
  70. // the Reflection interface which is independent of any serialization scheme.
  71. class LIBPROTOBUF_EXPORT UnknownFieldSet {
  72. public:
  73. UnknownFieldSet();
  74. ~UnknownFieldSet();
  75. // Remove all fields.
  76. inline void Clear();
  77. // Remove all fields and deallocate internal data objects
  78. void ClearAndFreeMemory();
  79. // Is this set empty?
  80. inline bool empty() const;
  81. // Merge the contents of some other UnknownFieldSet with this one.
  82. void MergeFrom(const UnknownFieldSet& other);
  83. // Similar to above, but this function will destroy the contents of other.
  84. void MergeFromAndDestroy(UnknownFieldSet* other);
  85. // Merge the contents an UnknownFieldSet with the UnknownFieldSet in
  86. // *metadata, if there is one. If *metadata doesn't have an UnknownFieldSet
  87. // then add one to it and make it be a copy of the first arg.
  88. static void MergeToInternalMetdata(
  89. const UnknownFieldSet& other,
  90. internal::InternalMetadataWithArena* metadata);
  91. // Swaps the contents of some other UnknownFieldSet with this one.
  92. inline void Swap(UnknownFieldSet* x);
  93. // Computes (an estimate of) the total number of bytes currently used for
  94. // storing the unknown fields in memory. Does NOT include
  95. // sizeof(*this) in the calculation.
  96. size_t SpaceUsedExcludingSelfLong() const;
  97. int SpaceUsedExcludingSelf() const {
  98. return internal::ToIntSize(SpaceUsedExcludingSelfLong());
  99. }
  100. // Version of SpaceUsed() including sizeof(*this).
  101. size_t SpaceUsedLong() const;
  102. int SpaceUsed() const {
  103. return internal::ToIntSize(SpaceUsedLong());
  104. }
  105. // Returns the number of fields present in the UnknownFieldSet.
  106. inline int field_count() const;
  107. // Get a field in the set, where 0 <= index < field_count(). The fields
  108. // appear in the order in which they were added.
  109. inline const UnknownField& field(int index) const;
  110. // Get a mutable pointer to a field in the set, where
  111. // 0 <= index < field_count(). The fields appear in the order in which
  112. // they were added.
  113. inline UnknownField* mutable_field(int index);
  114. // Adding fields ---------------------------------------------------
  115. void AddVarint(int number, uint64 value);
  116. void AddFixed32(int number, uint32 value);
  117. void AddFixed64(int number, uint64 value);
  118. void AddLengthDelimited(int number, const string& value);
  119. string* AddLengthDelimited(int number);
  120. UnknownFieldSet* AddGroup(int number);
  121. // Adds an unknown field from another set.
  122. void AddField(const UnknownField& field);
  123. // Delete fields with indices in the range [start .. start+num-1].
  124. // Caution: implementation moves all fields with indices [start+num .. ].
  125. void DeleteSubrange(int start, int num);
  126. // Delete all fields with a specific field number. The order of left fields
  127. // is preserved.
  128. // Caution: implementation moves all fields after the first deleted field.
  129. void DeleteByNumber(int number);
  130. // Parsing helpers -------------------------------------------------
  131. // These work exactly like the similarly-named methods of Message.
  132. bool MergeFromCodedStream(io::CodedInputStream* input);
  133. bool ParseFromCodedStream(io::CodedInputStream* input);
  134. bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
  135. bool ParseFromArray(const void* data, int size);
  136. inline bool ParseFromString(const string& data) {
  137. return ParseFromArray(data.data(), static_cast<int>(data.size()));
  138. }
  139. static const UnknownFieldSet* default_instance();
  140. private:
  141. // For InternalMergeFrom
  142. friend class UnknownField;
  143. // Merges from other UnknownFieldSet. This method assumes, that this object
  144. // is newly created and has fields_ == NULL;
  145. void InternalMergeFrom(const UnknownFieldSet& other);
  146. void ClearFallback();
  147. // fields_ is either NULL, or a pointer to a vector that is *non-empty*. We
  148. // never hold the empty vector because we want the 'do we have any unknown
  149. // fields' check to be fast, and avoid a cache miss: the UFS instance gets
  150. // embedded in the message object, so 'fields_ != NULL' tests a member
  151. // variable hot in the cache, without the need to go touch a vector somewhere
  152. // else in memory.
  153. std::vector<UnknownField>* fields_;
  154. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
  155. };
  156. // Represents one field in an UnknownFieldSet.
  157. class LIBPROTOBUF_EXPORT UnknownField {
  158. public:
  159. enum Type {
  160. TYPE_VARINT,
  161. TYPE_FIXED32,
  162. TYPE_FIXED64,
  163. TYPE_LENGTH_DELIMITED,
  164. TYPE_GROUP
  165. };
  166. // The field's field number, as seen on the wire.
  167. inline int number() const;
  168. // The field type.
  169. inline Type type() const;
  170. // Accessors -------------------------------------------------------
  171. // Each method works only for UnknownFields of the corresponding type.
  172. inline uint64 varint() const;
  173. inline uint32 fixed32() const;
  174. inline uint64 fixed64() const;
  175. inline const string& length_delimited() const;
  176. inline const UnknownFieldSet& group() const;
  177. inline void set_varint(uint64 value);
  178. inline void set_fixed32(uint32 value);
  179. inline void set_fixed64(uint64 value);
  180. inline void set_length_delimited(const string& value);
  181. inline string* mutable_length_delimited();
  182. inline UnknownFieldSet* mutable_group();
  183. // Serialization API.
  184. // These methods can take advantage of the underlying implementation and may
  185. // archieve a better performance than using getters to retrieve the data and
  186. // do the serialization yourself.
  187. void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
  188. uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
  189. inline size_t GetLengthDelimitedSize() const;
  190. // If this UnknownField contains a pointer, delete it.
  191. void Delete();
  192. // Reset all the underlying pointers to NULL. A special function to be only
  193. // used while merging from a temporary UFS.
  194. void Reset();
  195. // Make a deep copy of any pointers in this UnknownField.
  196. void DeepCopy(const UnknownField& other);
  197. // Set the wire type of this UnknownField. Should only be used when this
  198. // UnknownField is being created.
  199. inline void SetType(Type type);
  200. union LengthDelimited {
  201. string* string_value_;
  202. };
  203. uint32 number_;
  204. uint32 type_;
  205. union {
  206. uint64 varint_;
  207. uint32 fixed32_;
  208. uint64 fixed64_;
  209. mutable union LengthDelimited length_delimited_;
  210. UnknownFieldSet* group_;
  211. } data_;
  212. };
  213. // ===================================================================
  214. // inline implementations
  215. inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {}
  216. inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
  217. inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
  218. inline void UnknownFieldSet::Clear() {
  219. if (fields_ != NULL) {
  220. ClearFallback();
  221. }
  222. }
  223. inline bool UnknownFieldSet::empty() const {
  224. // Invariant: fields_ is never empty if present.
  225. return !fields_;
  226. }
  227. inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
  228. std::swap(fields_, x->fields_);
  229. }
  230. inline int UnknownFieldSet::field_count() const {
  231. return fields_ ? static_cast<int>(fields_->size()) : 0;
  232. }
  233. inline const UnknownField& UnknownFieldSet::field(int index) const {
  234. GOOGLE_DCHECK(fields_ != NULL);
  235. return (*fields_)[static_cast<size_t>(index)];
  236. }
  237. inline UnknownField* UnknownFieldSet::mutable_field(int index) {
  238. return &(*fields_)[static_cast<size_t>(index)];
  239. }
  240. inline void UnknownFieldSet::AddLengthDelimited(
  241. int number, const string& value) {
  242. AddLengthDelimited(number)->assign(value);
  243. }
  244. inline int UnknownField::number() const { return static_cast<int>(number_); }
  245. inline UnknownField::Type UnknownField::type() const {
  246. return static_cast<Type>(type_);
  247. }
  248. inline uint64 UnknownField::varint() const {
  249. assert(type() == TYPE_VARINT);
  250. return data_.varint_;
  251. }
  252. inline uint32 UnknownField::fixed32() const {
  253. assert(type() == TYPE_FIXED32);
  254. return data_.fixed32_;
  255. }
  256. inline uint64 UnknownField::fixed64() const {
  257. assert(type() == TYPE_FIXED64);
  258. return data_.fixed64_;
  259. }
  260. inline const string& UnknownField::length_delimited() const {
  261. assert(type() == TYPE_LENGTH_DELIMITED);
  262. return *data_.length_delimited_.string_value_;
  263. }
  264. inline const UnknownFieldSet& UnknownField::group() const {
  265. assert(type() == TYPE_GROUP);
  266. return *data_.group_;
  267. }
  268. inline void UnknownField::set_varint(uint64 value) {
  269. assert(type() == TYPE_VARINT);
  270. data_.varint_ = value;
  271. }
  272. inline void UnknownField::set_fixed32(uint32 value) {
  273. assert(type() == TYPE_FIXED32);
  274. data_.fixed32_ = value;
  275. }
  276. inline void UnknownField::set_fixed64(uint64 value) {
  277. assert(type() == TYPE_FIXED64);
  278. data_.fixed64_ = value;
  279. }
  280. inline void UnknownField::set_length_delimited(const string& value) {
  281. assert(type() == TYPE_LENGTH_DELIMITED);
  282. data_.length_delimited_.string_value_->assign(value);
  283. }
  284. inline string* UnknownField::mutable_length_delimited() {
  285. assert(type() == TYPE_LENGTH_DELIMITED);
  286. return data_.length_delimited_.string_value_;
  287. }
  288. inline UnknownFieldSet* UnknownField::mutable_group() {
  289. assert(type() == TYPE_GROUP);
  290. return data_.group_;
  291. }
  292. inline size_t UnknownField::GetLengthDelimitedSize() const {
  293. GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
  294. return data_.length_delimited_.string_value_->size();
  295. }
  296. inline void UnknownField::SetType(Type type) {
  297. type_ = type;
  298. }
  299. } // namespace protobuf
  300. } // namespace google
  301. #endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__