| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2012 Google Inc. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 // Useful utility functions for the TICL |
| 16 |
| 17 #include "google/cacheinvalidation/impl/proto-helpers.h" |
| 18 |
| 19 #include <sstream> |
| 20 |
| 21 #include "google/cacheinvalidation/client_test_internal.pb.h" |
| 22 #include "google/cacheinvalidation/deps/string_util.h" |
| 23 |
| 24 namespace invalidation { |
| 25 |
| 26 using ::ipc::invalidation::RegistrationManagerStateP; |
| 27 |
| 28 // Defines a ToString template method specialization for the given type. |
| 29 #define DEFINE_TO_STRING(type) \ |
| 30 template<> \ |
| 31 string ProtoHelpers::ToString(const type& message) |
| 32 |
| 33 // Creates a stringstream |stream| and emits a leading "{ " to it. |
| 34 #define BEGIN() \ |
| 35 std::stringstream stream; \ |
| 36 stream << "{ " |
| 37 |
| 38 // Emits a closing " }" on |stream| and returns the string that has been built. |
| 39 #define END() \ |
| 40 stream << " }"; \ |
| 41 return stream.str() |
| 42 |
| 43 // Defines a trivial ToString method for a type (which just returns "<type>"). |
| 44 #define DEFINE_TRIVIAL_TO_STRING(type) \ |
| 45 DEFINE_TO_STRING(type) { \ |
| 46 return "<" #type ">"; \ |
| 47 } |
| 48 |
| 49 // Emits "field: <field value as string>" if |field| is present in |message|. |
| 50 #define OPTIONAL(field) \ |
| 51 if (message.has_##field()) { \ |
| 52 stream << #field << ": " << ToString(message.field()) << " "; \ |
| 53 } |
| 54 |
| 55 // Emits "field: <field value as string>" for each instance of field in message. |
| 56 #define REPEATED(field) \ |
| 57 for (int i = 0; i < message.field##_size(); ++i) { \ |
| 58 stream << #field << ": " << ToString(message.field(i)) << " "; \ |
| 59 } |
| 60 |
| 61 // Expands to a case branch that returns "name" if the implicitly tested |
| 62 // expression is equal to the enum constant |name| in the given |type|. |
| 63 #define ENUM_VALUE(type, name) case type##_##name: return #name |
| 64 |
| 65 // Expands to a default case branch that returns the string representation of |
| 66 // |message|. |
| 67 #define ENUM_UNKNOWN() default: return SimpleItoa(message) |
| 68 |
| 69 DEFINE_TO_STRING(bool) { |
| 70 return message ? "true" : "false"; |
| 71 } |
| 72 |
| 73 DEFINE_TO_STRING(int) { |
| 74 std::stringstream stream; |
| 75 stream << message; |
| 76 return stream.str(); |
| 77 } |
| 78 |
| 79 DEFINE_TO_STRING(int64) { |
| 80 std::stringstream stream; |
| 81 stream << message; |
| 82 return stream.str(); |
| 83 } |
| 84 |
| 85 /* |
| 86 * Three arrays that store the representation of each character from 0 to 255. |
| 87 * The ith number's octal representation is: CHAR_OCTAL_STRINGS1[i], |
| 88 * CHAR_OCTAL_STRINGS2[i], CHAR_OCTAL_STRINGS3[i] |
| 89 * <p> |
| 90 * E.g., if the number 128, these arrays contain 2, 0, 0 at index 128. We use |
| 91 * 3 char arrays instead of an array of strings since the code path for a |
| 92 * character append operation is quite a bit shorterthan the append operation |
| 93 * for strings. |
| 94 */ |
| 95 char ProtoHelpers::CHAR_OCTAL_STRINGS1[]; |
| 96 char ProtoHelpers::CHAR_OCTAL_STRINGS2[]; |
| 97 char ProtoHelpers::CHAR_OCTAL_STRINGS3[]; |
| 98 bool ProtoHelpers::is_initialized = false; |
| 99 |
| 100 template<> |
| 101 string ProtoHelpers::ToString(const string& bytes) { |
| 102 // This is a racy initialization but that is ok since we are initializing to |
| 103 // the same values. |
| 104 if (!is_initialized) { |
| 105 // Initialize the array with the Octal string values so that we do not have |
| 106 // to do string.format for every byte during runtime. |
| 107 for (int i = 0; i < ProtoHelpers::NUM_CHARS; i++) { |
| 108 string value = StringPrintf("%03o", i); |
| 109 ProtoHelpers::CHAR_OCTAL_STRINGS1[i] = value[0]; |
| 110 ProtoHelpers::CHAR_OCTAL_STRINGS2[i] = value[1]; |
| 111 ProtoHelpers::CHAR_OCTAL_STRINGS3[i] = value[2]; |
| 112 } |
| 113 is_initialized = true; |
| 114 } |
| 115 string builder; |
| 116 builder.reserve(3 * bytes.length() + 2); |
| 117 builder += "\""; |
| 118 for (size_t i = 0; i < bytes.length(); i++) { |
| 119 char c = bytes[i]; |
| 120 switch (c) { |
| 121 case '\n': builder += '\\'; builder += 'n'; break; |
| 122 case '\r': builder += '\\'; builder += 'r'; break; |
| 123 case '\t': builder += '\\'; builder += 't'; break; |
| 124 case '\"': builder += '\\'; builder += '"'; break; |
| 125 case '\\': builder += '\\'; builder += '\\'; break; |
| 126 default: |
| 127 if ((c >= 32) && (c < 127) && c != '\'') { |
| 128 builder += c; |
| 129 } else { |
| 130 int byteValue = c; |
| 131 if (c < 0) { |
| 132 byteValue = c + 256; |
| 133 } |
| 134 builder += '\\'; |
| 135 builder += CHAR_OCTAL_STRINGS1[byteValue]; |
| 136 builder += CHAR_OCTAL_STRINGS2[byteValue]; |
| 137 builder += CHAR_OCTAL_STRINGS3[byteValue]; |
| 138 } |
| 139 break; |
| 140 } |
| 141 } |
| 142 builder += "\""; |
| 143 return builder; |
| 144 } |
| 145 |
| 146 void ProtoHelpers::InitRegistrationP(const ObjectIdP& oid, |
| 147 RegistrationP::OpType op_type, RegistrationP* reg) { |
| 148 reg->mutable_object_id()->CopyFrom(oid); |
| 149 reg->set_op_type(op_type); |
| 150 } |
| 151 |
| 152 void ProtoHelpers::InitRateLimitP(int window_ms, int count, |
| 153 RateLimitP *rate_limit) { |
| 154 rate_limit->set_window_ms(window_ms); |
| 155 rate_limit->set_count(count); |
| 156 } |
| 157 |
| 158 void ProtoHelpers::InitInitializeMessage( |
| 159 const ApplicationClientIdP& application_client_id, const string& nonce, |
| 160 InitializeMessage* init_msg) { |
| 161 init_msg->set_client_type(application_client_id.client_type()); |
| 162 init_msg->mutable_application_client_id()->CopyFrom( |
| 163 application_client_id); |
| 164 init_msg->set_nonce(nonce); |
| 165 init_msg->set_digest_serialization_type( |
| 166 InitializeMessage_DigestSerializationType_BYTE_BASED); |
| 167 } |
| 168 |
| 169 void ProtoHelpers::InitClientVersion(const string& platform, |
| 170 const string& application_info, ClientVersion* client_version) { |
| 171 Version* version = client_version->mutable_version(); |
| 172 version->set_major_version(Constants::kClientMajorVersion); |
| 173 version->set_minor_version(Constants::kClientMinorVersion); |
| 174 client_version->set_platform(platform); |
| 175 client_version->set_language("C++"); |
| 176 client_version->set_application_info(application_info); |
| 177 } |
| 178 |
| 179 void ProtoHelpers::InitProtocolVersion(ProtocolVersion* protocol_version) { |
| 180 Version* version = protocol_version->mutable_version(); |
| 181 version->set_major_version(Constants::kProtocolMajorVersion); |
| 182 version->set_minor_version(Constants::kProtocolMinorVersion); |
| 183 } |
| 184 |
| 185 void ProtoHelpers::InitConfigVersion(Version* config_version) { |
| 186 config_version->set_major_version(Constants::kConfigMajorVersion); |
| 187 config_version->set_minor_version(Constants::kConfigMinorVersion); |
| 188 } |
| 189 |
| 190 DEFINE_TO_STRING(ErrorMessage::Code) { |
| 191 switch (message) { |
| 192 ENUM_VALUE(ErrorMessage_Code, AUTH_FAILURE); |
| 193 ENUM_VALUE(ErrorMessage_Code, UNKNOWN_FAILURE); |
| 194 ENUM_UNKNOWN(); |
| 195 } |
| 196 } |
| 197 DEFINE_TO_STRING(InfoRequestMessage::InfoType) { |
| 198 switch (message) { |
| 199 ENUM_VALUE(InfoRequestMessage_InfoType, GET_PERFORMANCE_COUNTERS); |
| 200 ENUM_UNKNOWN(); |
| 201 } |
| 202 } |
| 203 |
| 204 DEFINE_TO_STRING(InitializeMessage::DigestSerializationType) { |
| 205 switch (message) { |
| 206 ENUM_VALUE(InitializeMessage_DigestSerializationType, BYTE_BASED); |
| 207 ENUM_VALUE(InitializeMessage_DigestSerializationType, NUMBER_BASED); |
| 208 ENUM_UNKNOWN(); |
| 209 } |
| 210 } |
| 211 |
| 212 DEFINE_TO_STRING(StatusP::Code) { |
| 213 switch (message) { |
| 214 ENUM_VALUE(StatusP_Code, SUCCESS); |
| 215 ENUM_VALUE(StatusP_Code, TRANSIENT_FAILURE); |
| 216 ENUM_VALUE(StatusP_Code, PERMANENT_FAILURE); |
| 217 ENUM_UNKNOWN(); |
| 218 } |
| 219 } |
| 220 |
| 221 DEFINE_TO_STRING(RegistrationP::OpType) { |
| 222 switch (message) { |
| 223 ENUM_VALUE(RegistrationP_OpType, REGISTER); |
| 224 ENUM_VALUE(RegistrationP_OpType, UNREGISTER); |
| 225 ENUM_UNKNOWN(); |
| 226 } |
| 227 } |
| 228 |
| 229 DEFINE_TO_STRING(RegistrationSyncRequestMessage) { |
| 230 BEGIN(); |
| 231 END(); |
| 232 } |
| 233 |
| 234 DEFINE_TO_STRING(Version) { |
| 235 BEGIN(); |
| 236 OPTIONAL(major_version); |
| 237 OPTIONAL(minor_version); |
| 238 END(); |
| 239 } |
| 240 |
| 241 DEFINE_TO_STRING(ClientVersion) { |
| 242 BEGIN(); |
| 243 OPTIONAL(version); |
| 244 OPTIONAL(platform); |
| 245 OPTIONAL(language); |
| 246 OPTIONAL(application_info); |
| 247 END(); |
| 248 } |
| 249 |
| 250 DEFINE_TO_STRING(ProtocolVersion) { |
| 251 BEGIN(); |
| 252 OPTIONAL(version); |
| 253 END(); |
| 254 } |
| 255 |
| 256 DEFINE_TO_STRING(InfoRequestMessage) { |
| 257 BEGIN(); |
| 258 REPEATED(info_type); |
| 259 END(); |
| 260 } |
| 261 |
| 262 DEFINE_TO_STRING(ConfigChangeMessage) { |
| 263 BEGIN(); |
| 264 OPTIONAL(next_message_delay_ms); |
| 265 END(); |
| 266 } |
| 267 |
| 268 DEFINE_TO_STRING(PropertyRecord) { |
| 269 BEGIN(); |
| 270 OPTIONAL(name); |
| 271 OPTIONAL(value); |
| 272 END(); |
| 273 } |
| 274 |
| 275 DEFINE_TO_STRING(RateLimitP) { |
| 276 BEGIN(); |
| 277 OPTIONAL(window_ms); |
| 278 OPTIONAL(count); |
| 279 END(); |
| 280 } |
| 281 |
| 282 DEFINE_TO_STRING(ProtocolHandlerConfigP) { |
| 283 BEGIN(); |
| 284 OPTIONAL(batching_delay_ms); |
| 285 REPEATED(rate_limit); |
| 286 END(); |
| 287 } |
| 288 |
| 289 DEFINE_TO_STRING(ClientConfigP) { |
| 290 BEGIN(); |
| 291 OPTIONAL(version); |
| 292 OPTIONAL(network_timeout_delay_ms); |
| 293 OPTIONAL(write_retry_delay_ms); |
| 294 OPTIONAL(heartbeat_interval_ms); |
| 295 OPTIONAL(perf_counter_delay_ms); |
| 296 OPTIONAL(max_exponential_backoff_factor); |
| 297 OPTIONAL(smear_percent); |
| 298 OPTIONAL(is_transient); |
| 299 OPTIONAL(initial_persistent_heartbeat_delay_ms); |
| 300 OPTIONAL(protocol_handler_config); |
| 301 END(); |
| 302 } |
| 303 |
| 304 DEFINE_TO_STRING(InfoMessage) { |
| 305 BEGIN(); |
| 306 OPTIONAL(client_version); |
| 307 REPEATED(config_parameter); |
| 308 REPEATED(performance_counter); |
| 309 OPTIONAL(server_registration_summary_requested); |
| 310 END(); |
| 311 } |
| 312 |
| 313 DEFINE_TO_STRING(ErrorMessage) { |
| 314 BEGIN(); |
| 315 OPTIONAL(code); |
| 316 OPTIONAL(description); |
| 317 END(); |
| 318 } |
| 319 |
| 320 DEFINE_TO_STRING(RegistrationSummary) { |
| 321 BEGIN(); |
| 322 OPTIONAL(num_registrations); |
| 323 OPTIONAL(registration_digest); |
| 324 END(); |
| 325 } |
| 326 |
| 327 DEFINE_TO_STRING(ObjectIdP) { |
| 328 BEGIN(); |
| 329 OPTIONAL(source); |
| 330 OPTIONAL(name); |
| 331 END(); |
| 332 } |
| 333 |
| 334 DEFINE_TO_STRING(InvalidationP) { |
| 335 BEGIN(); |
| 336 OPTIONAL(object_id); |
| 337 OPTIONAL(is_known_version); |
| 338 OPTIONAL(version); |
| 339 OPTIONAL(is_trickle_restart); |
| 340 OPTIONAL(payload); |
| 341 END(); |
| 342 } |
| 343 |
| 344 DEFINE_TO_STRING(AckHandleP) { |
| 345 BEGIN(); |
| 346 OPTIONAL(invalidation); |
| 347 END(); |
| 348 } |
| 349 |
| 350 DEFINE_TO_STRING(ApplicationClientIdP) { |
| 351 BEGIN(); |
| 352 OPTIONAL(client_type); |
| 353 OPTIONAL(client_name); |
| 354 END(); |
| 355 } |
| 356 |
| 357 DEFINE_TO_STRING(StatusP) { |
| 358 BEGIN(); |
| 359 OPTIONAL(code); |
| 360 OPTIONAL(description); |
| 361 END(); |
| 362 } |
| 363 |
| 364 DEFINE_TO_STRING(RegistrationP) { |
| 365 BEGIN(); |
| 366 OPTIONAL(object_id); |
| 367 OPTIONAL(op_type); |
| 368 END(); |
| 369 } |
| 370 |
| 371 DEFINE_TO_STRING(RegistrationStatus) { |
| 372 BEGIN(); |
| 373 OPTIONAL(registration); |
| 374 OPTIONAL(status); |
| 375 END(); |
| 376 } |
| 377 |
| 378 DEFINE_TO_STRING(ClientHeader) { |
| 379 BEGIN(); |
| 380 OPTIONAL(protocol_version); |
| 381 OPTIONAL(client_token); |
| 382 OPTIONAL(registration_summary); |
| 383 OPTIONAL(client_time_ms); |
| 384 OPTIONAL(max_known_server_time_ms); |
| 385 OPTIONAL(message_id); |
| 386 END(); |
| 387 } |
| 388 |
| 389 DEFINE_TO_STRING(InitializeMessage) { |
| 390 BEGIN(); |
| 391 OPTIONAL(client_type); |
| 392 OPTIONAL(nonce); |
| 393 OPTIONAL(application_client_id); |
| 394 OPTIONAL(digest_serialization_type); |
| 395 END(); |
| 396 } |
| 397 |
| 398 DEFINE_TO_STRING(RegistrationMessage) { |
| 399 BEGIN(); |
| 400 REPEATED(registration); |
| 401 END(); |
| 402 } |
| 403 |
| 404 DEFINE_TO_STRING(InvalidationMessage) { |
| 405 BEGIN(); |
| 406 REPEATED(invalidation); |
| 407 END(); |
| 408 } |
| 409 |
| 410 DEFINE_TO_STRING(RegistrationSubtree) { |
| 411 BEGIN(); |
| 412 REPEATED(registered_object); |
| 413 END(); |
| 414 } |
| 415 DEFINE_TO_STRING(RegistrationSyncMessage) { |
| 416 BEGIN(); |
| 417 REPEATED(subtree); |
| 418 END(); |
| 419 } |
| 420 |
| 421 DEFINE_TO_STRING(ClientToServerMessage) { |
| 422 BEGIN(); |
| 423 OPTIONAL(header); |
| 424 OPTIONAL(initialize_message); |
| 425 OPTIONAL(registration_message); |
| 426 OPTIONAL(registration_sync_message); |
| 427 OPTIONAL(invalidation_ack_message); |
| 428 OPTIONAL(info_message); |
| 429 END(); |
| 430 } |
| 431 |
| 432 DEFINE_TO_STRING(ServerHeader) { |
| 433 BEGIN(); |
| 434 OPTIONAL(protocol_version); |
| 435 OPTIONAL(client_token); |
| 436 OPTIONAL(registration_summary); |
| 437 OPTIONAL(server_time_ms); |
| 438 OPTIONAL(message_id); |
| 439 END(); |
| 440 } |
| 441 |
| 442 DEFINE_TO_STRING(TokenControlMessage) { |
| 443 BEGIN(); |
| 444 OPTIONAL(new_token); |
| 445 END(); |
| 446 } |
| 447 |
| 448 DEFINE_TO_STRING(RegistrationStatusMessage) { |
| 449 BEGIN(); |
| 450 REPEATED(registration_status); |
| 451 END(); |
| 452 } |
| 453 |
| 454 DEFINE_TO_STRING(ServerToClientMessage) { |
| 455 BEGIN(); |
| 456 OPTIONAL(header); |
| 457 OPTIONAL(token_control_message); |
| 458 OPTIONAL(invalidation_message); |
| 459 OPTIONAL(registration_status_message); |
| 460 OPTIONAL(registration_sync_request_message); |
| 461 OPTIONAL(info_request_message); |
| 462 END(); |
| 463 } |
| 464 |
| 465 DEFINE_TO_STRING(RegistrationManagerStateP) { |
| 466 BEGIN(); |
| 467 OPTIONAL(client_summary); |
| 468 OPTIONAL(server_summary); |
| 469 REPEATED(registered_objects); |
| 470 END(); |
| 471 } |
| 472 |
| 473 } // namespace invalidation |
| OLD | NEW |