PageRenderTime 45ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/google/protobuf/unknown_field_set.h

https://gitlab.com/yenny.prathivi/protobuf
C Header | 346 lines | 189 code | 57 blank | 100 comment | 14 complexity | c321773eca0be5c4fe6e98fea9636410 MD5 | raw file
  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. namespace google {
  44. namespace protobuf {
  45. namespace io {
  46. class CodedInputStream; // coded_stream.h
  47. class CodedOutputStream; // coded_stream.h
  48. class ZeroCopyInputStream; // zero_copy_stream.h
  49. }
  50. namespace internal {
  51. class WireFormat; // wire_format.h
  52. class MessageSetFieldSkipperUsingCord;
  53. // extension_set_heavy.cc
  54. }
  55. class Message; // message.h
  56. class UnknownField; // below
  57. // An UnknownFieldSet contains fields that were encountered while parsing a
  58. // message but were not defined by its type. Keeping track of these can be
  59. // useful, especially in that they may be written if the message is serialized
  60. // again without being cleared in between. This means that software which
  61. // simply receives messages and forwards them to other servers does not need
  62. // to be updated every time a new field is added to the message definition.
  63. //
  64. // To get the UnknownFieldSet attached to any message, call
  65. // Reflection::GetUnknownFields().
  66. //
  67. // This class is necessarily tied to the protocol buffer wire format, unlike
  68. // the Reflection interface which is independent of any serialization scheme.
  69. class LIBPROTOBUF_EXPORT UnknownFieldSet {
  70. public:
  71. UnknownFieldSet();
  72. ~UnknownFieldSet();
  73. // Remove all fields.
  74. inline void Clear();
  75. // Remove all fields and deallocate internal data objects
  76. void ClearAndFreeMemory();
  77. // Is this set empty?
  78. inline bool empty() const;
  79. // Merge the contents of some other UnknownFieldSet with this one.
  80. void MergeFrom(const UnknownFieldSet& other);
  81. // Similar to above, but this function will destroy the contents of other.
  82. void MergeFromAndDestroy(UnknownFieldSet* other);
  83. // Swaps the contents of some other UnknownFieldSet with this one.
  84. inline void Swap(UnknownFieldSet* x);
  85. // Computes (an estimate of) the total number of bytes currently used for
  86. // storing the unknown fields in memory. Does NOT include
  87. // sizeof(*this) in the calculation.
  88. int SpaceUsedExcludingSelf() const;
  89. // Version of SpaceUsed() including sizeof(*this).
  90. int SpaceUsed() const;
  91. // Returns the number of fields present in the UnknownFieldSet.
  92. inline int field_count() const;
  93. // Get a field in the set, where 0 <= index < field_count(). The fields
  94. // appear in the order in which they were added.
  95. inline const UnknownField& field(int index) const;
  96. // Get a mutable pointer to a field in the set, where
  97. // 0 <= index < field_count(). The fields appear in the order in which
  98. // they were added.
  99. inline UnknownField* mutable_field(int index);
  100. // Adding fields ---------------------------------------------------
  101. void AddVarint(int number, uint64 value);
  102. void AddFixed32(int number, uint32 value);
  103. void AddFixed64(int number, uint64 value);
  104. void AddLengthDelimited(int number, const string& value);
  105. string* AddLengthDelimited(int number);
  106. UnknownFieldSet* AddGroup(int number);
  107. // Adds an unknown field from another set.
  108. void AddField(const UnknownField& field);
  109. // Delete fields with indices in the range [start .. start+num-1].
  110. // Caution: implementation moves all fields with indices [start+num .. ].
  111. void DeleteSubrange(int start, int num);
  112. // Delete all fields with a specific field number. The order of left fields
  113. // is preserved.
  114. // Caution: implementation moves all fields after the first deleted field.
  115. void DeleteByNumber(int number);
  116. // Parsing helpers -------------------------------------------------
  117. // These work exactly like the similarly-named methods of Message.
  118. bool MergeFromCodedStream(io::CodedInputStream* input);
  119. bool ParseFromCodedStream(io::CodedInputStream* input);
  120. bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
  121. bool ParseFromArray(const void* data, int size);
  122. inline bool ParseFromString(const string& data) {
  123. return ParseFromArray(data.data(), static_cast<int>(data.size()));
  124. }
  125. static const UnknownFieldSet* default_instance();
  126. private:
  127. // For InternalMergeFrom
  128. friend class UnknownField;
  129. // Merges from other UnknownFieldSet. This method assumes, that this object
  130. // is newly created and has fields_ == NULL;
  131. void InternalMergeFrom(const UnknownFieldSet& other);
  132. void ClearFallback();
  133. // fields_ is either NULL, or a pointer to a vector that is *non-empty*. We
  134. // never hold the empty vector because we want the 'do we have any unknown
  135. // fields' check to be fast, and avoid a cache miss: the UFS instance gets
  136. // embedded in the message object, so 'fields_ != NULL' tests a member
  137. // variable hot in the cache, without the need to go touch a vector somewhere
  138. // else in memory.
  139. std::vector<UnknownField>* fields_;
  140. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
  141. };
  142. // Represents one field in an UnknownFieldSet.
  143. class LIBPROTOBUF_EXPORT UnknownField {
  144. public:
  145. enum Type {
  146. TYPE_VARINT,
  147. TYPE_FIXED32,
  148. TYPE_FIXED64,
  149. TYPE_LENGTH_DELIMITED,
  150. TYPE_GROUP
  151. };
  152. // The field's tag number, as seen on the wire.
  153. inline int number() const;
  154. // The field type.
  155. inline Type type() const;
  156. // Accessors -------------------------------------------------------
  157. // Each method works only for UnknownFields of the corresponding type.
  158. inline uint64 varint() const;
  159. inline uint32 fixed32() const;
  160. inline uint64 fixed64() const;
  161. inline const string& length_delimited() const;
  162. inline const UnknownFieldSet& group() const;
  163. inline void set_varint(uint64 value);
  164. inline void set_fixed32(uint32 value);
  165. inline void set_fixed64(uint64 value);
  166. inline void set_length_delimited(const string& value);
  167. inline string* mutable_length_delimited();
  168. inline UnknownFieldSet* mutable_group();
  169. // Serialization API.
  170. // These methods can take advantage of the underlying implementation and may
  171. // archieve a better performance than using getters to retrieve the data and
  172. // do the serialization yourself.
  173. void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
  174. uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
  175. inline int GetLengthDelimitedSize() const;
  176. private:
  177. friend class UnknownFieldSet;
  178. // If this UnknownField contains a pointer, delete it.
  179. void Delete();
  180. // Reset all the underlying pointers to NULL. A special function to be only
  181. // used while merging from a temporary UFS.
  182. void Reset();
  183. // Make a deep copy of any pointers in this UnknownField.
  184. void DeepCopy(const UnknownField& other);
  185. // Set the wire type of this UnknownField. Should only be used when this
  186. // UnknownField is being created.
  187. inline void SetType(Type type);
  188. union LengthDelimited {
  189. string* string_value_;
  190. };
  191. uint32 number_;
  192. uint32 type_;
  193. union {
  194. uint64 varint_;
  195. uint32 fixed32_;
  196. uint64 fixed64_;
  197. mutable union LengthDelimited length_delimited_;
  198. UnknownFieldSet* group_;
  199. };
  200. };
  201. // ===================================================================
  202. // inline implementations
  203. inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {}
  204. inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
  205. inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
  206. inline void UnknownFieldSet::Clear() {
  207. if (fields_ != NULL) {
  208. ClearFallback();
  209. }
  210. }
  211. inline bool UnknownFieldSet::empty() const {
  212. // Invariant: fields_ is never empty if present.
  213. return !fields_;
  214. }
  215. inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
  216. std::swap(fields_, x->fields_);
  217. }
  218. inline int UnknownFieldSet::field_count() const {
  219. return fields_ ? static_cast<int>(fields_->size()) : 0;
  220. }
  221. inline const UnknownField& UnknownFieldSet::field(int index) const {
  222. GOOGLE_DCHECK(fields_ != NULL);
  223. return (*fields_)[index];
  224. }
  225. inline UnknownField* UnknownFieldSet::mutable_field(int index) {
  226. return &(*fields_)[index];
  227. }
  228. inline void UnknownFieldSet::AddLengthDelimited(
  229. int number, const string& value) {
  230. AddLengthDelimited(number)->assign(value);
  231. }
  232. inline int UnknownField::number() const { return number_; }
  233. inline UnknownField::Type UnknownField::type() const {
  234. return static_cast<Type>(type_);
  235. }
  236. inline uint64 UnknownField::varint() const {
  237. assert(type() == TYPE_VARINT);
  238. return varint_;
  239. }
  240. inline uint32 UnknownField::fixed32() const {
  241. assert(type() == TYPE_FIXED32);
  242. return fixed32_;
  243. }
  244. inline uint64 UnknownField::fixed64() const {
  245. assert(type() == TYPE_FIXED64);
  246. return fixed64_;
  247. }
  248. inline const string& UnknownField::length_delimited() const {
  249. assert(type() == TYPE_LENGTH_DELIMITED);
  250. return *length_delimited_.string_value_;
  251. }
  252. inline const UnknownFieldSet& UnknownField::group() const {
  253. assert(type() == TYPE_GROUP);
  254. return *group_;
  255. }
  256. inline void UnknownField::set_varint(uint64 value) {
  257. assert(type() == TYPE_VARINT);
  258. varint_ = value;
  259. }
  260. inline void UnknownField::set_fixed32(uint32 value) {
  261. assert(type() == TYPE_FIXED32);
  262. fixed32_ = value;
  263. }
  264. inline void UnknownField::set_fixed64(uint64 value) {
  265. assert(type() == TYPE_FIXED64);
  266. fixed64_ = value;
  267. }
  268. inline void UnknownField::set_length_delimited(const string& value) {
  269. assert(type() == TYPE_LENGTH_DELIMITED);
  270. length_delimited_.string_value_->assign(value);
  271. }
  272. inline string* UnknownField::mutable_length_delimited() {
  273. assert(type() == TYPE_LENGTH_DELIMITED);
  274. return length_delimited_.string_value_;
  275. }
  276. inline UnknownFieldSet* UnknownField::mutable_group() {
  277. assert(type() == TYPE_GROUP);
  278. return group_;
  279. }
  280. inline int UnknownField::GetLengthDelimitedSize() const {
  281. GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
  282. return static_cast<int>(length_delimited_.string_value_->size());
  283. }
  284. inline void UnknownField::SetType(Type type) {
  285. type_ = type;
  286. }
  287. } // namespace protobuf
  288. } // namespace google
  289. #endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__