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 |
33 #include <google/protobuf/stubs/callback.h> | 35 #include <google/protobuf/stubs/callback.h> |
34 #include <google/protobuf/stubs/common.h> | 36 #include <google/protobuf/stubs/common.h> |
35 #include <google/protobuf/stubs/logging.h> | 37 #include <google/protobuf/stubs/logging.h> |
36 #include <google/protobuf/wrappers.pb.h> | 38 #include <google/protobuf/wrappers.pb.h> |
37 #include <google/protobuf/descriptor.pb.h> | 39 #include <google/protobuf/descriptor.pb.h> |
38 #include <google/protobuf/descriptor.h> | 40 #include <google/protobuf/descriptor.h> |
39 #include <google/protobuf/util/internal/constants.h> | 41 #include <google/protobuf/util/internal/constants.h> |
40 #include <google/protobuf/stubs/strutil.h> | 42 #include <google/protobuf/stubs/strutil.h> |
41 #include <google/protobuf/stubs/map_util.h> | 43 #include <google/protobuf/stubs/map_util.h> |
42 #include <google/protobuf/stubs/mathlimits.h> | 44 #include <google/protobuf/stubs/mathlimits.h> |
43 | 45 |
44 namespace google { | 46 namespace google { |
45 namespace protobuf { | 47 namespace protobuf { |
46 namespace util { | 48 namespace util { |
47 namespace converter { | 49 namespace converter { |
48 | 50 |
49 namespace { | 51 namespace { |
50 const StringPiece SkipWhiteSpace(StringPiece str) { | 52 const StringPiece SkipWhiteSpace(StringPiece str) { |
51 StringPiece::size_type i; | 53 StringPiece::size_type i; |
52 for (i = 0; i < str.size() && isspace(str[i]); ++i) { | 54 for (i = 0; i < str.size() && isspace(str[i]); ++i) { |
53 } | 55 } |
54 GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); | 56 GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); |
55 return StringPiece(str, i); | 57 return str.substr(i); |
56 } | 58 } |
57 } // namespace | 59 } // namespace |
58 | 60 |
59 bool GetBoolOptionOrDefault( | 61 bool GetBoolOptionOrDefault( |
60 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, | 62 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, |
61 const string& option_name, bool default_value) { | 63 const string& option_name, bool default_value) { |
62 const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); | 64 const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); |
63 if (opt == NULL) { | 65 if (opt == NULL) { |
64 return default_value; | 66 return default_value; |
65 } | 67 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 return i.value(); | 123 return i.value(); |
122 } | 124 } |
123 | 125 |
124 string GetStringFromAny(const google::protobuf::Any& any) { | 126 string GetStringFromAny(const google::protobuf::Any& any) { |
125 google::protobuf::StringValue s; | 127 google::protobuf::StringValue s; |
126 ParseFromAny(any.value(), &s); | 128 ParseFromAny(any.value(), &s); |
127 return s.value(); | 129 return s.value(); |
128 } | 130 } |
129 | 131 |
130 const StringPiece GetTypeWithoutUrl(StringPiece type_url) { | 132 const StringPiece GetTypeWithoutUrl(StringPiece type_url) { |
131 size_t idx = type_url.rfind('/'); | 133 if (type_url.size() > kTypeUrlSize && type_url[kTypeUrlSize] == '/') { |
132 return type_url.substr(idx + 1); | 134 return type_url.substr(kTypeUrlSize + 1); |
| 135 } else { |
| 136 size_t idx = type_url.rfind('/'); |
| 137 return type_url.substr(idx + 1); |
| 138 } |
133 } | 139 } |
134 | 140 |
135 const string GetFullTypeWithUrl(StringPiece simple_type) { | 141 const string GetFullTypeWithUrl(StringPiece simple_type) { |
136 return StrCat(kTypeServiceBaseUrl, "/", simple_type); | 142 return StrCat(kTypeServiceBaseUrl, "/", simple_type); |
137 } | 143 } |
138 | 144 |
139 const google::protobuf::Option* FindOptionOrNull( | 145 const google::protobuf::Option* FindOptionOrNull( |
140 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, | 146 const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, |
141 const string& option_name) { | 147 const string& option_name) { |
142 for (int i = 0; i < options.size(); ++i) { | 148 for (int i = 0; i < options.size(); ++i) { |
(...skipping 24 matching lines...) Expand all Loading... |
167 for (int i = 0; i < type->fields_size(); ++i) { | 173 for (int i = 0; i < type->fields_size(); ++i) { |
168 const google::protobuf::Field& field = type->fields(i); | 174 const google::protobuf::Field& field = type->fields(i); |
169 if (field.json_name() == json_name) { | 175 if (field.json_name() == json_name) { |
170 return &field; | 176 return &field; |
171 } | 177 } |
172 } | 178 } |
173 } | 179 } |
174 return NULL; | 180 return NULL; |
175 } | 181 } |
176 | 182 |
| 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 |
177 const google::protobuf::EnumValue* FindEnumValueByNameOrNull( | 196 const google::protobuf::EnumValue* FindEnumValueByNameOrNull( |
178 const google::protobuf::Enum* enum_type, StringPiece enum_name) { | 197 const google::protobuf::Enum* enum_type, StringPiece enum_name) { |
179 if (enum_type != NULL) { | 198 if (enum_type != NULL) { |
180 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { | 199 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { |
181 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); | 200 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); |
182 if (enum_value.name() == enum_name) { | 201 if (enum_value.name() == enum_name) { |
183 return &enum_value; | 202 return &enum_value; |
184 } | 203 } |
185 } | 204 } |
186 } | 205 } |
187 return NULL; | 206 return NULL; |
188 } | 207 } |
189 | 208 |
190 const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( | 209 const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( |
191 const google::protobuf::Enum* enum_type, int32 value) { | 210 const google::protobuf::Enum* enum_type, int32 value) { |
192 if (enum_type != NULL) { | 211 if (enum_type != NULL) { |
193 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { | 212 for (int i = 0; i < enum_type->enumvalue_size(); ++i) { |
194 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); | 213 const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); |
195 if (enum_value.number() == value) { | 214 if (enum_value.number() == value) { |
196 return &enum_value; | 215 return &enum_value; |
197 } | 216 } |
198 } | 217 } |
199 } | 218 } |
200 return NULL; | 219 return NULL; |
201 } | 220 } |
202 | 221 |
| 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 |
203 string ToCamelCase(const StringPiece input) { | 248 string ToCamelCase(const StringPiece input) { |
204 bool capitalize_next = false; | 249 bool capitalize_next = false; |
205 bool was_cap = true; | 250 bool was_cap = true; |
206 bool is_cap = false; | 251 bool is_cap = false; |
207 bool first_word = true; | 252 bool first_word = true; |
208 string result; | 253 string result; |
209 result.reserve(input.size()); | 254 result.reserve(input.size()); |
210 | 255 |
211 for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) { | 256 for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) { |
212 is_cap = ascii_isupper(input[i]); | 257 is_cap = ascii_isupper(input[i]); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 was_not_cap = false; | 317 was_not_cap = false; |
273 } else { | 318 } else { |
274 result.push_back(input[i]); | 319 result.push_back(input[i]); |
275 was_not_underscore = input[i] != '_'; | 320 was_not_underscore = input[i] != '_'; |
276 was_not_cap = true; | 321 was_not_cap = true; |
277 } | 322 } |
278 } | 323 } |
279 return result; | 324 return result; |
280 } | 325 } |
281 | 326 |
282 set<string>* well_known_types_ = NULL; | 327 std::set<string>* well_known_types_ = NULL; |
283 GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_); | 328 GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_); |
284 const char* well_known_types_name_array_[] = { | 329 const char* well_known_types_name_array_[] = { |
285 "google.protobuf.Timestamp", "google.protobuf.Duration", | 330 "google.protobuf.Timestamp", "google.protobuf.Duration", |
286 "google.protobuf.DoubleValue", "google.protobuf.FloatValue", | 331 "google.protobuf.DoubleValue", "google.protobuf.FloatValue", |
287 "google.protobuf.Int64Value", "google.protobuf.UInt64Value", | 332 "google.protobuf.Int64Value", "google.protobuf.UInt64Value", |
288 "google.protobuf.Int32Value", "google.protobuf.UInt32Value", | 333 "google.protobuf.Int32Value", "google.protobuf.UInt32Value", |
289 "google.protobuf.BoolValue", "google.protobuf.StringValue", | 334 "google.protobuf.BoolValue", "google.protobuf.StringValue", |
290 "google.protobuf.BytesValue", "google.protobuf.FieldMask"}; | 335 "google.protobuf.BytesValue", "google.protobuf.FieldMask"}; |
291 | 336 |
292 void DeleteWellKnownTypes() { delete well_known_types_; } | 337 void DeleteWellKnownTypes() { delete well_known_types_; } |
293 | 338 |
294 void InitWellKnownTypes() { | 339 void InitWellKnownTypes() { |
295 well_known_types_ = new set<string>; | 340 well_known_types_ = new std::set<string>; |
296 for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { | 341 for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) { |
297 well_known_types_->insert(well_known_types_name_array_[i]); | 342 well_known_types_->insert(well_known_types_name_array_[i]); |
298 } | 343 } |
299 google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes); | 344 google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes); |
300 } | 345 } |
301 | 346 |
302 bool IsWellKnownType(const string& type_name) { | 347 bool IsWellKnownType(const string& type_name) { |
303 InitWellKnownTypes(); | 348 InitWellKnownTypes(); |
304 return ContainsKey(*well_known_types_, type_name); | 349 return ContainsKey(*well_known_types_, type_name); |
305 } | 350 } |
306 | 351 |
307 bool IsValidBoolString(const string& bool_string) { | 352 bool IsValidBoolString(const string& bool_string) { |
308 return bool_string == "true" || bool_string == "false" || | 353 return bool_string == "true" || bool_string == "false" || |
309 bool_string == "1" || bool_string == "0"; | 354 bool_string == "1" || bool_string == "0"; |
310 } | 355 } |
311 | 356 |
312 bool IsMap(const google::protobuf::Field& field, | 357 bool IsMap(const google::protobuf::Field& field, |
313 const google::protobuf::Type& type) { | 358 const google::protobuf::Type& type) { |
314 return (field.cardinality() == | 359 return ( |
315 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED && | 360 field.cardinality() == |
316 GetBoolOptionOrDefault(type.options(), | 361 google::protobuf::Field_Cardinality_CARDINALITY_REPEATED && |
317 "google.protobuf.MessageOptions.map_entry", fal
se)); | 362 (GetBoolOptionOrDefault( |
| 363 type.options(), "google.protobuf.MessageOptions.map_entry", false) || |
| 364 GetBoolOptionOrDefault(type.options(), "proto2.MessageOptions.map_entry", |
| 365 false))); |
318 } | 366 } |
319 | 367 |
320 bool IsMessageSetWireFormat(const google::protobuf::Type& type) { | 368 bool IsMessageSetWireFormat(const google::protobuf::Type& type) { |
321 return GetBoolOptionOrDefault( | 369 return ( |
322 type.options(), "google.protobuf.MessageOptions.message_set_wire_format",
false); | 370 GetBoolOptionOrDefault( |
| 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)); |
323 } | 376 } |
324 | 377 |
325 string DoubleAsString(double value) { | 378 string DoubleAsString(double value) { |
326 if (MathLimits<double>::IsPosInf(value)) return "Infinity"; | 379 if (MathLimits<double>::IsPosInf(value)) return "Infinity"; |
327 if (MathLimits<double>::IsNegInf(value)) return "-Infinity"; | 380 if (MathLimits<double>::IsNegInf(value)) return "-Infinity"; |
328 if (MathLimits<double>::IsNaN(value)) return "NaN"; | 381 if (MathLimits<double>::IsNaN(value)) return "NaN"; |
329 | 382 |
330 return SimpleDtoa(value); | 383 return SimpleDtoa(value); |
331 } | 384 } |
332 | 385 |
(...skipping 19 matching lines...) Expand all Loading... |
352 } | 405 } |
353 | 406 |
354 *value = static_cast<float>(double_value); | 407 *value = static_cast<float>(double_value); |
355 return true; | 408 return true; |
356 } | 409 } |
357 | 410 |
358 } // namespace converter | 411 } // namespace converter |
359 } // namespace util | 412 } // namespace util |
360 } // namespace protobuf | 413 } // namespace protobuf |
361 } // namespace google | 414 } // namespace google |
| 415 |
OLD | NEW |