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

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

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: 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 StatusOr<double> FloatToDouble(float before) { 97 template <typename To, typename From>
98 // Casting float to double should just work as double has more precision 98 StatusOr<To> FloatingPointConvertAndCheck(From before) {
99 // than float. 99 if (MathLimits<From>::IsNaN(before)) {
100 return static_cast<double>(before); 100 return std::numeric_limits<To>::quiet_NaN();
101 } 101 }
102 102
103 StatusOr<float> DoubleToFloat(double before) { 103 To after = static_cast<To>(before);
104 if (MathLimits<double>::IsNaN(before)) { 104 if (MathUtil::AlmostEquals<To>(after, before)) {
105 return std::numeric_limits<float>::quiet_NaN(); 105 return after;
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));
113 } else { 106 } else {
114 return static_cast<float>(before); 107 return InvalidArgument(::google::protobuf::internal::is_same<From, double>:: value
108 ? DoubleAsString(before)
109 : FloatAsString(before));
115 } 110 }
116 } 111 }
117 112
118 } // namespace 113 } // namespace
119 114
120 StatusOr<int32> DataPiece::ToInt32() const { 115 StatusOr<int32> DataPiece::ToInt32() const {
121 if (type_ == TYPE_STRING) return StringToNumber<int32>(safe_strto32); 116 if (type_ == TYPE_STRING) return StringToNumber<int32>(safe_strto32);
122 117
123 if (type_ == TYPE_DOUBLE) 118 if (type_ == TYPE_DOUBLE)
124 return FloatingPointToIntConvertAndCheck<int32, double>(double_); 119 return FloatingPointToIntConvertAndCheck<int32, double>(double_);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 return FloatingPointToIntConvertAndCheck<uint64, double>(double_); 155 return FloatingPointToIntConvertAndCheck<uint64, double>(double_);
161 156
162 if (type_ == TYPE_FLOAT) 157 if (type_ == TYPE_FLOAT)
163 return FloatingPointToIntConvertAndCheck<uint64, float>(float_); 158 return FloatingPointToIntConvertAndCheck<uint64, float>(float_);
164 159
165 return GenericConvert<uint64>(); 160 return GenericConvert<uint64>();
166 } 161 }
167 162
168 StatusOr<double> DataPiece::ToDouble() const { 163 StatusOr<double> DataPiece::ToDouble() const {
169 if (type_ == TYPE_FLOAT) { 164 if (type_ == TYPE_FLOAT) {
170 return FloatToDouble(float_); 165 return FloatingPointConvertAndCheck<double, float>(float_);
171 } 166 }
172 if (type_ == TYPE_STRING) { 167 if (type_ == TYPE_STRING) {
173 if (str_ == "Infinity") return std::numeric_limits<double>::infinity(); 168 if (str_ == "Infinity") return std::numeric_limits<double>::infinity();
174 if (str_ == "-Infinity") return -std::numeric_limits<double>::infinity(); 169 if (str_ == "-Infinity") return -std::numeric_limits<double>::infinity();
175 if (str_ == "NaN") return std::numeric_limits<double>::quiet_NaN(); 170 if (str_ == "NaN") return std::numeric_limits<double>::quiet_NaN();
176 StatusOr<double> value = StringToNumber<double>(safe_strtod); 171 return 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 }
184 } 172 }
185 return GenericConvert<double>(); 173 return GenericConvert<double>();
186 } 174 }
187 175
188 StatusOr<float> DataPiece::ToFloat() const { 176 StatusOr<float> DataPiece::ToFloat() const {
189 if (type_ == TYPE_DOUBLE) { 177 if (type_ == TYPE_DOUBLE) {
190 return DoubleToFloat(double_); 178 return FloatingPointConvertAndCheck<float, double>(double_);
191 } 179 }
192 if (type_ == TYPE_STRING) { 180 if (type_ == TYPE_STRING) {
193 if (str_ == "Infinity") return std::numeric_limits<float>::infinity(); 181 if (str_ == "Infinity") return std::numeric_limits<float>::infinity();
194 if (str_ == "-Infinity") return -std::numeric_limits<float>::infinity(); 182 if (str_ == "-Infinity") return -std::numeric_limits<float>::infinity();
195 if (str_ == "NaN") return std::numeric_limits<float>::quiet_NaN(); 183 if (str_ == "NaN") return std::numeric_limits<float>::quiet_NaN();
196 // SafeStrToFloat() is used instead of safe_strtof() because the later 184 // SafeStrToFloat() is used instead of safe_strtof() because the later
197 // does not fail on inputs like SimpleDtoa(DBL_MAX). 185 // does not fail on inputs like SimpleDtoa(DBL_MAX).
198 return StringToNumber<float>(SafeStrToFloat); 186 return StringToNumber<float>(SafeStrToFloat);
199 } 187 }
200 return GenericConvert<float>(); 188 return GenericConvert<float>();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 if (!DecodeBase64(str_, &decoded)) { 252 if (!DecodeBase64(str_, &decoded)) {
265 return InvalidArgument(ValueAsStringOrDefault("Invalid data in input.")); 253 return InvalidArgument(ValueAsStringOrDefault("Invalid data in input."));
266 } 254 }
267 return decoded; 255 return decoded;
268 } else { 256 } else {
269 return InvalidArgument(ValueAsStringOrDefault( 257 return InvalidArgument(ValueAsStringOrDefault(
270 "Wrong type. Only String or Bytes can be converted to Bytes.")); 258 "Wrong type. Only String or Bytes can be converted to Bytes."));
271 } 259 }
272 } 260 }
273 261
274 StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type, 262 StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type) const {
275 bool use_lower_camel_for_enums) const {
276 if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE; 263 if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE;
277 264
278 if (type_ == TYPE_STRING) { 265 if (type_ == TYPE_STRING) {
279 // First try the given value as a name. 266 // First try the given value as a name.
280 string enum_name = str_.ToString(); 267 string enum_name = str_.ToString();
281 const google::protobuf::EnumValue* value = 268 const google::protobuf::EnumValue* value =
282 FindEnumValueByNameOrNull(enum_type, enum_name); 269 FindEnumValueByNameOrNull(enum_type, enum_name);
283 if (value != NULL) return value->number(); 270 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
294 // Next try a normalized name. 271 // Next try a normalized name.
295 for (string::iterator it = enum_name.begin(); it != enum_name.end(); ++it) { 272 for (string::iterator it = enum_name.begin(); it != enum_name.end(); ++it) {
296 *it = *it == '-' ? '_' : ascii_toupper(*it); 273 *it = *it == '-' ? '_' : ascii_toupper(*it);
297 } 274 }
298 value = FindEnumValueByNameOrNull(enum_type, enum_name); 275 value = FindEnumValueByNameOrNull(enum_type, enum_name);
299 if (value != NULL) return value->number(); 276 if (value != NULL) return value->number();
300 277 } else {
301 // If use_lower_camel_for_enums is true try with enum name without 278 StatusOr<int32> value = ToInt32();
302 // underscore. This will also accept camel case names as the enum_name has 279 if (value.ok()) {
303 // been normalized before. 280 if (const google::protobuf::EnumValue* enum_value =
304 if (use_lower_camel_for_enums) { 281 FindEnumValueByNumberOrNull(enum_type, value.ValueOrDie())) {
305 value = FindEnumValueByNameWithoutUnderscoreOrNull(enum_type, enum_name); 282 return enum_value->number();
306 if (value != NULL) return value->number(); 283 }
307 } 284 }
308 } else {
309 // We don't need to check whether the value is actually declared in the
310 // enum because we preserve unknown enum values as well.
311 return ToInt32();
312 } 285 }
313 return InvalidArgument( 286 return InvalidArgument(
314 ValueAsStringOrDefault("Cannot find enum with given value.")); 287 ValueAsStringOrDefault("Cannot find enum with given value."));
315 } 288 }
316 289
317 template <typename To> 290 template <typename To>
318 StatusOr<To> DataPiece::GenericConvert() const { 291 StatusOr<To> DataPiece::GenericConvert() const {
319 switch (type_) { 292 switch (type_) {
320 case TYPE_INT32: 293 case TYPE_INT32:
321 return NumberConvertAndCheck<To, int32>(i32_); 294 return NumberConvertAndCheck<To, int32>(i32_);
(...skipping 27 matching lines...) Expand all
349 bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { 322 bool DataPiece::DecodeBase64(StringPiece src, string* dest) const {
350 // Try web-safe decode first, if it fails, try the non-web-safe decode. 323 // Try web-safe decode first, if it fails, try the non-web-safe decode.
351 if (WebSafeBase64Unescape(src, dest)) { 324 if (WebSafeBase64Unescape(src, dest)) {
352 if (use_strict_base64_decoding_) { 325 if (use_strict_base64_decoding_) {
353 // In strict mode, check if the escaped version gives us the same value as 326 // In strict mode, check if the escaped version gives us the same value as
354 // unescaped. 327 // unescaped.
355 string encoded; 328 string encoded;
356 // WebSafeBase64Escape does no padding by default. 329 // WebSafeBase64Escape does no padding by default.
357 WebSafeBase64Escape(*dest, &encoded); 330 WebSafeBase64Escape(*dest, &encoded);
358 // Remove trailing padding '=' characters before comparison. 331 // Remove trailing padding '=' characters before comparison.
359 StringPiece src_no_padding = StringPiece(src).substr( 332 StringPiece src_no_padding(src, 0, src.ends_with("=")
360 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); 333 ? src.find_last_not_of('=') + 1
334 : src.length());
361 return encoded == src_no_padding; 335 return encoded == src_no_padding;
362 } 336 }
363 return true; 337 return true;
364 } 338 }
365 339
366 if (Base64Unescape(src, dest)) { 340 if (Base64Unescape(src, dest)) {
367 if (use_strict_base64_decoding_) { 341 if (use_strict_base64_decoding_) {
368 string encoded; 342 string encoded;
369 Base64Escape( 343 Base64Escape(
370 reinterpret_cast<const unsigned char*>(dest->data()), dest->length(), 344 reinterpret_cast<const unsigned char*>(dest->data()), dest->length(),
371 &encoded, false); 345 &encoded, false);
372 StringPiece src_no_padding = StringPiece(src).substr( 346 StringPiece src_no_padding(src, 0, src.ends_with("=")
373 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); 347 ? src.find_last_not_of('=') + 1
348 : src.length());
374 return encoded == src_no_padding; 349 return encoded == src_no_padding;
375 } 350 }
376 return true; 351 return true;
377 } 352 }
378 353
379 return false; 354 return false;
380 } 355 }
381 356
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
403 } // namespace converter 357 } // namespace converter
404 } // namespace util 358 } // namespace util
405 } // namespace protobuf 359 } // namespace protobuf
406 } // namespace google 360 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698