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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #include <gtest/gtest.h> | 51 #include <gtest/gtest.h> |
52 #include <google/protobuf/io/zero_copy_stream_impl.h> | 52 #include <google/protobuf/io/zero_copy_stream_impl.h> |
53 | 53 |
54 | 54 |
55 // This declares an unsigned long long integer literal in a portable way. | 55 // This declares an unsigned long long integer literal in a portable way. |
56 // (The original macro is way too big and ruins my formatting.) | 56 // (The original macro is way too big and ruins my formatting.) |
57 #undef ULL | 57 #undef ULL |
58 #define ULL(x) GOOGLE_ULONGLONG(x) | 58 #define ULL(x) GOOGLE_ULONGLONG(x) |
59 | 59 |
60 namespace google { | 60 namespace google { |
61 | |
62 namespace protobuf { | 61 namespace protobuf { |
63 namespace io { | 62 namespace io { |
64 namespace { | 63 namespace { |
65 | 64 |
66 // =================================================================== | 65 // =================================================================== |
67 // Data-Driven Test Infrastructure | 66 // Data-Driven Test Infrastructure |
68 | 67 |
69 // TEST_1D and TEST_2D are macros I'd eventually like to see added to | 68 // TEST_1D and TEST_2D are macros I'd eventually like to see added to |
70 // gTest. These macros can be used to declare tests which should be | 69 // gTest. These macros can be used to declare tests which should be |
71 // run multiple times, once for each item in some input array. TEST_1D | 70 // run multiple times, once for each item in some input array. TEST_1D |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 const CaseType2& CASES2##_case) | 127 const CaseType2& CASES2##_case) |
129 | 128 |
130 // =================================================================== | 129 // =================================================================== |
131 | 130 |
132 class CodedStreamTest : public testing::Test { | 131 class CodedStreamTest : public testing::Test { |
133 protected: | 132 protected: |
134 // Helper method used by tests for bytes warning. See implementation comment | 133 // Helper method used by tests for bytes warning. See implementation comment |
135 // for further information. | 134 // for further information. |
136 static void SetupTotalBytesLimitWarningTest( | 135 static void SetupTotalBytesLimitWarningTest( |
137 int total_bytes_limit, int warning_threshold, | 136 int total_bytes_limit, int warning_threshold, |
138 std::vector<string>* out_errors, std::vector<string>* out_warnings); | 137 vector<string>* out_errors, vector<string>* out_warnings); |
139 | 138 |
140 // Buffer used during most of the tests. This assumes tests run sequentially. | 139 // Buffer used during most of the tests. This assumes tests run sequentially. |
141 static const int kBufferSize = 1024 * 64; | 140 static const int kBufferSize = 1024 * 64; |
142 static uint8 buffer_[kBufferSize]; | 141 static uint8 buffer_[kBufferSize]; |
143 }; | 142 }; |
144 | 143 |
145 uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize]; | 144 uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize]; |
146 | 145 |
147 // We test each operation over a variety of block sizes to insure that | 146 // We test each operation over a variety of block sizes to insure that |
148 // we test cases where reads or writes cross buffer boundaries, cases | 147 // we test cases where reads or writes cross buffer boundaries, cases |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 GOOGLE_LOG(FATAL) << "Tests never call this."; | 237 GOOGLE_LOG(FATAL) << "Tests never call this."; |
239 } | 238 } |
240 virtual bool Skip(int count) { | 239 virtual bool Skip(int count) { |
241 GOOGLE_LOG(FATAL) << "Tests never call this."; | 240 GOOGLE_LOG(FATAL) << "Tests never call this."; |
242 return false; | 241 return false; |
243 } | 242 } |
244 virtual int64 ByteCount() const { return 0; } | 243 virtual int64 ByteCount() const { return 0; } |
245 int count_; | 244 int count_; |
246 } in; | 245 } in; |
247 CodedInputStream input(&in); | 246 CodedInputStream input(&in); |
248 input.ReadTagNoLastTag(); | 247 input.ReadTag(); |
249 EXPECT_TRUE(input.ConsumedEntireMessage()); | 248 EXPECT_TRUE(input.ConsumedEntireMessage()); |
250 } | 249 } |
251 | 250 |
252 TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { | 251 TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { |
253 // Leave one byte at the beginning of the buffer so we can read it | 252 // Leave one byte at the beginning of the buffer so we can read it |
254 // to force the first buffer to be loaded. | 253 // to force the first buffer to be loaded. |
255 buffer_[0] = '\0'; | 254 buffer_[0] = '\0'; |
256 memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size); | 255 memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size); |
257 ArrayInputStream input(buffer_, sizeof(buffer_)); | 256 ArrayInputStream input(buffer_, sizeof(buffer_)); |
258 | 257 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) { | 438 TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) { |
440 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); | 439 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); |
441 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, | 440 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, |
442 kBlockSizes_case); | 441 kBlockSizes_case); |
443 CodedInputStream coded_input(&input); | 442 CodedInputStream coded_input(&input); |
444 | 443 |
445 uint32 value; | 444 uint32 value; |
446 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); | 445 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); |
447 } | 446 } |
448 | 447 |
449 TEST_2D(CodedStreamTest, ReadVarint32Error_LeavesValueInInitializedState, | |
450 kVarintErrorCases, kBlockSizes) { | |
451 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); | |
452 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, | |
453 kBlockSizes_case); | |
454 CodedInputStream coded_input(&input); | |
455 | |
456 uint32 value = 0; | |
457 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); | |
458 // While the specific value following a failure is not critical, we do want to | |
459 // ensure that it doesn't get set to an uninitialized value. (This check fails | |
460 // in MSAN mode if value has been set to an uninitialized value.) | |
461 EXPECT_EQ(value, value); | |
462 } | |
463 | |
464 TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) { | 448 TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) { |
465 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); | 449 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); |
466 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, | 450 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, |
467 kBlockSizes_case); | 451 kBlockSizes_case); |
468 CodedInputStream coded_input(&input); | 452 CodedInputStream coded_input(&input); |
469 | 453 |
470 uint64 value; | 454 uint64 value; |
471 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); | 455 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); |
472 } | 456 } |
473 | 457 |
474 TEST_2D(CodedStreamTest, ReadVarint64Error_LeavesValueInInitializedState, | |
475 kVarintErrorCases, kBlockSizes) { | |
476 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); | |
477 ArrayInputStream input(buffer_, kVarintErrorCases_case.size, | |
478 kBlockSizes_case); | |
479 CodedInputStream coded_input(&input); | |
480 | |
481 uint64 value = 0; | |
482 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); | |
483 // While the specific value following a failure is not critical, we do want to | |
484 // ensure that it doesn't get set to an uninitialized value. (This check fails | |
485 // in MSAN mode if value has been set to an uninitialized value.) | |
486 EXPECT_EQ(value, value); | |
487 } | |
488 | |
489 // ------------------------------------------------------------------- | 458 // ------------------------------------------------------------------- |
490 // VarintSize | 459 // VarintSize |
491 | 460 |
492 struct VarintSizeCase { | 461 struct VarintSizeCase { |
493 uint64 value; | 462 uint64 value; |
494 int size; | 463 int size; |
495 }; | 464 }; |
496 | 465 |
497 inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) { | 466 inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) { |
498 return os << c.value; | 467 return os << c.value; |
(...skipping 19 matching lines...) Expand all Loading... |
518 EXPECT_EQ(kVarintSizeCases_case.size, | 487 EXPECT_EQ(kVarintSizeCases_case.size, |
519 CodedOutputStream::VarintSize32( | 488 CodedOutputStream::VarintSize32( |
520 static_cast<uint32>(kVarintSizeCases_case.value))); | 489 static_cast<uint32>(kVarintSizeCases_case.value))); |
521 } | 490 } |
522 | 491 |
523 TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) { | 492 TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) { |
524 EXPECT_EQ(kVarintSizeCases_case.size, | 493 EXPECT_EQ(kVarintSizeCases_case.size, |
525 CodedOutputStream::VarintSize64(kVarintSizeCases_case.value)); | 494 CodedOutputStream::VarintSize64(kVarintSizeCases_case.value)); |
526 } | 495 } |
527 | 496 |
528 TEST_F(CodedStreamTest, VarintSize32PowersOfTwo) { | |
529 int expected = 1; | |
530 for (int i = 1; i < 32; i++) { | |
531 if (i % 7 == 0) { | |
532 expected += 1; | |
533 } | |
534 EXPECT_EQ(expected, | |
535 CodedOutputStream::VarintSize32(static_cast<uint32>(0x1u << i))); | |
536 } | |
537 } | |
538 | |
539 TEST_F(CodedStreamTest, VarintSize64PowersOfTwo) { | |
540 int expected = 1; | |
541 for (int i = 1; i < 64; i++) { | |
542 if (i % 7 == 0) { | |
543 expected += 1; | |
544 } | |
545 EXPECT_EQ(expected, CodedOutputStream::VarintSize64( | |
546 static_cast<uint64>(0x1ull << i))); | |
547 } | |
548 } | |
549 | |
550 // ------------------------------------------------------------------- | 497 // ------------------------------------------------------------------- |
551 // Fixed-size int tests | 498 // Fixed-size int tests |
552 | 499 |
553 struct Fixed32Case { | 500 struct Fixed32Case { |
554 uint8 bytes[sizeof(uint32)]; // Encoded bytes. | 501 uint8 bytes[sizeof(uint32)]; // Encoded bytes. |
555 uint32 value; // Parsed value. | 502 uint32 value; // Parsed value. |
556 }; | 503 }; |
557 | 504 |
558 struct Fixed64Case { | 505 struct Fixed64Case { |
559 uint8 bytes[sizeof(uint64)]; // Encoded bytes. | 506 uint8 bytes[sizeof(uint64)]; // Encoded bytes. |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 TEST_F(CodedStreamTest, TotalBytesLimit) { | 1169 TEST_F(CodedStreamTest, TotalBytesLimit) { |
1223 ArrayInputStream input(buffer_, sizeof(buffer_)); | 1170 ArrayInputStream input(buffer_, sizeof(buffer_)); |
1224 CodedInputStream coded_input(&input); | 1171 CodedInputStream coded_input(&input); |
1225 coded_input.SetTotalBytesLimit(16, -1); | 1172 coded_input.SetTotalBytesLimit(16, -1); |
1226 EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit()); | 1173 EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit()); |
1227 | 1174 |
1228 string str; | 1175 string str; |
1229 EXPECT_TRUE(coded_input.ReadString(&str, 16)); | 1176 EXPECT_TRUE(coded_input.ReadString(&str, 16)); |
1230 EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit()); | 1177 EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit()); |
1231 | 1178 |
1232 std::vector<string> errors; | 1179 vector<string> errors; |
1233 | 1180 |
1234 { | 1181 { |
1235 ScopedMemoryLog error_log; | 1182 ScopedMemoryLog error_log; |
1236 EXPECT_FALSE(coded_input.ReadString(&str, 1)); | 1183 EXPECT_FALSE(coded_input.ReadString(&str, 1)); |
1237 errors = error_log.GetMessages(ERROR); | 1184 errors = error_log.GetMessages(ERROR); |
1238 } | 1185 } |
1239 | 1186 |
1240 ASSERT_EQ(1, errors.size()); | 1187 ASSERT_EQ(1, errors.size()); |
1241 EXPECT_PRED_FORMAT2(testing::IsSubstring, | 1188 EXPECT_PRED_FORMAT2(testing::IsSubstring, |
1242 "A protocol message was rejected because it was too big", errors[0]); | 1189 "A protocol message was rejected because it was too big", errors[0]); |
(...skipping 13 matching lines...) Expand all Loading... |
1256 // Set both total_bytes_limit and a regular limit at 16 bytes. | 1203 // Set both total_bytes_limit and a regular limit at 16 bytes. |
1257 coded_input.SetTotalBytesLimit(16, -1); | 1204 coded_input.SetTotalBytesLimit(16, -1); |
1258 CodedInputStream::Limit limit = coded_input.PushLimit(16); | 1205 CodedInputStream::Limit limit = coded_input.PushLimit(16); |
1259 | 1206 |
1260 // Read 16 bytes. | 1207 // Read 16 bytes. |
1261 string str; | 1208 string str; |
1262 EXPECT_TRUE(coded_input.ReadString(&str, 16)); | 1209 EXPECT_TRUE(coded_input.ReadString(&str, 16)); |
1263 | 1210 |
1264 // Read a tag. Should fail, but report being a valid endpoint since it's | 1211 // Read a tag. Should fail, but report being a valid endpoint since it's |
1265 // a regular limit. | 1212 // a regular limit. |
1266 EXPECT_EQ(0, coded_input.ReadTagNoLastTag()); | 1213 EXPECT_EQ(0, coded_input.ReadTag()); |
1267 EXPECT_TRUE(coded_input.ConsumedEntireMessage()); | 1214 EXPECT_TRUE(coded_input.ConsumedEntireMessage()); |
1268 | 1215 |
1269 // Pop the limit. | 1216 // Pop the limit. |
1270 coded_input.PopLimit(limit); | 1217 coded_input.PopLimit(limit); |
1271 | 1218 |
1272 // Read a tag. Should fail, and report *not* being a valid endpoint, since | 1219 // Read a tag. Should fail, and report *not* being a valid endpoint, since |
1273 // this time we're hitting the total bytes limit. | 1220 // this time we're hitting the total bytes limit. |
1274 EXPECT_EQ(0, coded_input.ReadTagNoLastTag()); | 1221 EXPECT_EQ(0, coded_input.ReadTag()); |
1275 EXPECT_FALSE(coded_input.ConsumedEntireMessage()); | 1222 EXPECT_FALSE(coded_input.ConsumedEntireMessage()); |
1276 } | 1223 } |
1277 | 1224 |
1278 // This method is used by the tests below. | 1225 // This method is used by the tests below. |
1279 // It constructs a CodedInputStream with the given limits and tries to read 2KiB | 1226 // It constructs a CodedInputStream with the given limits and tries to read 2KiB |
1280 // of data from it. Then it returns the logged errors and warnings in the given | 1227 // of data from it. Then it returns the logged errors and warnings in the given |
1281 // vectors. | 1228 // vectors. |
1282 void CodedStreamTest::SetupTotalBytesLimitWarningTest( | 1229 void CodedStreamTest::SetupTotalBytesLimitWarningTest( |
1283 int total_bytes_limit, int warning_threshold, | 1230 int total_bytes_limit, int warning_threshold, |
1284 std::vector<string>* out_errors, std::vector<string>* out_warnings) { | 1231 vector<string>* out_errors, vector<string>* out_warnings) { |
1285 ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128); | 1232 ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128); |
1286 | 1233 |
1287 ScopedMemoryLog scoped_log; | 1234 ScopedMemoryLog scoped_log; |
1288 { | 1235 { |
1289 CodedInputStream input(&raw_input); | 1236 CodedInputStream input(&raw_input); |
1290 input.SetTotalBytesLimit(total_bytes_limit, warning_threshold); | 1237 input.SetTotalBytesLimit(total_bytes_limit, warning_threshold); |
1291 string str; | 1238 string str; |
1292 EXPECT_TRUE(input.ReadString(&str, 2048)); | 1239 EXPECT_TRUE(input.ReadString(&str, 2048)); |
1293 } | 1240 } |
1294 | 1241 |
1295 *out_errors = scoped_log.GetMessages(ERROR); | 1242 *out_errors = scoped_log.GetMessages(ERROR); |
1296 *out_warnings = scoped_log.GetMessages(WARNING); | 1243 *out_warnings = scoped_log.GetMessages(WARNING); |
1297 } | 1244 } |
1298 | 1245 |
1299 TEST_F(CodedStreamTest, TotalBytesLimitWarning) { | 1246 TEST_F(CodedStreamTest, TotalBytesLimitWarning) { |
1300 std::vector<string> errors; | 1247 vector<string> errors; |
1301 std::vector<string> warnings; | 1248 vector<string> warnings; |
1302 SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings); | 1249 SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings); |
1303 | 1250 |
1304 EXPECT_EQ(0, errors.size()); | 1251 EXPECT_EQ(0, errors.size()); |
1305 | 1252 |
1306 EXPECT_EQ(1, warnings.size()); | 1253 ASSERT_EQ(2, warnings.size()); |
| 1254 EXPECT_PRED_FORMAT2(testing::IsSubstring, |
| 1255 "Reading dangerously large protocol message. If the message turns out to " |
| 1256 "be larger than 10240 bytes, parsing will be halted for security reasons.", |
| 1257 warnings[0]); |
1307 EXPECT_PRED_FORMAT2(testing::IsSubstring, | 1258 EXPECT_PRED_FORMAT2(testing::IsSubstring, |
1308 "The total number of bytes read was 2048", | 1259 "The total number of bytes read was 2048", |
1309 warnings[0]); | 1260 warnings[1]); |
1310 } | 1261 } |
1311 | 1262 |
1312 TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) { | 1263 TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) { |
1313 std::vector<string> errors; | 1264 vector<string> errors; |
1314 std::vector<string> warnings; | 1265 vector<string> warnings; |
1315 | 1266 |
1316 // Test with -1 | 1267 // Test with -1 |
1317 SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings); | 1268 SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings); |
1318 EXPECT_EQ(0, errors.size()); | 1269 EXPECT_EQ(0, errors.size()); |
1319 EXPECT_EQ(0, warnings.size()); | 1270 EXPECT_EQ(0, warnings.size()); |
1320 | 1271 |
1321 // Test again with -2, expecting the same result | 1272 // Test again with -2, expecting the same result |
1322 SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings); | 1273 SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings); |
1323 EXPECT_EQ(0, errors.size()); | 1274 EXPECT_EQ(0, errors.size()); |
1324 EXPECT_EQ(0, warnings.size()); | 1275 EXPECT_EQ(0, warnings.size()); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 private: | 1354 private: |
1404 char buffer_[1024]; | 1355 char buffer_[1024]; |
1405 int64 buffer_count_; | 1356 int64 buffer_count_; |
1406 }; | 1357 }; |
1407 | 1358 |
1408 TEST_F(CodedStreamTest, InputOver2G) { | 1359 TEST_F(CodedStreamTest, InputOver2G) { |
1409 // CodedInputStream should gracefully handle input over 2G and call | 1360 // CodedInputStream should gracefully handle input over 2G and call |
1410 // input.BackUp() with the correct number of bytes on destruction. | 1361 // input.BackUp() with the correct number of bytes on destruction. |
1411 ReallyBigInputStream input; | 1362 ReallyBigInputStream input; |
1412 | 1363 |
1413 std::vector<string> errors; | 1364 vector<string> errors; |
1414 | 1365 |
1415 { | 1366 { |
1416 ScopedMemoryLog error_log; | 1367 ScopedMemoryLog error_log; |
1417 CodedInputStream coded_input(&input); | 1368 CodedInputStream coded_input(&input); |
1418 string str; | 1369 string str; |
1419 EXPECT_TRUE(coded_input.ReadString(&str, 512)); | 1370 EXPECT_TRUE(coded_input.ReadString(&str, 512)); |
1420 EXPECT_TRUE(coded_input.ReadString(&str, 1024)); | 1371 EXPECT_TRUE(coded_input.ReadString(&str, 1024)); |
1421 errors = error_log.GetMessages(ERROR); | 1372 errors = error_log.GetMessages(ERROR); |
1422 } | 1373 } |
1423 | 1374 |
1424 EXPECT_EQ(INT_MAX - 512, input.backup_amount_); | 1375 EXPECT_EQ(INT_MAX - 512, input.backup_amount_); |
1425 EXPECT_EQ(0, errors.size()); | 1376 EXPECT_EQ(0, errors.size()); |
1426 } | 1377 } |
1427 | 1378 |
1428 // =================================================================== | 1379 // =================================================================== |
1429 | 1380 |
1430 | 1381 |
1431 } // namespace | 1382 } // namespace |
1432 } // namespace io | 1383 } // namespace io |
1433 } // namespace protobuf | 1384 } // namespace protobuf |
1434 } // namespace google | 1385 } // namespace google |
OLD | NEW |