1
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.
2
// Copyright 2008 Google Inc. All rights reserved.
3
3
// http://code.google.com/p/protobuf/
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
9
// http://www.apache.org/licenses/LICENSE-2.0
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.
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
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
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.
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.
17
31
// Author: kenton@google.com (Kenton Varda)
18
32
// Based on original Protocol Buffers design by
300
316
// ===================================================================
302
bool WireFormat::ParseAndMergePartial(const Descriptor* descriptor,
303
io::CodedInputStream* input,
304
Message::Reflection* message_reflection) {
318
bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
320
const Descriptor* descriptor = message->GetDescriptor();
321
const Reflection* message_reflection = message->GetReflection();
306
324
uint32 tag = input->ReadTag();
330
348
if (field == NULL &&
331
349
descriptor->options().message_set_wire_format() &&
332
350
tag == kMessageSetItemStartTag) {
333
if (!ParseAndMergeMessageSetItem(input, message_reflection)) {
351
if (!ParseAndMergeMessageSetItem(input, message)) {
336
354
continue; // Skip ParseAndMergeField(); already taken care of.
340
if (!ParseAndMergeField(tag, field, message_reflection, input)) {
358
if (!ParseAndMergeField(tag, field, message, input)) {
346
364
bool WireFormat::ParseAndMergeField(
348
366
const FieldDescriptor* field, // May be NULL for unknown
349
Message::Reflection* message_reflection,
350
368
io::CodedInputStream* input) {
369
const Reflection* message_reflection = message->GetReflection();
351
371
if (field == NULL ||
352
372
GetTagWireType(tag) != WireTypeForFieldType(field->type())) {
353
373
// We don't recognize this field. Either the field number is unknown
354
374
// or the wire type doesn't match. Put it in our unknown field set.
355
return SkipField(input, tag, message_reflection->MutableUnknownFields());
375
return SkipField(input, tag,
376
message_reflection->MutableUnknownFields(message));
358
379
switch (field->type()) {
362
383
if (!Read##TYPE_METHOD(input, &value)) return false; \
363
384
if (field->is_repeated()) { \
364
message_reflection->Add##CPPTYPE_METHOD(field, value); \
385
message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
366
message_reflection->Set##CPPTYPE_METHOD(field, value); \
387
message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
397
418
field->enum_type()->FindValueByNumber(value);
398
419
if (enum_value != NULL) {
399
420
if (field->is_repeated()) {
400
message_reflection->AddEnum(field, enum_value);
421
message_reflection->AddEnum(message, field, enum_value);
402
message_reflection->SetEnum(field, enum_value);
423
message_reflection->SetEnum(message, field, enum_value);
405
426
// The enum value is not one of the known values. Add it to the
406
427
// UnknownFieldSet.
407
428
int64 sign_extended_value = static_cast<int64>(value);
408
message_reflection->MutableUnknownFields()
429
message_reflection->MutableUnknownFields(message)
409
430
->AddField(GetTagFieldNumber(tag))
410
431
->add_varint(sign_extended_value);
416
437
case FieldDescriptor::TYPE_GROUP: {
417
438
Message* sub_message;
418
439
if (field->is_repeated()) {
419
sub_message = message_reflection->AddMessage(field);
440
sub_message = message_reflection->AddMessage(message, field);
421
sub_message = message_reflection->MutableMessage(field);
442
sub_message = message_reflection->MutableMessage(message, field);
424
445
if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) return false;
428
449
case FieldDescriptor::TYPE_MESSAGE: {
429
450
Message* sub_message;
430
451
if (field->is_repeated()) {
431
sub_message = message_reflection->AddMessage(field);
452
sub_message = message_reflection->AddMessage(message, field);
433
sub_message = message_reflection->MutableMessage(field);
454
sub_message = message_reflection->MutableMessage(message, field);
436
457
if (!ReadMessage(input, sub_message)) return false;
444
465
bool WireFormat::ParseAndMergeMessageSetItem(
445
466
io::CodedInputStream* input,
446
Message::Reflection* message_reflection) {
468
const Reflection* message_reflection = message->GetReflection();
447
470
// This method parses a group which should contain two fields:
448
471
// required int32 type_id = 2;
449
472
// required data message = 3;
481
504
io::ArrayInputStream raw_input(message_data.data(),
482
505
message_data.size());
483
506
io::CodedInputStream sub_input(&raw_input);
484
if (!ParseAndMergeField(fake_tag, field, message_reflection,
507
if (!ParseAndMergeField(fake_tag, field, message,
501
524
message_data.append(temp);
503
526
// Already saw type_id, so we can parse this directly.
504
if (!ParseAndMergeField(fake_tag, field, message_reflection, input)) {
527
if (!ParseAndMergeField(fake_tag, field, message, input)) {
523
546
// ===================================================================
525
548
bool WireFormat::SerializeWithCachedSizes(
526
const Descriptor* descriptor,
527
const Message::Reflection* message_reflection,
549
const Message& message,
528
550
int size, io::CodedOutputStream* output) {
551
const Descriptor* descriptor = message.GetDescriptor();
552
const Reflection* message_reflection = message.GetReflection();
529
553
int expected_endpoint = output->ByteCount() + size;
531
555
vector<const FieldDescriptor*> fields;
532
message_reflection->ListFields(&fields);
556
message_reflection->ListFields(message, &fields);
533
557
for (int i = 0; i < fields.size(); i++) {
534
if (!SerializeFieldWithCachedSizes(fields[i], message_reflection, output)) {
558
if (!SerializeFieldWithCachedSizes(fields[i], message, output)) {
539
563
if (descriptor->options().message_set_wire_format()) {
540
564
if (!SerializeUnknownMessageSetItems(
541
message_reflection->GetUnknownFields(), output)) {
565
message_reflection->GetUnknownFields(message), output)) {
545
569
if (!SerializeUnknownFields(
546
message_reflection->GetUnknownFields(), output)) {
570
message_reflection->GetUnknownFields(message), output)) {
559
583
bool WireFormat::SerializeFieldWithCachedSizes(
560
584
const FieldDescriptor* field,
561
const Message::Reflection* message_reflection,
585
const Message& message,
562
586
io::CodedOutputStream* output) {
587
const Reflection* message_reflection = message.GetReflection();
563
589
if (field->is_extension() &&
564
590
field->containing_type()->options().message_set_wire_format() &&
565
591
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
566
592
!field->is_repeated()) {
567
593
return SerializeMessageSetItemWithCachedSizes(
568
field, message_reflection, output);
594
field, message, output);
573
599
if (field->is_repeated()) {
574
count = message_reflection->FieldSize(field);
575
} else if (message_reflection->HasField(field)) {
600
count = message_reflection->FieldSize(message, field);
601
} else if (message_reflection->HasField(message, field)) {
583
609
if (!Write##TYPE_METHOD( \
584
610
field->number(), \
585
611
field->is_repeated() ? \
586
message_reflection->GetRepeated##CPPTYPE_METHOD(field, j) : \
587
message_reflection->Get##CPPTYPE_METHOD(field), \
612
message_reflection->GetRepeated##CPPTYPE_METHOD( \
613
message, field, j) : \
614
message_reflection->Get##CPPTYPE_METHOD(message, field), \
614
641
case FieldDescriptor::TYPE_ENUM: {
615
642
const EnumValueDescriptor* value = field->is_repeated() ?
616
message_reflection->GetRepeatedEnum(field, j) :
617
message_reflection->GetEnum(field);
643
message_reflection->GetRepeatedEnum(message, field, j) :
644
message_reflection->GetEnum(message, field);
618
645
if (!WriteEnum(field->number(), value->number(), output)) return false;
622
649
// Handle strings separately so that we can get string references
623
650
// instead of copying.
624
case FieldDescriptor::TYPE_STRING:
651
case FieldDescriptor::TYPE_STRING: {
653
const string& value = field->is_repeated() ?
654
message_reflection->GetRepeatedStringReference(
655
message, field, j, &scratch) :
656
message_reflection->GetStringReference(message, field, &scratch);
657
if (!WriteString(field->number(), value, output)) return false;
625
661
case FieldDescriptor::TYPE_BYTES: {
627
663
const string& value = field->is_repeated() ?
628
message_reflection->GetRepeatedStringReference(field, j, &scratch) :
629
message_reflection->GetStringReference(field, &scratch);
630
if (!WriteString(field->number(), value, output)) return false;
664
message_reflection->GetRepeatedStringReference(
665
message, field, j, &scratch) :
666
message_reflection->GetStringReference(message, field, &scratch);
667
if (!WriteBytes(field->number(), value, output)) return false;
639
676
bool WireFormat::SerializeMessageSetItemWithCachedSizes(
640
677
const FieldDescriptor* field,
641
const Message::Reflection* message_reflection,
678
const Message& message,
642
679
io::CodedOutputStream* output) {
680
const Reflection* message_reflection = message.GetReflection();
644
683
if (!output->WriteVarint32(kMessageSetItemStartTag)) return false;
663
702
// ===================================================================
665
int WireFormat::ByteSize(
666
const Descriptor* descriptor,
667
const Message::Reflection* message_reflection) {
704
int WireFormat::ByteSize(const Message& message) {
705
const Descriptor* descriptor = message.GetDescriptor();
706
const Reflection* message_reflection = message.GetReflection();
668
708
int our_size = 0;
670
710
vector<const FieldDescriptor*> fields;
671
message_reflection->ListFields(&fields);
711
message_reflection->ListFields(message, &fields);
672
712
for (int i = 0; i < fields.size(); i++) {
673
our_size += FieldByteSize(fields[i], message_reflection);
713
our_size += FieldByteSize(fields[i], message);
676
716
if (descriptor->options().message_set_wire_format()) {
677
717
our_size += ComputeUnknownMessageSetItemsSize(
678
message_reflection->GetUnknownFields());
718
message_reflection->GetUnknownFields(message));
680
720
our_size += ComputeUnknownFieldsSize(
681
message_reflection->GetUnknownFields());
721
message_reflection->GetUnknownFields(message));
687
727
int WireFormat::FieldByteSize(
688
728
const FieldDescriptor* field,
689
const Message::Reflection* message_reflection) {
729
const Message& message) {
730
const Reflection* message_reflection = message.GetReflection();
690
732
if (field->is_extension() &&
691
733
field->containing_type()->options().message_set_wire_format() &&
692
734
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
693
735
!field->is_repeated()) {
694
return MessageSetItemByteSize(field, message_reflection);
736
return MessageSetItemByteSize(field, message);
697
739
int our_size = 0;
712
754
if (field->is_repeated()) { \
713
755
for (int j = 0; j < count; j++) { \
714
756
our_size += TYPE_METHOD##Size( \
715
message_reflection->GetRepeated##CPPTYPE_METHOD(field, j)); \
757
message_reflection->GetRepeated##CPPTYPE_METHOD( \
758
message, field, j)); \
718
761
our_size += TYPE_METHOD##Size( \
719
message_reflection->Get##CPPTYPE_METHOD(field)); \
762
message_reflection->Get##CPPTYPE_METHOD(message, field)); \
751
794
if (field->is_repeated()) {
752
795
for (int j = 0; j < count; j++) {
753
796
our_size += EnumSize(
754
message_reflection->GetRepeatedEnum(field, j)->number());
797
message_reflection->GetRepeatedEnum(message, field, j)->number());
757
800
our_size += EnumSize(
758
message_reflection->GetEnum(field)->number());
801
message_reflection->GetEnum(message, field)->number());
767
810
for (int j = 0; j < count; j++) {
769
812
const string& value = field->is_repeated() ?
770
message_reflection->GetRepeatedStringReference(field, j, &scratch) :
771
message_reflection->GetStringReference(field, &scratch);
813
message_reflection->GetRepeatedStringReference(
814
message, field, j, &scratch) :
815
message_reflection->GetStringReference(message, field, &scratch);
772
816
our_size += StringSize(value);
781
825
int WireFormat::MessageSetItemByteSize(
782
826
const FieldDescriptor* field,
783
const Message::Reflection* message_reflection) {
827
const Message& message) {
828
const Reflection* message_reflection = message.GetReflection();
784
830
int our_size = kMessageSetItemTagsSize;
787
833
our_size += io::CodedOutputStream::VarintSize32(field->number());
790
const Message& sub_message = message_reflection->GetMessage(field);
836
const Message& sub_message = message_reflection->GetMessage(message, field);
791
837
int message_size = sub_message.ByteSize();
793
839
our_size += io::CodedOutputStream::VarintSize32(message_size);