~ubuntu-branches/debian/squeeze/protobuf/squeeze

« back to all changes in this revision

Viewing changes to src/google/protobuf/extension_set.cc

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-06-02 16:19:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090602161900-vm176i3ryt35yk91
Tags: 2.0.3-2.2
* Non-maintainer upload.
* Fix FTBFS from -2.1: don't fail when we can't clean up the java build,
  such as when openjdk isn't installed.
* Disable parallel builds, because libtool is made of fail (if binary-arch
  and build-indep run concurrently, we relink a library while it's being
  used; that doesn't work so well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/
4
4
//
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
8
 
//
9
 
//      http://www.apache.org/licenses/LICENSE-2.0
10
 
//
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
 
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.
16
30
 
17
31
// Author: kenton@google.com (Kenton Varda)
18
32
//  Based on original Protocol Buffers design by
26
40
#include <google/protobuf/io/coded_stream.h>
27
41
#include <google/protobuf/wire_format.h>
28
42
#include <google/protobuf/repeated_field.h>
 
43
#include <google/protobuf/generated_message_reflection.h>
29
44
 
30
45
namespace google {
31
46
namespace protobuf {
35
50
// Lookup functions
36
51
 
37
52
const FieldDescriptor*
38
 
ExtensionSet::FindKnownExtensionByName(const string& name) const {
39
 
  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
40
 
  if (result != NULL && result->containing_type() == extendee_) {
41
 
    return result;
42
 
  }
43
 
 
44
 
  if (extendee_->options().message_set_wire_format()) {
45
 
    // MessageSet extensions may be identified by type name.
46
 
    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
47
 
    if (type != NULL) {
48
 
      // Look for a matching extension in the foreign type's scope.
49
 
      for (int i = 0; i < type->extension_count(); i++) {
50
 
        const FieldDescriptor* extension = type->extension(i);
51
 
        if (extension->containing_type() == extendee_ &&
52
 
            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
53
 
            extension->is_optional() &&
54
 
            extension->message_type() == type) {
55
 
          // Found it.
56
 
          return extension;
57
 
        }
58
 
      }
59
 
    }
60
 
  }
61
 
 
62
 
  return NULL;
63
 
}
64
 
 
65
 
const FieldDescriptor*
66
 
ExtensionSet::FindKnownExtensionByNumber(int number) const {
67
 
  return descriptor_pool_->FindExtensionByNumber(extendee_, number);
68
 
}
69
 
 
70
 
const FieldDescriptor*
71
53
ExtensionSet::FindKnownExtensionOrDie(int number) const {
72
 
  const FieldDescriptor* descriptor = FindKnownExtensionByNumber(number);
 
54
  const FieldDescriptor* descriptor =
 
55
    descriptor_pool_->FindExtensionByNumber(*extendee_, number);
73
56
  if (descriptor == NULL) {
74
57
    // This extension doesn't exist, so we have to crash.  However, let's
75
58
    // try to provide an informative error message.
77
60
        message_factory_ == MessageFactory::generated_factory()) {
78
61
      // This is probably the ExtensionSet for a generated class.
79
62
      GOOGLE_LOG(FATAL) << ": No extension is registered for \""
80
 
                 << extendee_->full_name() << "\" with number "
 
63
                 << (*extendee_)->full_name() << "\" with number "
81
64
                 << number << ".  Perhaps you were trying to access it via "
82
65
                    "the Reflection interface, but you provided a "
83
66
                    "FieldDescriptor which did not come from a linked-in "
87
70
    } else {
88
71
      // This is probably a DynamicMessage.
89
72
      GOOGLE_LOG(FATAL) << ": No extension is registered for \""
90
 
                 << extendee_->full_name() << "\" with number "
 
73
                 << (*extendee_)->full_name() << "\" with number "
91
74
                 << number << ".  If you were using a DynamicMessage, "
92
75
                    "remember that you are only allowed to access extensions "
93
76
                    "which are defined in the DescriptorPool which you passed "
105
88
// ===================================================================
106
89
// Constructors and basic methods.
107
90
 
108
 
ExtensionSet::ExtensionSet(const Descriptor* extendee,
 
91
ExtensionSet::ExtensionSet(const Descriptor* const* extendee,
109
92
                           const DescriptorPool* pool,
110
93
                           MessageFactory* factory)
111
94
  : extendee_(extendee),
461
444
}  // namespace
462
445
 
463
446
void ExtensionSet::MergeFrom(const ExtensionSet& other) {
464
 
  GOOGLE_DCHECK_EQ(extendee_, other.extendee_);
 
447
  GOOGLE_DCHECK_EQ(*extendee_, *other.extendee_);
465
448
 
466
449
  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
467
450
       iter != other.extensions_.end(); ++iter) {
533
516
  }
534
517
}
535
518
 
 
519
void ExtensionSet::Swap(ExtensionSet* x) {
 
520
  extensions_.swap(x->extensions_);
 
521
  std::swap(extendee_, x->extendee_);
 
522
  std::swap(descriptor_pool_, x->descriptor_pool_);
 
523
  std::swap(message_factory_, x->message_factory_);
 
524
}
 
525
 
536
526
bool ExtensionSet::IsInitialized() const {
537
527
  // Extensions are never requried.  However, we need to check that all
538
528
  // embedded messages are initialized.
558
548
}
559
549
 
560
550
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
561
 
                              Message::Reflection* reflection) {
 
551
                              Message* message) {
562
552
  const FieldDescriptor* field =
563
 
    FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
 
553
    message->GetReflection()
 
554
           ->FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
564
555
 
565
 
  return WireFormat::ParseAndMergeField(tag, field, reflection, input);
 
556
  return WireFormat::ParseAndMergeField(tag, field, message, input);
566
557
}
567
558
 
568
559
bool ExtensionSet::SerializeWithCachedSizes(
569
560
    int start_field_number, int end_field_number,
570
 
    const Message::Reflection* reflection,
 
561
    const Message& message,
571
562
    io::CodedOutputStream* output) const {
572
563
  map<int, Extension>::const_iterator iter;
573
564
  for (iter = extensions_.lower_bound(start_field_number);
574
565
       iter != extensions_.end() && iter->first < end_field_number;
575
566
       ++iter) {
576
 
    if (!iter->second.SerializeFieldWithCachedSizes(reflection, output)) {
 
567
    if (!iter->second.SerializeFieldWithCachedSizes(message, output)) {
577
568
      return false;
578
569
    }
579
570
  }
581
572
  return true;
582
573
}
583
574
 
584
 
int ExtensionSet::ByteSize(const Message::Reflection* reflection) const {
 
575
int ExtensionSet::ByteSize(const Message& message) const {
585
576
  int total_size = 0;
586
577
 
587
578
  for (map<int, Extension>::const_iterator iter = extensions_.begin();
588
579
       iter != extensions_.end(); ++iter) {
589
 
    total_size += iter->second.ByteSize(reflection);
590
 
  }
591
 
 
 
580
    total_size += iter->second.ByteSize(message);
 
581
  }
 
582
 
 
583
  return total_size;
 
584
}
 
585
 
 
586
int ExtensionSet::SpaceUsedExcludingSelf() const {
 
587
  int total_size =
 
588
      extensions_.size() * sizeof(map<int, Extension>::value_type);
 
589
  for (map<int, Extension>::const_iterator iter = extensions_.begin(),
 
590
       end = extensions_.end();
 
591
       iter != end;
 
592
       ++iter) {
 
593
    total_size += iter->second.SpaceUsedExcludingSelf();
 
594
  }
592
595
  return total_size;
593
596
}
594
597
 
652
655
}
653
656
 
654
657
bool ExtensionSet::Extension::SerializeFieldWithCachedSizes(
655
 
    const Message::Reflection* reflection,
 
658
    const Message& message,
656
659
    io::CodedOutputStream* output) const {
657
660
  if (descriptor->is_repeated() || !is_cleared) {
658
661
    return WireFormat::SerializeFieldWithCachedSizes(
659
 
        descriptor, reflection, output);
 
662
      descriptor, message, output);
660
663
  } else {
661
664
    return true;
662
665
  }
663
666
}
664
667
 
665
 
int64 ExtensionSet::Extension::ByteSize(
666
 
    const Message::Reflection* reflection) const {
 
668
int64 ExtensionSet::Extension::ByteSize(const Message& message) const {
667
669
  if (descriptor->is_repeated() || !is_cleared) {
668
 
    return WireFormat::FieldByteSize(descriptor, reflection);
 
670
    return WireFormat::FieldByteSize(descriptor, message);
669
671
  } else {
670
672
    // Cleared, non-repeated field.
671
673
    return 0;
730
732
  }
731
733
}
732
734
 
 
735
int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
 
736
  int total_size = 0;
 
737
  if (descriptor->is_repeated()) {
 
738
    switch (descriptor->cpp_type()) {
 
739
#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
 
740
      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
 
741
        total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
 
742
            repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
 
743
        break
 
744
 
 
745
      HANDLE_TYPE(  INT32,   int32);
 
746
      HANDLE_TYPE(  INT64,   int64);
 
747
      HANDLE_TYPE( UINT32,  uint32);
 
748
      HANDLE_TYPE( UINT64,  uint64);
 
749
      HANDLE_TYPE(  FLOAT,   float);
 
750
      HANDLE_TYPE( DOUBLE,  double);
 
751
      HANDLE_TYPE(   BOOL,    bool);
 
752
      HANDLE_TYPE(   ENUM,    enum);
 
753
      HANDLE_TYPE( STRING,  string);
 
754
      HANDLE_TYPE(MESSAGE, message);
 
755
    }
 
756
  } else {
 
757
    switch (descriptor->cpp_type()) {
 
758
      case FieldDescriptor::CPPTYPE_STRING:
 
759
        total_size += sizeof(*string_value) +
 
760
                      StringSpaceUsedExcludingSelf(*string_value);
 
761
        break;
 
762
      case FieldDescriptor::CPPTYPE_MESSAGE:
 
763
        total_size += message_value->SpaceUsed();
 
764
        break;
 
765
      default:
 
766
        // No extra storage costs for primitive types.
 
767
        break;
 
768
    }
 
769
  }
 
770
  return total_size;
 
771
}
 
772
 
733
773
}  // namespace internal
734
774
}  // namespace protobuf
735
775
}  // namespace google