Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/internal/datapiece.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 // point types (double, float) only. 87 // point types (double, float) only.
88 template <typename To, typename From> 88 template <typename To, typename From>
89 StatusOr<To> FloatingPointToIntConvertAndCheck(From before) { 89 StatusOr<To> FloatingPointToIntConvertAndCheck(From before) {
90 if (::google::protobuf::internal::is_same<From, To>::value) return before; 90 if (::google::protobuf::internal::is_same<From, To>::value) return before;
91 91
92 To after = static_cast<To>(before); 92 To after = static_cast<To>(before);
93 return ValidateNumberConversion(after, before); 93 return ValidateNumberConversion(after, before);
94 } 94 }
95 95
96 // For conversion between double and float only. 96 // For conversion between double and float only.
97 template <typename To, typename From> 97 StatusOr<double> FloatToDouble(float before) {
98 StatusOr<To> FloatingPointConvertAndCheck(From before) { 98 // Casting float to double should just work as double has more precision
99 if (MathLimits<From>::IsNaN(before)) { 99 // than float.
100 return std::numeric_limits<To>::quiet_NaN(); 100 return static_cast<double>(before);
101 } 101 }
102 102
103 To after = static_cast<To>(before); 103 StatusOr<float> DoubleToFloat(double before) {
104 if (MathUtil::AlmostEquals<To>(after, before)) { 104 if (MathLimits<double>::IsNaN(before)) {
105 return after; 105 return std::numeric_limits<float>::quiet_NaN();
106 } else if (!MathLimits<double>::IsFinite(before)) {
107 // Converting a double +inf/-inf to float should just work.
108 return static_cast<float>(before);
109 } else if (before > std::numeric_limits<float>::max() ||
110 before < -std::numeric_limits<float>::max()) {
111 // Double value outside of the range of float.
112 return InvalidArgument(DoubleAsString(before));
106 } else { 113 } else {
107 return InvalidArgument(::google::protobuf::internal::is_same<From, double>:: value 114 return static_cast<float>(before);
108 ? DoubleAsString(before)
109 : FloatAsString(before));
110 } 115 }
111 } 116 }
112 117
113 } // namespace 118 } // namespace
114 119
115 StatusOr<int32> DataPiece::ToInt32() const { 120 StatusOr<int32> DataPiece::ToInt32() const {
116 if (type_ == TYPE_STRING) return StringToNumber<int32>(safe_strto32); 121 if (type_ == TYPE_STRING) return StringToNumber<int32>(safe_strto32);
117 122
118 if (type_ == TYPE_DOUBLE) 123 if (type_ == TYPE_DOUBLE)
119 return FloatingPointToIntConvertAndCheck<int32, double>(double_); 124 return FloatingPointToIntConvertAndCheck<int32, double>(double_);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 return FloatingPointToIntConvertAndCheck<uint64, double>(double_); 160 return FloatingPointToIntConvertAndCheck<uint64, double>(double_);
156 161
157 if (type_ == TYPE_FLOAT) 162 if (type_ == TYPE_FLOAT)
158 return FloatingPointToIntConvertAndCheck<uint64, float>(float_); 163 return FloatingPointToIntConvertAndCheck<uint64, float>(float_);
159 164
160 return GenericConvert<uint64>(); 165 return GenericConvert<uint64>();
161 } 166 }
162 167
163 StatusOr<double> DataPiece::ToDouble() const { 168 StatusOr<double> DataPiece::ToDouble() const {
164 if (type_ == TYPE_FLOAT) { 169 if (type_ == TYPE_FLOAT) {
165 return FloatingPointConvertAndCheck<double, float>(float_); 170 return FloatToDouble(float_);
166 } 171 }
167 if (type_ == TYPE_STRING) { 172 if (type_ == TYPE_STRING) {
168 if (str_ == "Infinity") return std::numeric_limits<double>::infinity(); 173 if (str_ == "Infinity") return std::numeric_limits<double>::infinity();
169 if (str_ == "-Infinity") return -std::numeric_limits<double>::infinity(); 174 if (str_ == "-Infinity") return -std::numeric_limits<double>::infinity();
170 if (str_ == "NaN") return std::numeric_limits<double>::quiet_NaN(); 175 if (str_ == "NaN") return std::numeric_limits<double>::quiet_NaN();
171 return StringToNumber<double>(safe_strtod); 176 StatusOr<double> value = StringToNumber<double>(safe_strtod);
177 if (value.ok() && !MathLimits<double>::IsFinite(value.ValueOrDie())) {
178 // safe_strtod converts out-of-range values to +inf/-inf, but we want
179 // to report them as errors.
180 return InvalidArgument(StrCat("\"", str_, "\""));
181 } else {
182 return value;
183 }
172 } 184 }
173 return GenericConvert<double>(); 185 return GenericConvert<double>();
174 } 186 }
175 187
176 StatusOr<float> DataPiece::ToFloat() const { 188 StatusOr<float> DataPiece::ToFloat() const {
177 if (type_ == TYPE_DOUBLE) { 189 if (type_ == TYPE_DOUBLE) {
178 return FloatingPointConvertAndCheck<float, double>(double_); 190 return DoubleToFloat(double_);
179 } 191 }
180 if (type_ == TYPE_STRING) { 192 if (type_ == TYPE_STRING) {
181 if (str_ == "Infinity") return std::numeric_limits<float>::infinity(); 193 if (str_ == "Infinity") return std::numeric_limits<float>::infinity();
182 if (str_ == "-Infinity") return -std::numeric_limits<float>::infinity(); 194 if (str_ == "-Infinity") return -std::numeric_limits<float>::infinity();
183 if (str_ == "NaN") return std::numeric_limits<float>::quiet_NaN(); 195 if (str_ == "NaN") return std::numeric_limits<float>::quiet_NaN();
184 // SafeStrToFloat() is used instead of safe_strtof() because the later 196 // SafeStrToFloat() is used instead of safe_strtof() because the later
185 // does not fail on inputs like SimpleDtoa(DBL_MAX). 197 // does not fail on inputs like SimpleDtoa(DBL_MAX).
186 return StringToNumber<float>(SafeStrToFloat); 198 return StringToNumber<float>(SafeStrToFloat);
187 } 199 }
188 return GenericConvert<float>(); 200 return GenericConvert<float>();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 if (!DecodeBase64(str_, &decoded)) { 264 if (!DecodeBase64(str_, &decoded)) {
253 return InvalidArgument(ValueAsStringOrDefault("Invalid data in input.")); 265 return InvalidArgument(ValueAsStringOrDefault("Invalid data in input."));
254 } 266 }
255 return decoded; 267 return decoded;
256 } else { 268 } else {
257 return InvalidArgument(ValueAsStringOrDefault( 269 return InvalidArgument(ValueAsStringOrDefault(
258 "Wrong type. Only String or Bytes can be converted to Bytes.")); 270 "Wrong type. Only String or Bytes can be converted to Bytes."));
259 } 271 }
260 } 272 }
261 273
262 StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type) const { 274 StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type,
275 bool use_lower_camel_for_enums) const {
263 if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE; 276 if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE;
264 277
265 if (type_ == TYPE_STRING) { 278 if (type_ == TYPE_STRING) {
266 // First try the given value as a name. 279 // First try the given value as a name.
267 string enum_name = str_.ToString(); 280 string enum_name = str_.ToString();
268 const google::protobuf::EnumValue* value = 281 const google::protobuf::EnumValue* value =
269 FindEnumValueByNameOrNull(enum_type, enum_name); 282 FindEnumValueByNameOrNull(enum_type, enum_name);
270 if (value != NULL) return value->number(); 283 if (value != NULL) return value->number();
284
285 // Check if int version of enum is sent as string.
286 StatusOr<int32> int_value = ToInt32();
287 if (int_value.ok()) {
288 if (const google::protobuf::EnumValue* enum_value =
289 FindEnumValueByNumberOrNull(enum_type, int_value.ValueOrDie())) {
290 return enum_value->number();
291 }
292 }
293
271 // Next try a normalized name. 294 // Next try a normalized name.
272 for (string::iterator it = enum_name.begin(); it != enum_name.end(); ++it) { 295 for (string::iterator it = enum_name.begin(); it != enum_name.end(); ++it) {
273 *it = *it == '-' ? '_' : ascii_toupper(*it); 296 *it = *it == '-' ? '_' : ascii_toupper(*it);
274 } 297 }
275 value = FindEnumValueByNameOrNull(enum_type, enum_name); 298 value = FindEnumValueByNameOrNull(enum_type, enum_name);
276 if (value != NULL) return value->number(); 299 if (value != NULL) return value->number();
300
301 // If use_lower_camel_for_enums is true try with enum name without
302 // underscore. This will also accept camel case names as the enum_name has
303 // been normalized before.
304 if (use_lower_camel_for_enums) {
305 value = FindEnumValueByNameWithoutUnderscoreOrNull(enum_type, enum_name);
306 if (value != NULL) return value->number();
307 }
277 } else { 308 } else {
278 StatusOr<int32> value = ToInt32(); 309 // We don't need to check whether the value is actually declared in the
279 if (value.ok()) { 310 // enum because we preserve unknown enum values as well.
280 if (const google::protobuf::EnumValue* enum_value = 311 return ToInt32();
281 FindEnumValueByNumberOrNull(enum_type, value.ValueOrDie())) {
282 return enum_value->number();
283 }
284 }
285 } 312 }
286 return InvalidArgument( 313 return InvalidArgument(
287 ValueAsStringOrDefault("Cannot find enum with given value.")); 314 ValueAsStringOrDefault("Cannot find enum with given value."));
288 } 315 }
289 316
290 template <typename To> 317 template <typename To>
291 StatusOr<To> DataPiece::GenericConvert() const { 318 StatusOr<To> DataPiece::GenericConvert() const {
292 switch (type_) { 319 switch (type_) {
293 case TYPE_INT32: 320 case TYPE_INT32:
294 return NumberConvertAndCheck<To, int32>(i32_); 321 return NumberConvertAndCheck<To, int32>(i32_);
(...skipping 27 matching lines...) Expand all
322 bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { 349 bool DataPiece::DecodeBase64(StringPiece src, string* dest) const {
323 // Try web-safe decode first, if it fails, try the non-web-safe decode. 350 // Try web-safe decode first, if it fails, try the non-web-safe decode.
324 if (WebSafeBase64Unescape(src, dest)) { 351 if (WebSafeBase64Unescape(src, dest)) {
325 if (use_strict_base64_decoding_) { 352 if (use_strict_base64_decoding_) {
326 // In strict mode, check if the escaped version gives us the same value as 353 // In strict mode, check if the escaped version gives us the same value as
327 // unescaped. 354 // unescaped.
328 string encoded; 355 string encoded;
329 // WebSafeBase64Escape does no padding by default. 356 // WebSafeBase64Escape does no padding by default.
330 WebSafeBase64Escape(*dest, &encoded); 357 WebSafeBase64Escape(*dest, &encoded);
331 // Remove trailing padding '=' characters before comparison. 358 // Remove trailing padding '=' characters before comparison.
332 StringPiece src_no_padding(src, 0, src.ends_with("=") 359 StringPiece src_no_padding = StringPiece(src).substr(
333 ? src.find_last_not_of('=') + 1 360 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length());
334 : src.length());
335 return encoded == src_no_padding; 361 return encoded == src_no_padding;
336 } 362 }
337 return true; 363 return true;
338 } 364 }
339 365
340 if (Base64Unescape(src, dest)) { 366 if (Base64Unescape(src, dest)) {
341 if (use_strict_base64_decoding_) { 367 if (use_strict_base64_decoding_) {
342 string encoded; 368 string encoded;
343 Base64Escape( 369 Base64Escape(
344 reinterpret_cast<const unsigned char*>(dest->data()), dest->length(), 370 reinterpret_cast<const unsigned char*>(dest->data()), dest->length(),
345 &encoded, false); 371 &encoded, false);
346 StringPiece src_no_padding(src, 0, src.ends_with("=") 372 StringPiece src_no_padding = StringPiece(src).substr(
347 ? src.find_last_not_of('=') + 1 373 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length());
348 : src.length());
349 return encoded == src_no_padding; 374 return encoded == src_no_padding;
350 } 375 }
351 return true; 376 return true;
352 } 377 }
353 378
354 return false; 379 return false;
355 } 380 }
356 381
382 void DataPiece::InternalCopy(const DataPiece& other) {
383 type_ = other.type_;
384 use_strict_base64_decoding_ = other.use_strict_base64_decoding_;
385 switch (type_) {
386 case TYPE_INT32:
387 case TYPE_INT64:
388 case TYPE_UINT32:
389 case TYPE_UINT64:
390 case TYPE_DOUBLE:
391 case TYPE_FLOAT:
392 case TYPE_BOOL:
393 case TYPE_ENUM:
394 case TYPE_NULL:
395 case TYPE_BYTES:
396 case TYPE_STRING: {
397 str_ = other.str_;
398 break;
399 }
400 }
401 }
402
357 } // namespace converter 403 } // namespace converter
358 } // namespace util 404 } // namespace util
359 } // namespace protobuf 405 } // namespace protobuf
360 } // namespace google 406 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698