field_comparator.cc
Go to the documentation of this 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 
31 // Author: ksroka@google.com (Krzysztof Sroka)
32 
34 
35 #include <string>
36 
43 
44 namespace google {
45 namespace protobuf {
46 namespace util {
47 
50 
52  : float_comparison_(EXACT),
53  treat_nan_as_equal_(false),
54  has_default_tolerance_(false) {}
55 
57 
59  const Message& message_1, const Message& message_2,
60  const FieldDescriptor* field, int index_1, int index_2,
61  const util::FieldContext* field_context) {
62  const Reflection* reflection_1 = message_1.GetReflection();
63  const Reflection* reflection_2 = message_2.GetReflection();
64 
65  switch (field->cpp_type()) {
66 #define COMPARE_FIELD(METHOD) \
67  if (field->is_repeated()) { \
68  return ResultFromBoolean(Compare##METHOD( \
69  *field, reflection_1->GetRepeated##METHOD(message_1, field, index_1), \
70  reflection_2->GetRepeated##METHOD(message_2, field, index_2))); \
71  } else { \
72  return ResultFromBoolean( \
73  Compare##METHOD(*field, reflection_1->Get##METHOD(message_1, field), \
74  reflection_2->Get##METHOD(message_2, field))); \
75  } \
76  break; // Make sure no fall-through is introduced.
77 
91  if (field->is_repeated()) {
92  // Allocate scratch strings to store the result if a conversion is
93  // needed.
94  std::string scratch1;
95  std::string scratch2;
96  return ResultFromBoolean(
98  reflection_1->GetRepeatedStringReference(
99  message_1, field, index_1, &scratch1),
100  reflection_2->GetRepeatedStringReference(
101  message_2, field, index_2, &scratch2)));
102  } else {
103  // Allocate scratch strings to store the result if a conversion is
104  // needed.
105  std::string scratch1;
106  std::string scratch2;
108  *field,
109  reflection_1->GetStringReference(message_1, field, &scratch1),
110  reflection_2->GetStringReference(message_2, field, &scratch2)));
111  }
112  break;
117 
118 #undef COMPARE_FIELD
119 
121  return RECURSE;
122 
123  default:
124  GOOGLE_LOG(FATAL) << "No comparison code for field " << field->full_name()
125  << " of CppType = " << field->cpp_type();
126  return DIFFERENT;
127  }
128 }
129 
131  const Message& message1,
132  const Message& message2,
133  const util::FieldContext* field_context) {
134  return differencer->Compare(message1, message2,
135  field_context->parent_fields());
136 }
137 
139  double margin) {
140  default_tolerance_ = Tolerance(fraction, margin);
141  has_default_tolerance_ = true;
142 }
143 
145  double fraction,
146  double margin) {
148  FieldDescriptor::CPPTYPE_DOUBLE == field->cpp_type())
149  << "Field has to be float or double type. Field name is: "
150  << field->full_name();
151  map_tolerance_[field] = Tolerance(fraction, margin);
152 }
153 
155  double value_1, double value_2) {
156  return CompareDoubleOrFloat(field, value_1, value_2);
157 }
158 
160  const EnumValueDescriptor* value_1,
161  const EnumValueDescriptor* value_2) {
162  return value_1->number() == value_2->number();
163 }
164 
166  float value_1, float value_2) {
167  return CompareDoubleOrFloat(field, value_1, value_2);
168 }
169 
170 template <typename T>
172  T value_1, T value_2) {
173  if (value_1 == value_2) {
174  // Covers +inf and -inf (which are not within margin or fraction of
175  // themselves), and is a shortcut for finite values.
176  return true;
177  } else if (float_comparison_ == EXACT) {
178  if (treat_nan_as_equal_ && MathLimits<T>::IsNaN(value_1) &&
179  MathLimits<T>::IsNaN(value_2)) {
180  return true;
181  }
182  return false;
183  } else {
184  if (treat_nan_as_equal_ && MathLimits<T>::IsNaN(value_1) &&
185  MathLimits<T>::IsNaN(value_2)) {
186  return true;
187  }
188  // float_comparison_ == APPROXIMATE covers two use cases.
189  Tolerance* tolerance = FindOrNull(map_tolerance_, &field);
190  if (tolerance == NULL && has_default_tolerance_) {
191  tolerance = &default_tolerance_;
192  }
193  if (tolerance == NULL) {
194  return MathUtil::AlmostEquals(value_1, value_2);
195  } else {
196  // Use user-provided fraction and margin. Since they are stored as
197  // doubles, we explicitly cast them to types of values provided. This
198  // is very likely to fail if provided values are not numeric.
200  value_1, value_2, static_cast<T>(tolerance->fraction),
201  static_cast<T>(tolerance->margin));
202  }
203  }
204 }
205 
207  bool boolean_result) const {
208  return boolean_result ? FieldComparator::SAME : FieldComparator::DIFFERENT;
209 }
210 
211 } // namespace util
212 } // namespace protobuf
213 } // namespace google
Json::UInt64
unsigned long long int UInt64
Definition: json.h:241
google::protobuf::Reflection::GetStringReference
const std::string & GetStringReference(const Message &message, const FieldDescriptor *field, std::string *scratch) const
Definition: generated_message_reflection.cc:1171
google::protobuf::FieldDescriptor::CPPTYPE_ENUM
@ CPPTYPE_ENUM
Definition: src/google/protobuf/descriptor.h:561
map_util.h
google::protobuf::util::DefaultFieldComparator::CompareDouble
bool CompareDouble(const FieldDescriptor &field, double value_1, double value_2)
Definition: field_comparator.cc:154
google::protobuf::FieldDescriptor::CPPTYPE_STRING
@ CPPTYPE_STRING
Definition: src/google/protobuf/descriptor.h:562
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
google::protobuf::util::MessageDifferencer
Definition: message_differencer.h:120
google::protobuf::util::DefaultFieldComparator::ResultFromBoolean
ComparisonResult ResultFromBoolean(bool boolean_result) const
Definition: field_comparator.cc:206
NULL
NULL
Definition: test_security_zap.cpp:405
Bool
Definition: gtest_pred_impl_unittest.cc:56
google::protobuf::FieldDescriptor::CPPTYPE_UINT64
@ CPPTYPE_UINT64
Definition: src/google/protobuf/descriptor.h:557
FATAL
const int FATAL
Definition: log_severity.h:60
google::protobuf::MathUtil::WithinFractionOrMargin
static bool WithinFractionOrMargin(const T x, const T y, const T fraction, const T margin)
Definition: mathutil.h:115
google::protobuf::util::FieldComparator::~FieldComparator
virtual ~FieldComparator()
Definition: field_comparator.cc:49
google::protobuf::Reflection::GetRepeatedStringReference
const std::string & GetRepeatedStringReference(const Message &message, const FieldDescriptor *field, int index, std::string *scratch) const
Definition: generated_message_reflection.cc:1241
google::protobuf::Message::GetReflection
const Reflection * GetReflection() const
Definition: src/google/protobuf/message.h:335
message_differencer.h
google::protobuf::FieldDescriptor::CPPTYPE_INT64
@ CPPTYPE_INT64
Definition: src/google/protobuf/descriptor.h:555
google::protobuf::FieldDescriptor::CPPTYPE_UINT32
@ CPPTYPE_UINT32
Definition: src/google/protobuf/descriptor.h:556
google::protobuf::util::FieldComparator::DIFFERENT
@ DIFFERENT
Definition: field_comparator.h:68
google::protobuf::util::FieldComparator::RECURSE
@ RECURSE
Definition: field_comparator.h:71
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::util::DefaultFieldComparator::~DefaultFieldComparator
~DefaultFieldComparator() override
Definition: field_comparator.cc:56
google::protobuf::Reflection
Definition: src/google/protobuf/message.h:400
testing::internal::Int32
TypeWithSize< 4 >::Int Int32
Definition: gtest-port.h:2241
google::protobuf::util::FieldComparator::SAME
@ SAME
Definition: field_comparator.h:66
T
#define T(upbtypeconst, upbtype, ctype, default_value)
Enum
Definition: type.pb.h:797
google::protobuf::util::FieldContext
Definition: message_differencer.h:900
testing::internal::Double
FloatingPoint< double > Double
Definition: gtest-internal.h:429
testing::internal::UInt32
TypeWithSize< 4 >::UInt UInt32
Definition: gtest-port.h:2242
google::protobuf::util::DefaultFieldComparator::treat_nan_as_equal_
bool treat_nan_as_equal_
Definition: field_comparator.h:235
google::protobuf::util::DefaultFieldComparator::EXACT
@ EXACT
Definition: field_comparator.h:103
google::protobuf::MathLimits
Definition: mathlimits.h:78
google::protobuf::util::DefaultFieldComparator::Tolerance::margin
double margin
Definition: field_comparator.h:165
google::protobuf::FindOrNull
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:137
google::protobuf::util::DefaultFieldComparator::float_comparison_
FloatComparison float_comparison_
Definition: field_comparator.h:230
google::protobuf::util::DefaultFieldComparator::SetFractionAndMargin
void SetFractionAndMargin(const FieldDescriptor *field, double fraction, double margin)
Definition: field_comparator.cc:144
google::protobuf::util::DefaultFieldComparator::map_tolerance_
ToleranceMap map_tolerance_
Definition: field_comparator.h:249
testing::internal::Float
FloatingPoint< float > Float
Definition: gtest-internal.h:428
mathlimits.h
google::protobuf::util::MessageDifferencer::Compare
bool Compare(const Message &message1, const Message &message2)
Definition: message_differencer.cc:482
google::protobuf::EnumValueDescriptor::number
int number() const
message.h
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
mathutil.h
google::protobuf::util::FieldContext::parent_fields
std::vector< MessageDifferencer::SpecificField > * parent_fields() const
Definition: message_differencer.h:906
google::protobuf::util::DefaultFieldComparator::DefaultFieldComparator
DefaultFieldComparator()
Definition: field_comparator.cc:51
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::util::DefaultFieldComparator::default_tolerance_
Tolerance default_tolerance_
Definition: field_comparator.h:245
google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE
@ CPPTYPE_DOUBLE
Definition: src/google/protobuf/descriptor.h:558
google::protobuf::util::DefaultFieldComparator::CompareFloat
bool CompareFloat(const FieldDescriptor &field, float value_1, float value_2)
Definition: field_comparator.cc:165
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: logging.h:153
google::protobuf::util::DefaultFieldComparator::CompareEnum
bool CompareEnum(const FieldDescriptor &field, const EnumValueDescriptor *value_1, const EnumValueDescriptor *value_2)
Definition: field_comparator.cc:159
google::protobuf::FieldDescriptor::CPPTYPE_FLOAT
@ CPPTYPE_FLOAT
Definition: src/google/protobuf/descriptor.h:559
google::protobuf::util::DefaultFieldComparator::SetDefaultFractionAndMargin
void SetDefaultFractionAndMargin(double fraction, double margin)
Definition: field_comparator.cc:138
google::protobuf::FieldDescriptor::CPPTYPE_BOOL
@ CPPTYPE_BOOL
Definition: src/google/protobuf/descriptor.h:560
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::MathUtil::AlmostEquals
static bool AlmostEquals(T a, T b)
Definition: mathutil.h:69
field_comparator.h
google::protobuf::EnumValueDescriptor
Definition: src/google/protobuf/descriptor.h:1075
descriptor.h
google::protobuf::util::DefaultFieldComparator::Tolerance::fraction
double fraction
Definition: field_comparator.h:164
google::protobuf::util::DefaultFieldComparator::Compare
ComparisonResult Compare(const Message &message_1, const Message &message_2, const FieldDescriptor *field, int index_1, int index_2, const util::FieldContext *field_context) override
Definition: field_comparator.cc:58
google::protobuf::util::FieldComparator::ComparisonResult
ComparisonResult
Definition: field_comparator.h:65
google::protobuf::util::DefaultFieldComparator::CompareDoubleOrFloat
bool CompareDoubleOrFloat(const FieldDescriptor &field, T value_1, T value_2)
Definition: field_comparator.cc:171
google::protobuf::util::FieldComparator::FieldComparator
FieldComparator()
Definition: field_comparator.cc:48
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: src/google/protobuf/descriptor.h:563
google::protobuf::FieldDescriptor::CPPTYPE_INT32
@ CPPTYPE_INT32
Definition: src/google/protobuf/descriptor.h:554
false
#define false
Definition: cJSON.c:70
google::protobuf::util::DefaultFieldComparator::has_default_tolerance_
bool has_default_tolerance_
Definition: field_comparator.h:241
google::protobuf::util::DefaultFieldComparator::Tolerance
Definition: field_comparator.h:163
Json::Int64
long long int Int64
Definition: json.h:240
google::protobuf::util::DefaultFieldComparator::CompareString
bool CompareString(const FieldDescriptor &, const std::string &value_1, const std::string &value_2)
Definition: field_comparator.h:205
google
Definition: data_proto2_to_proto3_util.h:11
COMPARE_FIELD
#define COMPARE_FIELD(METHOD)


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:51