aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/generated_message_reflection.cc
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-06-25 19:05:36 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-06-25 19:05:36 +0000
commitceb561d65bfe234a301979a7e3f7ddc244d349b3 (patch)
tree8b86ec6fda6f7bcce0f214940dcaea5fb73c7d9f /src/google/protobuf/generated_message_reflection.cc
parentf22943c7d0ce19b35a1e3d7f33c8ede3b6fed485 (diff)
Add Swap(), SwapElements(), and RemoveLast() to Reflection. Patch by Scott Stafford.
Diffstat (limited to 'src/google/protobuf/generated_message_reflection.cc')
-rw-r--r--src/google/protobuf/generated_message_reflection.cc89
1 files changed, 87 insertions, 2 deletions
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index ffeaf62d..0cd367de 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -269,6 +269,61 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
return total_size;
}
+void GeneratedMessageReflection::Swap(
+ Message* message1,
+ Message* message2) const {
+ if (message1 == message2) return;
+
+ GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+ << "Tried to swap using reflection object incompatible with message1.";
+
+ GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+ << "Tried to swap using reflection object incompatible with message2.";
+
+ uint32* has_bits1 = MutableHasBits(message1);
+ uint32* has_bits2 = MutableHasBits(message2);
+ int has_bits_size = (descriptor_->field_count() + 31) / 32;
+
+ for (int i = 0; i < has_bits_size; i++) {
+ std::swap(has_bits1[i], has_bits2[i]);
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_repeated()) {
+ MutableRaw<GenericRepeatedField>(message1, field)->GenericSwap(
+ MutableRaw<GenericRepeatedField>(message2, field));
+ } else {
+ switch (field->cpp_type()) {
+#define SWAP_VALUES(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ swap(*MutableRaw<TYPE>(message1, field), \
+ *MutableRaw<TYPE>(message2, field)); \
+ break;
+ SWAP_VALUES(INT32 , int32 );
+ SWAP_VALUES(INT64 , int64 );
+ SWAP_VALUES(UINT32, uint32);
+ SWAP_VALUES(UINT64, uint64);
+ SWAP_VALUES(FLOAT , float );
+ SWAP_VALUES(DOUBLE, double);
+ SWAP_VALUES(BOOL , bool );
+ SWAP_VALUES(ENUM , int32 );
+ SWAP_VALUES(STRING, string*);
+ SWAP_VALUES(MESSAGE, Message*);
+#undef SWAP_PRIMITIVE_VALUES
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ }
+ }
+
+ if (extensions_offset_ != -1) {
+ MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
+ }
+
+ MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
+}
+
// -------------------------------------------------------------------
bool GeneratedMessageReflection::HasField(const Message& message,
@@ -285,8 +340,8 @@ bool GeneratedMessageReflection::HasField(const Message& message,
int GeneratedMessageReflection::FieldSize(const Message& message,
const FieldDescriptor* field) const {
- USAGE_CHECK_MESSAGE_TYPE(HasField);
- USAGE_CHECK_REPEATED(HasField);
+ USAGE_CHECK_MESSAGE_TYPE(FieldSize);
+ USAGE_CHECK_REPEATED(FieldSize);
if (field->is_extension()) {
return GetExtensionSet(message).ExtensionSize(field->number());
@@ -350,6 +405,36 @@ void GeneratedMessageReflection::ClearField(
}
}
+void GeneratedMessageReflection::RemoveLast(
+ Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
+ USAGE_CHECK_REPEATED(RemoveLast);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->RemoveLast(field->number());
+ } else {
+ MutableRaw<GenericRepeatedField>(message, field)->GenericRemoveLast();
+ }
+}
+
+void GeneratedMessageReflection::SwapElements(
+ Message* message,
+ const FieldDescriptor* field,
+ int index1,
+ int index2) const {
+ USAGE_CHECK_MESSAGE_TYPE(Swap);
+ USAGE_CHECK_REPEATED(Swap);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SwapElements(
+ field->number(), index1, index2);
+ } else {
+ MutableRaw<GenericRepeatedField>(message, field)->GenericSwapElements(
+ index1, index2);
+ }
+}
+
namespace {
// Comparison functor for sorting FieldDescriptors by field number.
struct FieldNumberSorter {