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 |