Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: third_party/protobuf/src/google/protobuf/map_entry_lite.h

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 13 matching lines...) Expand all
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ 31 #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
32 #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ 32 #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
33 33
34 #include <assert.h>
35 #include <google/protobuf/map_type_handler.h> 34 #include <google/protobuf/map_type_handler.h>
36 #include <google/protobuf/wire_format_lite_inl.h> 35 #include <google/protobuf/wire_format_lite_inl.h>
37 36
38 namespace google { 37 namespace google {
39 namespace protobuf { 38 namespace protobuf {
40 class Arena; 39 class Arena;
41 namespace internal { 40 namespace internal {
42 template <typename Key, typename Value, 41 template <typename Key, typename Value,
43 WireFormatLite::FieldType kKeyFieldType, 42 WireFormatLite::FieldType kKeyFieldType,
44 WireFormatLite::FieldType kValueFieldType, 43 WireFormatLite::FieldType kValueFieldType,
45 int default_enum_value> 44 int default_enum_value>
46 class MapEntry; 45 class MapEntry;
47 template <typename Key, typename Value, 46 template <typename Key, typename Value,
48 WireFormatLite::FieldType kKeyFieldType, 47 WireFormatLite::FieldType kKeyFieldType,
49 WireFormatLite::FieldType kValueFieldType, 48 WireFormatLite::FieldType kValueFieldType,
50 int default_enum_value> 49 int default_enum_value>
51 class MapFieldLite; 50 class MapFieldLite;
52 } // namespace internal 51 } // namespace internal
53 } // namespace protobuf 52 } // namespace protobuf
54 53
55 namespace protobuf { 54 namespace protobuf {
56 namespace internal { 55 namespace internal {
57 56
58 // MoveHelper::Move is used to set *dest. It copies *src, or moves it (in
59 // the C++11 sense), or swaps it. *src is left in a sane state for
60 // subsequent destruction, but shouldn't be used for anything.
61 template <bool is_enum, bool is_message, bool is_stringlike, typename T>
62 struct MoveHelper { // primitives
63 static void Move(T* src, T* dest) { *dest = *src; }
64 };
65
66 template <bool is_message, bool is_stringlike, typename T>
67 struct MoveHelper<true, is_message, is_stringlike, T> { // enums
68 static void Move(T* src, T* dest) { *dest = *src; }
69 // T is an enum here, so allow conversions to and from int.
70 static void Move(T* src, int* dest) { *dest = static_cast<int>(*src); }
71 static void Move(int* src, T* dest) { *dest = static_cast<T>(*src); }
72 };
73
74 template <bool is_stringlike, typename T>
75 struct MoveHelper<false, true, is_stringlike, T> { // messages
76 static void Move(T* src, T* dest) { dest->Swap(src); }
77 };
78
79 template <typename T>
80 struct MoveHelper<false, false, true, T> { // strings and similar
81 static void Move(T* src, T* dest) {
82 #if __cplusplus >= 201103L
83 *dest = std::move(*src);
84 #else
85 dest->swap(*src);
86 #endif
87 }
88 };
89
90 // MapEntryLite is used to implement parsing and serialization of map for lite 57 // MapEntryLite is used to implement parsing and serialization of map for lite
91 // runtime. 58 // runtime.
92 template <typename Key, typename Value, 59 template <typename Key, typename Value,
93 WireFormatLite::FieldType kKeyFieldType, 60 WireFormatLite::FieldType kKeyFieldType,
94 WireFormatLite::FieldType kValueFieldType, 61 WireFormatLite::FieldType kValueFieldType,
95 int default_enum_value> 62 int default_enum_value>
96 class MapEntryLite : public MessageLite { 63 class MapEntryLite : public MessageLite {
97 // Provide utilities to parse/serialize key/value. Provide utilities to 64 // Provide utilities to parse/serialize key/value. Provide utilities to
98 // manipulate internal stored type. 65 // manipulate internal stored type.
99 typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; 66 typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
(...skipping 12 matching lines...) Expand all
112 79
113 // Constants for field number. 80 // Constants for field number.
114 static const int kKeyFieldNumber = 1; 81 static const int kKeyFieldNumber = 1;
115 static const int kValueFieldNumber = 2; 82 static const int kValueFieldNumber = 2;
116 83
117 // Constants for field tag. 84 // Constants for field tag.
118 static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( 85 static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
119 kKeyFieldNumber, KeyTypeHandler::kWireType); 86 kKeyFieldNumber, KeyTypeHandler::kWireType);
120 static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( 87 static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
121 kValueFieldNumber, ValueTypeHandler::kWireType); 88 kValueFieldNumber, ValueTypeHandler::kWireType);
122 static const size_t kTagSize = 1; 89 static const int kTagSize = 1;
123 90
124 public: 91 public:
125 ~MapEntryLite() { 92 ~MapEntryLite() {
126 if (this != default_instance_) { 93 if (this != default_instance_) {
127 if (GetArenaNoVirtual() != NULL) return; 94 if (GetArenaNoVirtual() != NULL) return;
128 KeyTypeHandler::DeleteNoArena(key_); 95 KeyTypeHandler::DeleteNoArena(key_);
129 ValueTypeHandler::DeleteNoArena(value_); 96 ValueTypeHandler::DeleteNoArena(value_);
130 } 97 }
131 } 98 }
132 99
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 131
165 for (;;) { 132 for (;;) {
166 // 1) corrupted data: return false; 133 // 1) corrupted data: return false;
167 // 2) unknown field: skip without putting into unknown field set; 134 // 2) unknown field: skip without putting into unknown field set;
168 // 3) unknown enum value: keep it in parsing. In proto2, caller should 135 // 3) unknown enum value: keep it in parsing. In proto2, caller should
169 // check the value and put this entry into containing message's unknown 136 // check the value and put this entry into containing message's unknown
170 // field set if the value is an unknown enum. In proto3, caller doesn't 137 // field set if the value is an unknown enum. In proto3, caller doesn't
171 // need to care whether the value is unknown enum; 138 // need to care whether the value is unknown enum;
172 // 4) missing key/value: missed key/value will have default value. caller 139 // 4) missing key/value: missed key/value will have default value. caller
173 // should take this entry as if key/value is set to default value. 140 // should take this entry as if key/value is set to default value.
174 tag = input->ReadTagNoLastTag(); 141 tag = input->ReadTag();
175 switch (tag) { 142 switch (tag) {
176 case kKeyTag: 143 case kKeyTag:
177 if (!KeyTypeHandler::Read(input, mutable_key())) { 144 if (!KeyTypeHandler::Read(input, mutable_key())) {
178 return false; 145 return false;
179 } 146 }
180 set_has_key(); 147 set_has_key();
181 if (!input->ExpectTag(kValueTag)) break; 148 if (!input->ExpectTag(kValueTag)) break;
182 GOOGLE_FALLTHROUGH_INTENDED; 149 GOOGLE_FALLTHROUGH_INTENDED;
183 150
184 case kValueTag: 151 case kValueTag:
185 if (!ValueTypeHandler::Read(input, mutable_value())) { 152 if (!ValueTypeHandler::Read(input, mutable_value())) {
186 return false; 153 return false;
187 } 154 }
188 set_has_value(); 155 set_has_value();
189 if (input->ExpectAtEnd()) return true; 156 if (input->ExpectAtEnd()) return true;
190 break; 157 break;
191 158
192 default: 159 default:
193 if (tag == 0 || 160 if (tag == 0 ||
194 WireFormatLite::GetTagWireType(tag) == 161 WireFormatLite::GetTagWireType(tag) ==
195 WireFormatLite::WIRETYPE_END_GROUP) { 162 WireFormatLite::WIRETYPE_END_GROUP) {
196 return true; 163 return true;
197 } 164 }
198 if (!WireFormatLite::SkipField(input, tag)) return false; 165 if (!WireFormatLite::SkipField(input, tag)) return false;
199 break; 166 break;
200 } 167 }
201 } 168 }
202 } 169 }
203 170
204 size_t ByteSizeLong() const { 171 int ByteSize() const {
205 size_t size = 0; 172 int size = 0;
206 size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0; 173 size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0;
207 size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0; 174 size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0;
208 return size; 175 return size;
209 } 176 }
210 177
211 void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* outpu t) const { 178 void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* outpu t) const {
212 KeyTypeHandler::Write(kKeyFieldNumber, key(), output); 179 KeyTypeHandler::Write(kKeyFieldNumber, key(), output);
213 ValueTypeHandler::Write(kValueFieldNumber, value(), output); 180 ValueTypeHandler::Write(kValueFieldNumber, value(), output);
214 } 181 }
215 182
216 ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool determ inistic, 183 ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf: :uint8* output) const {
217 ::google::protobuf::uint8* ou tput) const { 184 output = KeyTypeHandler::WriteToArray(kKeyFieldNumber, key(), output);
218 output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(), 185 output = ValueTypeHandler::WriteToArray(kValueFieldNumber, value(), output);
219 deterministic, output);
220 output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(),
221 deterministic, output);
222 return output; 186 return output;
223 } 187 }
224 ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf: :uint8* output) const {
225 return InternalSerializeWithCachedSizesToArray(false, output);
226 }
227 188
228 int GetCachedSize() const { 189 int GetCachedSize() const {
229 int size = 0; 190 int size = 0;
230 size += has_key() 191 size += has_key()
231 ? kTagSize + KeyTypeHandler::GetCachedSize(key()) 192 ? kTagSize + KeyTypeHandler::GetCachedSize(key())
232 : 0; 193 : 0;
233 size += has_value() 194 size += has_value()
234 ? kTagSize + ValueTypeHandler::GetCachedSize( 195 ? kTagSize + ValueTypeHandler::GetCachedSize(
235 value()) 196 value())
236 : 0; 197 : 0;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 264
304 // Like above, but for all the other types. This avoids value copy to create 265 // Like above, but for all the other types. This avoids value copy to create
305 // MapEntryLite from google::protobuf::Map in serialization. 266 // MapEntryLite from google::protobuf::Map in serialization.
306 static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) { 267 static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) {
307 return Arena::CreateMessage<MapEntryWrapper<Key, Value, kKeyFieldType, 268 return Arena::CreateMessage<MapEntryWrapper<Key, Value, kKeyFieldType,
308 kValueFieldType, 269 kValueFieldType,
309 default_enum_value> >( 270 default_enum_value> >(
310 arena, key, value); 271 arena, key, value);
311 } 272 }
312 273
313 // Parsing using MergePartialFromCodedStream, above, is not as
314 // efficient as it could be. This helper class provides a speedier way.
315 template <typename MapField, typename Map>
316 class Parser {
317 public:
318 explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {}
319
320 // This does what the typical MergePartialFromCodedStream() is expected to
321 // do, with the additional side-effect that if successful (i.e., if true is
322 // going to be its return value) it inserts the key-value pair into map_.
323 bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* i nput) {
324 // Look for the expected thing: a key and then a value. If it fails,
325 // invoke the enclosing class's MergePartialFromCodedStream, or return
326 // false if that would be pointless.
327 if (input->ExpectTag(kKeyTag)) {
328 if (!KeyTypeHandler::Read(input, &key_)) {
329 return false;
330 }
331 // Peek at the next byte to see if it is kValueTag. If not, bail out.
332 const void* data;
333 int size;
334 input->GetDirectBufferPointerInline(&data, &size);
335 // We could use memcmp here, but we don't bother. The tag is one byte.
336 GOOGLE_COMPILE_ASSERT(kTagSize == 1, tag_size_error);
337 if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) {
338 typename Map::size_type size = map_->size();
339 value_ptr_ = &(*map_)[key_];
340 if (GOOGLE_PREDICT_TRUE(size != map_->size())) {
341 // We created a new key-value pair. Fill in the value.
342 typedef
343 typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T;
344 input->Skip(kTagSize); // Skip kValueTag.
345 if (!ValueTypeHandler::Read(input,
346 reinterpret_cast<T>(value_ptr_))) {
347 map_->erase(key_); // Failure! Undo insertion.
348 return false;
349 }
350 if (input->ExpectAtEnd()) return true;
351 return ReadBeyondKeyValuePair(input);
352 }
353 }
354 } else {
355 key_ = Key();
356 }
357
358 entry_.reset(mf_->NewEntry());
359 *entry_->mutable_key() = key_;
360 const bool result = entry_->MergePartialFromCodedStream(input);
361 if (result) UseKeyAndValueFromEntry();
362 if (entry_->GetArena() != NULL) entry_.release();
363 return result;
364 }
365
366 const Key& key() const { return key_; }
367 const Value& value() const { return *value_ptr_; }
368
369 private:
370 void UseKeyAndValueFromEntry() GOOGLE_ATTRIBUTE_COLD {
371 // Update key_ in case we need it later (because key() is called).
372 // This is potentially inefficient, especially if the key is
373 // expensive to copy (e.g., a long string), but this is a cold
374 // path, so it's not a big deal.
375 key_ = entry_->key();
376 value_ptr_ = &(*map_)[key_];
377 MoveHelper<ValueTypeHandler::kIsEnum,
378 ValueTypeHandler::kIsMessage,
379 ValueTypeHandler::kWireType ==
380 WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
381 Value>::Move(entry_->mutable_value(), value_ptr_);
382 }
383
384 // After reading a key and value successfully, and inserting that data
385 // into map_, we are not at the end of the input. This is unusual, but
386 // allowed by the spec.
387 bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input)
388 GOOGLE_ATTRIBUTE_COLD {
389 typedef MoveHelper<KeyTypeHandler::kIsEnum,
390 KeyTypeHandler::kIsMessage,
391 KeyTypeHandler::kWireType ==
392 WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
393 Key> KeyMover;
394 typedef MoveHelper<ValueTypeHandler::kIsEnum,
395 ValueTypeHandler::kIsMessage,
396 ValueTypeHandler::kWireType ==
397 WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
398 Value> ValueMover;
399 entry_.reset(mf_->NewEntry());
400 ValueMover::Move(value_ptr_, entry_->mutable_value());
401 map_->erase(key_);
402 KeyMover::Move(&key_, entry_->mutable_key());
403 const bool result = entry_->MergePartialFromCodedStream(input);
404 if (result) UseKeyAndValueFromEntry();
405 if (entry_->GetArena() != NULL) entry_.release();
406 return result;
407 }
408
409 MapField* const mf_;
410 Map* const map_;
411 Key key_;
412 Value* value_ptr_;
413 // On the fast path entry_ is not used. And, when entry_ is used, it's set
414 // to mf_->NewEntry(), so in the arena case we must call entry_.release.
415 google::protobuf::scoped_ptr<MapEntryLite> entry_;
416 };
417
418 protected: 274 protected:
419 void set_has_key() { _has_bits_[0] |= 0x00000001u; } 275 void set_has_key() { _has_bits_[0] |= 0x00000001u; }
420 bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; } 276 bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
421 void clear_has_key() { _has_bits_[0] &= ~0x00000001u; } 277 void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
422 void set_has_value() { _has_bits_[0] |= 0x00000002u; } 278 void set_has_value() { _has_bits_[0] |= 0x00000002u; }
423 bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; } 279 bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
424 void clear_has_value() { _has_bits_[0] &= ~0x00000002u; } 280 void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
425 281
426 private: 282 private:
427 // Serializing a generated message containing map field involves serializing 283 // Serializing a generated message containing map field involves serializing
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 template <typename K, typename V, WireFormatLite::FieldType, 387 template <typename K, typename V, WireFormatLite::FieldType,
532 WireFormatLite::FieldType, int> 388 WireFormatLite::FieldType, int>
533 friend class internal::MapEntry; 389 friend class internal::MapEntry;
534 template <typename K, typename V, WireFormatLite::FieldType, 390 template <typename K, typename V, WireFormatLite::FieldType,
535 WireFormatLite::FieldType, int> 391 WireFormatLite::FieldType, int>
536 friend class internal::MapFieldLite; 392 friend class internal::MapFieldLite;
537 393
538 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); 394 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
539 }; 395 };
540 396
541 // Helpers for deterministic serialization =============================
542
543 // This struct can be used with any generic sorting algorithm. If the Key
544 // type is relatively small and easy to copy then copying Keys into an
545 // array of SortItems can be beneficial. Then all the data the sorting
546 // algorithm needs to touch is in that one array.
547 template <typename Key, typename PtrToKeyValuePair> struct SortItem {
548 SortItem() {}
549 explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
550
551 Key first;
552 PtrToKeyValuePair second;
553 };
554
555 template <typename T> struct CompareByFirstField {
556 bool operator()(const T& a, const T& b) const {
557 return a.first < b.first;
558 }
559 };
560
561 template <typename T> struct CompareByDerefFirst {
562 bool operator()(const T& a, const T& b) const {
563 return a->first < b->first;
564 }
565 };
566
567 } // namespace internal 397 } // namespace internal
568 } // namespace protobuf 398 } // namespace protobuf
569 399
570 } // namespace google 400 } // namespace google
571 #endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ 401 #endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
OLDNEW
« no previous file with comments | « third_party/protobuf/src/google/protobuf/map_entry.h ('k') | third_party/protobuf/src/google/protobuf/map_field.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698