| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 #include <google/protobuf/util/internal/utility.h> | 31 #include <google/protobuf/util/internal/utility.h> |
| 32 | 32 |
| 33 #include <algorithm> | |
| 34 | |
| 35 #include <google/protobuf/stubs/callback.h> | 33 #include <google/protobuf/stubs/callback.h> |
| 36 #include <google/protobuf/stubs/common.h> | 34 #include <google/protobuf/stubs/common.h> |
| 37 #include <google/protobuf/stubs/logging.h> | 35 #include <google/protobuf/stubs/logging.h> |
| 38 #include <google/protobuf/wrappers.pb.h> | 36 #include <google/protobuf/wrappers.pb.h> |
| 39 #include <google/protobuf/descriptor.pb.h> | 37 #include <google/protobuf/descriptor.pb.h> |
| 40 #include <google/protobuf/descriptor.h> | 38 #include <google/protobuf/descriptor.h> |
| 41 #include <google/protobuf/util/internal/constants.h> | 39 #include <google/protobuf/util/internal/constants.h> |
| 42 #include <google/protobuf/stubs/strutil.h> | 40 #include <google/protobuf/stubs/strutil.h> |
| 43 #include <google/protobuf/stubs/map_util.h> | 41 #include <google/protobuf/stubs/map_util.h> |
| 44 #include <google/protobuf/stubs/mathlimits.h> | 42 #include <google/protobuf/stubs/mathlimits.h> |
| 45 | 43 |
| 46 namespace google { | 44 namespace google { |
| 47 namespace protobuf { | 45 namespace protobuf { |
| 48 namespace util { | 46 namespace util { |
| 49 namespace converter { | 47 namespace converter { |
| 50 | 48 |
| 51 namespace { | 49 namespace { |
| 52 const StringPiece SkipWhiteSpace(StringPiece str) { | 50 const StringPiece SkipWhiteSpace(StringPiece str) { |
| 53 StringPiece::size_type i; | 51 StringPiece::size_type i; |
| 54 for (i = 0; i < str.size() && isspace(str[i]); ++i) { | 52 for (i = 0; i < str.size() && isspace(str[i]); ++i) { |
| 55 } | 53 } |
| 56 GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); | 54 GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); |
| 57 return str.substr(i); | 55 return StringPiece(str, i); |
| 58 } | 56 } |
| 59 } // namespace | 57 } // namespace |
| 60 | 58 |
| 61 bool GetBoolOptionOrDefault( | 59 bool GetBoolOptionOrDefault( |
| 62 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, | 60 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, |
| 63 const string& option_name, bool default_value) { | 61 const string& option_name, bool default_value) { |
| 64 const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); | 62 const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); |
| 65 if (opt == NULL) { | 63 if (opt == NULL) { |
| 66 return default_value; | 64 return default_value; |
| 67 } | 65 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 return i.value(); | 121 return i.value(); |
| 124 } | 122 } |
| 125 | 123 |
| 126 string GetStringFromAny(const google::protobuf::Any& any) { | 124 string GetStringFromAny(const google::protobuf::Any& any) { |
| 127 google::protobuf::StringValue s; | 125 google::protobuf::StringValue s; |
| 128 ParseFromAny(any.value(), &s); | 126 ParseFromAny(any.value(), &s); |
| 129 return s.value(); | 127 return s.value(); |
| 130 } | 128 } |
| 131 | 129 |
| 132 const StringPiece GetTypeWithoutUrl(StringPiece type_url) { | 130 const StringPiece GetTypeWithoutUrl(StringPiece type_url) { |
| 133 if (type_url.size() > kTypeUrlSize && type_url[kTypeUrlSize] == '/') { | 131 size_t idx = type_url.rfind('/'); |
| 134 return type_url.substr(kTypeUrlSize + 1); | 132 return type_url.substr(idx + 1); |
| 135 } else { | |
| 136 size_t idx = type_url.rfind('/'); | |
| 137 return type_url.substr(idx + 1); | |
| 138 } | |
| 139 } | 133 } |
| 140 | 134 |
| 141 const string GetFullTypeWithUrl(StringPiece simple_type) { | 135 const string GetFullTypeWithUrl(StringPiece simple_type) { |
| 142 return StrCat(kTypeServiceBaseUrl, "/", simple_type); | 136 return StrCat(kTypeServiceBaseUrl, "/", simple_type); |
| 143 } | 137 } |
| 144 | 138 |
| 145 const google::protobuf::Option* FindOptionOrNull( | 139 const google::protobuf::Option* FindOptionOrNull( |
| 146 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, | 140 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, |
| 147 const string& option_name) { | 141 const string& option_name) { |
| 148 for (int i = 0; i < options.size(); ++i) { | 142 for (int i = 0; i < options.size(); ++i) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 173 for (int i = 0; i < type->fields_size(); ++i) { | 167 for (int i = 0; i < type->fields_size(); ++i) { |
| 174 const google::protobuf::Field& field = type->fields(i); | 168 const google::protobuf::Field& field = type->fields(i); |
| 175 if (field.json_name() == json_name) { | 169 if (field.json_name() == json_name) { |
| 176 return &field; | 170 return &field; |
| 177 } | 171 } |
| 178 } | 172 } |
| 179 } | 173 } |
| 180 return NULL; | 174 return NULL; |
| 181 } | 175 } |
| 182 | 176 |
| 183 const google::protobuf::Field* FindFieldInTypeByNumberOrNull( | |
| 184 const google::protobuf::Type* type, int32 number) { | |
| 185 if (type != NULL) { | |
| 186 for (int i = 0; i < type->fields_size(); ++i) { | |
| 187 const google::protobuf::Field& field = type->fields(i); | |
| 188 if (field.number() == number) { | |
| 189 return &field; | |
| 190 } | |
| 191 } | |
| 192 } | |
| 193 return NULL; | |
| 194 } | |
| 195 | |
| 196 const google::protobuf::EnumValue* FindEnumValueByNameOrNull( | 177 const google::protobuf::EnumValue* FindEnumValueByNameOrNull( |
| 197 const google::protobuf::Enum* enum_type, StringPiece enum_name) { | 178 const google::protobuf::Enum* enum_type, StringPiece enum_name) { |
| 198 if (enum_type != NULL) { | 179 if (enum_type != NULL) { |
| 199 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { | 180 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { |
| 200 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); | 181 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); |
| 201 if (enum_value.name() == enum_name) { | 182 if (enum_value.name() == enum_name) { |
| 202 return &enum_value; | 183 return &enum_value; |
| 203 } | 184 } |
| 204 } | 185 } |
| 205 } | 186 } |
| 206 return NULL; | 187 return NULL; |
| 207 } | 188 } |
| 208 | 189 |
| 209 const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( | 190 const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( |
| 210 const google::protobuf::Enum* enum_type, int32 value) { | 191 const google::protobuf::Enum* enum_type, int32 value) { |
| 211 if (enum_type != NULL) { | 192 if (enum_type != NULL) { |
| 212 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { | 193 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { |
| 213 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); | 194 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); |
| 214 if (enum_value.number() == value) { | 195 if (enum_value.number() == value) { |
| 215 return &enum_value; | 196 return &enum_value; |
| 216 } | 197 } |
| 217 } | 198 } |
| 218 } | 199 } |
| 219 return NULL; | 200 return NULL; |
| 220 } | 201 } |
| 221 | 202 |
| 222 const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( | |
| 223 const google::protobuf::Enum* enum_type, StringPiece enum_name) { | |
| 224 if (enum_type != NULL) { | |
| 225 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { | |
| 226 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); | |
| 227 string enum_name_without_underscore = enum_value.name(); | |
| 228 | |
| 229 // Remove underscore from the name. | |
| 230 enum_name_without_underscore.erase( | |
| 231 std::remove(enum_name_without_underscore.begin(), | |
| 232 enum_name_without_underscore.end(), '_'), | |
| 233 enum_name_without_underscore.end()); | |
| 234 // Make the name uppercase. | |
| 235 for (string::iterator it = enum_name_without_underscore.begin(); | |
| 236 it != enum_name_without_underscore.end(); ++it) { | |
| 237 *it = ascii_toupper(*it); | |
| 238 } | |
| 239 | |
| 240 if (enum_name_without_underscore == enum_name) { | |
| 241 return &enum_value; | |
| 242 } | |
| 243 } | |
| 244 } | |
| 245 return NULL; | |
| 246 } | |
| 247 | |
| 248 string ToCamelCase(const StringPiece input) { | 203 string ToCamelCase(const StringPiece input) { |
| 249 bool capitalize_next = false; | 204 bool capitalize_next = false; |
| 250 bool was_cap = true; | 205 bool was_cap = true; |
| 251 bool is_cap = false; | 206 bool is_cap = false; |
| 252 bool first_word = true; | 207 bool first_word = true; |
| 253 string result; | 208 string result; |
| 254 result.reserve(input.size()); | 209 result.reserve(input.size()); |
| 255 | 210 |
| 256 for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) { | 211 for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) { |
| 257 is_cap = ascii_isupper(input[i]); | 212 is_cap = ascii_isupper(input[i]); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 was_not_cap = false; | 272 was_not_cap = false; |
| 318 } else { | 273 } else { |
| 319 result.push_back(input[i]); | 274 result.push_back(input[i]); |
| 320 was_not_underscore = input[i] != '_'; | 275 was_not_underscore = input[i] != '_'; |
| 321 was_not_cap = true; | 276 was_not_cap = true; |
| 322 } | 277 } |
| 323 } | 278 } |
| 324 return result; | 279 return result; |
| 325 } | 280 } |
| 326 | 281 |
| 327 std::set<string>* well_known_types_ = NULL; | 282 set<string>* well_known_types_ = NULL; |
| 328 GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_); | 283 GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_); |
| 329 const char* well_known_types_name_array_[] = { | 284 const char* well_known_types_name_array_[] = { |
| 330 "google.protobuf.Timestamp", "google.protobuf.Duration", | 285 "google.protobuf.Timestamp", "google.protobuf.Duration", |
| 331 "google.protobuf.DoubleValue", "google.protobuf.FloatValue", | 286 "google.protobuf.DoubleValue", "google.protobuf.FloatValue", |
| 332 "google.protobuf.Int64Value", "google.protobuf.UInt64Value", | 287 "google.protobuf.Int64Value", "google.protobuf.UInt64Value", |
| 333 "google.protobuf.Int32Value", "google.protobuf.UInt32Value", | 288 "google.protobuf.Int32Value", "google.protobuf.UInt32Value", |
| 334 "google.protobuf.BoolValue", "google.protobuf.StringValue", | 289 "google.protobuf.BoolValue", "google.protobuf.StringValue", |
| 335 "google.protobuf.BytesValue", "google.protobuf.FieldMask"}; | 290 "google.protobuf.BytesValue", "google.protobuf.FieldMask"}; |
| 336 | 291 |
| 337 void DeleteWellKnownTypes() { delete well_known_types_; } | 292 void DeleteWellKnownTypes() { delete well_known_types_; } |
| 338 | 293 |
| 339 void InitWellKnownTypes() { | 294 void InitWellKnownTypes() { |
| 340 well_known_types_ = new std::set<string>; | 295 well_known_types_ = new set<string>; |
| 341 for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { | 296 for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { |
| 342 well_known_types_->insert(well_known_types_name_array_[i]); | 297 well_known_types_->insert(well_known_types_name_array_[i]); |
| 343 } | 298 } |
| 344 google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes); | 299 google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes); |
| 345 } | 300 } |
| 346 | 301 |
| 347 bool IsWellKnownType(const string& type_name) { | 302 bool IsWellKnownType(const string& type_name) { |
| 348 InitWellKnownTypes(); | 303 InitWellKnownTypes(); |
| 349 return ContainsKey(*well_known_types_, type_name); | 304 return ContainsKey(*well_known_types_, type_name); |
| 350 } | 305 } |
| 351 | 306 |
| 352 bool IsValidBoolString(const string& bool_string) { | 307 bool IsValidBoolString(const string& bool_string) { |
| 353 return bool_string == "true" || bool_string == "false" || | 308 return bool_string == "true" || bool_string == "false" || |
| 354 bool_string == "1" || bool_string == "0"; | 309 bool_string == "1" || bool_string == "0"; |
| 355 } | 310 } |
| 356 | 311 |
| 357 bool IsMap(const google::protobuf::Field& field, | 312 bool IsMap(const google::protobuf::Field& field, |
| 358 const google::protobuf::Type& type) { | 313 const google::protobuf::Type& type) { |
| 359 return ( | 314 return (field.cardinality() == |
| 360 field.cardinality() == | 315 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED && |
| 361 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED && | 316 GetBoolOptionOrDefault(type.options(), |
| 362 (GetBoolOptionOrDefault( | 317 "google.protobuf.MessageOptions.map_entry", fal
se)); |
| 363 type.options(), "google.protobuf.MessageOptions.map_entry", false) || | |
| 364 GetBoolOptionOrDefault(type.options(), "proto2.MessageOptions.map_entry", | |
| 365 false))); | |
| 366 } | 318 } |
| 367 | 319 |
| 368 bool IsMessageSetWireFormat(const google::protobuf::Type& type) { | 320 bool IsMessageSetWireFormat(const google::protobuf::Type& type) { |
| 369 return ( | 321 return GetBoolOptionOrDefault( |
| 370 GetBoolOptionOrDefault( | 322 type.options(), "google.protobuf.MessageOptions.message_set_wire_format",
false); |
| 371 type.options(), | |
| 372 "google.protobuf.MessageOptions.message_set_wire_format", false) || | |
| 373 GetBoolOptionOrDefault(type.options(), | |
| 374 "proto2.MessageOptions.message_set_wire_format", | |
| 375 false)); | |
| 376 } | 323 } |
| 377 | 324 |
| 378 string DoubleAsString(double value) { | 325 string DoubleAsString(double value) { |
| 379 if (MathLimits<double>::IsPosInf(value)) return "Infinity"; | 326 if (MathLimits<double>::IsPosInf(value)) return "Infinity"; |
| 380 if (MathLimits<double>::IsNegInf(value)) return "-Infinity"; | 327 if (MathLimits<double>::IsNegInf(value)) return "-Infinity"; |
| 381 if (MathLimits<double>::IsNaN(value)) return "NaN"; | 328 if (MathLimits<double>::IsNaN(value)) return "NaN"; |
| 382 | 329 |
| 383 return SimpleDtoa(value); | 330 return SimpleDtoa(value); |
| 384 } | 331 } |
| 385 | 332 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 405 } | 352 } |
| 406 | 353 |
| 407 *value = static_cast<float>(double_value); | 354 *value = static_cast<float>(double_value); |
| 408 return true; | 355 return true; |
| 409 } | 356 } |
| 410 | 357 |
| 411 } // namespace converter | 358 } // namespace converter |
| 412 } // namespace util | 359 } // namespace util |
| 413 } // namespace protobuf | 360 } // namespace protobuf |
| 414 } // namespace google | 361 } // namespace google |
| 415 | |
| OLD | NEW |