webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
field_comparator.h
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 
33 #ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
34 #define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
35 
36 #include <map>
37 #include <string>
38 
40 
41 namespace google {
42 namespace protobuf {
43 
44 class Message;
45 class EnumValueDescriptor;
46 class FieldDescriptor;
47 
48 namespace util {
49 
50 class FieldContext;
51 
52 // Base class specifying the interface for comparing protocol buffer fields.
53 // Regular users should consider using or subclassing DefaultFieldComparator
54 // rather than this interface.
55 // Currently, this does not support comparing unknown fields.
57  public:
59  virtual ~FieldComparator();
60 
62  SAME, // Compared fields are equal. In case of comparing submessages,
63  // user should not recursively compare their contents.
64  DIFFERENT, // Compared fields are different. In case of comparing
65  // submessages, user should not recursively compare their
66  // contents.
67  RECURSE, // Compared submessages need to be compared recursively.
68  // FieldComparator does not specify the semantics of recursive
69  // comparison. This value should not be returned for simple
70  // values.
71  };
72 
73  // Compares the values of a field in two protocol buffer messages.
74  // Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE
75  // for submessages. Returning RECURSE for fields not being submessages is
76  // illegal.
77  // In case the given FieldDescriptor points to a repeated field, the indices
78  // need to be valid. Otherwise they should be ignored.
79  //
80  // FieldContext contains information about the specific instances of the
81  // fields being compared, versus FieldDescriptor which only contains general
82  // type information about the fields.
83  virtual ComparisonResult Compare(
84  const google::protobuf::Message& message_1,
85  const google::protobuf::Message& message_2,
87  int index_1, int index_2,
88  const google::protobuf::util::FieldContext* field_context) = 0;
89 
90  private:
92 };
93 
94 // Basic implementation of FieldComparator. Supports three modes of floating
95 // point value comparison: exact, approximate using MathUtil::AlmostEqual
96 // method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.
98  public:
100  EXACT, // Floats and doubles are compared exactly.
101  APPROXIMATE, // Floats and doubles are compared using the
102  // MathUtil::AlmostEqual method or
103  // MathUtil::WithinFractionOrMargin method.
104  // TODO(ksroka): Introduce third value to differenciate uses of AlmostEqual
105  // and WithinFractionOrMargin.
106  };
107 
108  // Creates new comparator with float comparison set to EXACT.
110 
111  virtual ~DefaultFieldComparator();
112 
113  virtual ComparisonResult Compare(
114  const google::protobuf::Message& message_1,
115  const google::protobuf::Message& message_2,
117  int index_1, int index_2,
118  const google::protobuf::util::FieldContext* field_context);
119 
120  void set_float_comparison(FloatComparison float_comparison) {
121  float_comparison_ = float_comparison;
122  }
123 
125  return float_comparison_;
126  }
127 
128  // Set whether the FieldComparator shall treat floats or doubles that are both
129  // NaN as equal (treat_nan_as_equal = true) or as different
130  // (treat_nan_as_equal = false). Default is treating NaNs always as different.
131  void set_treat_nan_as_equal(bool treat_nan_as_equal) {
132  treat_nan_as_equal_ = treat_nan_as_equal;
133  }
134 
135  bool treat_nan_as_equal() const {
136  return treat_nan_as_equal_;
137  }
138 
139  // Sets the fraction and margin for the float comparison of a given field.
140  // Uses MathUtil::WithinFractionOrMargin to compare the values.
141  //
142  // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
143  // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
144  // REQUIRES: float_comparison_ == APPROXIMATE
145  void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
146  double margin);
147 
148  // Sets the fraction and margin for the float comparison of all float and
149  // double fields, unless a field has been given a specific setting via
150  // SetFractionAndMargin() above.
151  // Uses MathUtil::WithinFractionOrMargin to compare the values.
152  //
153  // REQUIRES: float_comparison_ == APPROXIMATE
154  void SetDefaultFractionAndMargin(double fraction, double margin);
155 
156  private:
157  // Defines the tolerance for floating point comparison (fraction and margin).
158  struct Tolerance {
159  double fraction;
160  double margin;
161  Tolerance()
162  : fraction(0.0),
163  margin(0.0) {}
164  Tolerance(double f, double m)
165  : fraction(f),
166  margin(m) {}
167  };
168 
169  // Defines the map to store the tolerances for floating point comparison.
170  typedef map<const FieldDescriptor*, Tolerance> ToleranceMap;
171 
172  // The following methods get executed when CompareFields is called for the
173  // basic types (instead of submessages). They return true on success. One
174  // can use ResultFromBoolean() to convert that boolean to a ComparisonResult
175  // value.
176  bool CompareBool(const google::protobuf::FieldDescriptor& field,
177  bool value_1, bool value_2) {
178  return value_1 == value_2;
179  }
180 
181  // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
182  // CompareFloat.
184  double value_1, double value_2);
185 
186  bool CompareEnum(const google::protobuf::FieldDescriptor& field,
187  const EnumValueDescriptor* value_1,
188  const EnumValueDescriptor* value_2);
189 
190  // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
191  // CompareFloat.
193  float value_1, float value_2);
194 
195  bool CompareInt32(const google::protobuf::FieldDescriptor& field,
196  int32 value_1, int32 value_2) {
197  return value_1 == value_2;
198  }
199 
200  bool CompareInt64(const google::protobuf::FieldDescriptor& field,
201  int64 value_1, int64 value_2) {
202  return value_1 == value_2;
203  }
204 
205  bool CompareString(const google::protobuf::FieldDescriptor& field,
206  const string& value_1, const string& value_2) {
207  return value_1 == value_2;
208  }
209 
210  bool CompareUInt32(const google::protobuf::FieldDescriptor& field,
211  uint32 value_1, uint32 value_2) {
212  return value_1 == value_2;
213  }
214 
215  bool CompareUInt64(const google::protobuf::FieldDescriptor& field,
216  uint64 value_1, uint64 value_2) {
217  return value_1 == value_2;
218  }
219 
220  // This function is used by CompareDouble and CompareFloat to avoid code
221  // duplication. There are no checks done against types of the values passed,
222  // but it's likely to fail if passed non-numeric arguments.
223  template<typename T>
224  bool CompareDoubleOrFloat(const google::protobuf::FieldDescriptor& field,
225  T value_1, T value_2);
226 
227  // Returns FieldComparator::SAME if boolean_result is true and
228  // FieldComparator::DIFFERENT otherwise.
229  ComparisonResult ResultFromBoolean(bool boolean_result) const;
230 
231  FloatComparison float_comparison_;
232 
233  // If true, floats and doubles that are both NaN are considered to be
234  // equal. Otherwise, two floats or doubles that are NaN are considered to be
235  // different.
236  bool treat_nan_as_equal_;
237 
238  // True iff default_tolerance_ has been explicitly set.
239  //
240  // If false, then the default tolerance for flaots and doubles is that which
241  // is used by MathUtil::AlmostEquals().
242  bool has_default_tolerance_;
243 
244  // Default float/double tolerance. Only meaningful if
245  // has_default_tolerance_ == true.
246  Tolerance default_tolerance_;
247 
248  // Field-specific float/double tolerances, which override any default for
249  // those particular fields.
250  ToleranceMap map_tolerance_;
251 
253 };
254 
255 } // namespace util
256 } // namespace protobuf
257 
258 } // namespace google
259 #endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
FloatComparison float_comparison() const
Definition: field_comparator.h:124
Definition: message.h:179
Definition: util.py:1
const FieldDescriptor * field
Definition: parser_unittest.cc:2279
Definition: field_comparator.h:56
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: macros.h:40
const GLfloat * m
Definition: gl2ext.h:850
Message
Definition: peerconnection_unittest.cc:105
void set_float_comparison(FloatComparison float_comparison)
Definition: field_comparator.h:120
Definition: AirOpcode.h:41
Definition: descriptor.h:439
Definition: protobuf.h:85
int32_t int32
Definition: port.h:130
Definition: field_comparator.h:62
TestSubObjConstructor T
Definition: TestTypedefs.idl:84
FloatComparison
Definition: field_comparator.h:99
ComparisonResult
Definition: field_comparator.h:61
uint32_t uint32
Definition: port.h:135
Definition: __init__.py:1
Definition: message_differencer.h:825
uint64_t uint64
Definition: port.h:136
GLfloat f
Definition: gl2.h:417
int64_t int64
Definition: port.h:131
Definition: field_comparator.h:67
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
Definition: gflags_completions.h:115
Definition: descriptor.h:919
Definition: field_comparator.h:97
bool treat_nan_as_equal() const
Definition: field_comparator.h:135
void set_treat_nan_as_equal(bool treat_nan_as_equal)
Definition: field_comparator.h:131
Definition: AirOpcode.h:40