| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2009, Google Inc. | 2  * Copyright 2009, Google Inc. | 
| 3  * All rights reserved. | 3  * All rights reserved. | 
| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 56 const int kUserIDOffset           = 108; | 56 const int kUserIDOffset           = 108; | 
| 57 const int kGroupIDOffset          = 116; | 57 const int kGroupIDOffset          = 116; | 
| 58 const int kFileSizeOffset         = 124; | 58 const int kFileSizeOffset         = 124; | 
| 59 const int kModifyTimeOffset       = 136; | 59 const int kModifyTimeOffset       = 136; | 
| 60 const int kHeaderCheckSumOffset   = 148; | 60 const int kHeaderCheckSumOffset   = 148; | 
| 61 const int kLinkFlagOffset         = 156; | 61 const int kLinkFlagOffset         = 156; | 
| 62 const int kMagicOffset            = 257; | 62 const int kMagicOffset            = 257; | 
| 63 const int kUserNameOffset         = 265; | 63 const int kUserNameOffset         = 265; | 
| 64 const int kGroupNameOffset        = 297; | 64 const int kGroupNameOffset        = 297; | 
| 65 | 65 | 
|  | 66 const char *kLongLink = "././@LongLink"; | 
| 66 const char *kDirName1 = "test/apples/"; | 67 const char *kDirName1 = "test/apples/"; | 
| 67 const char *kDirName2 = "test/oranges/"; | 68 const char *kDirName2 = "test/oranges/"; | 
| 68 const char *kFileName1 = "test/apples/file1"; | 69 const char *kFileName1 = "test/apples/file1"; | 
| 69 const char *kFileName2 = "test/apples/file2"; | 70 const char *kFileName2 = "test/apples/file2"; | 
| 70 const char *kFileName3 = "test/oranges/file3"; | 71 const char *kFileName3 = "test/oranges/file3"; | 
|  | 72 const char *kFileName4 = | 
|  | 73     "ThisIsAFilenameLongerThen100CharsThisIsAFilenameLongerThen100Chars" | 
|  | 74     "ThisIsAFilenameLongerThen100CharsThisIsAFilenameLongerThen100Chars"; | 
| 71 | 75 | 
| 72 // The first file is less than one block in size | 76 // The first file is less than one block in size | 
| 73 const char *kFileContents1 = | 77 const char *kFileContents1 = | 
| 74     "The cellphone is the world’s most ubiquitous computer.\n" | 78     "The cellphone is the world most ubiquitous computer.\n" | 
| 75     "The four billion cellphones in use around the globe carry personal\n" | 79     "The four billion cellphones in use around the globe carry personal\n" | 
| 76     "information, provide access to the Web and are being used more and more\n" | 80     "information, provide access to the Web and are being used more and more\n" | 
| 77     "to navigate the real world. And as cellphones change how we live,\n" | 81     "to navigate the real world. And as cellphones change how we live,\n" | 
| 78     "computer scientists say, they are also changing\n" | 82     "computer scientists say, they are also changing\n" | 
| 79     "how we think about information\n"; | 83     "how we think about information\n"; | 
| 80 | 84 | 
| 81 // The 2nd file takes two blocks | 85 // The 2nd file takes two blocks | 
| 82 const char *kFileContents2 = | 86 const char *kFileContents2 = | 
| 83     "From Hong Kong to eastern Europe to Wall Street, financial gloom was\n" | 87     "From Hong Kong to eastern Europe to Wall Street, financial gloom was\n" | 
| 84     "everywhere on Tuesday.\n" | 88     "everywhere on Tuesday.\n" | 
| 85     "Stock markets around the world staggered lower. In New York,\n" | 89     "Stock markets around the world staggered lower. In New York,\n" | 
| 86     "the Dow fell more than 3 percent, coming within sight of its worst\n" | 90     "the Dow fell more than 3 percent, coming within sight of its worst\n" | 
| 87     "levels since the credit crisis erupted. Financial shares were battered.\n" | 91     "levels since the credit crisis erupted. Financial shares were battered.\n" | 
| 88     "And rattled investors clamored to buy rainy-day investments like gold\n" | 92     "And rattled investors clamored to buy rainy-day investments like gold\n" | 
| 89     "and Treasury debt. It was a global wave of selling spurred by rising\n" | 93     "and Treasury debt. It was a global wave of selling spurred by rising\n" | 
| 90     "worries about how banks, automakers — entire countries — would fare\n" | 94     "worries about how banks, automakers entire countries would fare\n" | 
| 91     "in a deepening global downturn.\n" | 95     "in a deepening global downturn.\n" | 
| 92     "'Nobody believes it’s going get better yet,' said Howard Silverblatt,\n" | 96     "'Nobody believes it&'s going get better yet,' said Howard Silverblatt,\n" | 
| 93     "senior index analyst at Standard & Poor’s. 'Do you see that light at\n" | 97     "senior index analyst at Standard & Poors. 'Do you see that light at\n" | 
| 94     "the end of the tunnel? Any kind of light? Right now, it’s not there'\n" | 98     "the end of the tunnel? Any kind of light? Right now, it's not there'\n" | 
| 95     "yet.\n"; | 99     "yet.\n"; | 
| 96 | 100 | 
| 97 // The 3rd file takes one block | 101 // The 3rd file takes one block | 
| 98 const char *kFileContents3 = "nothing much here...\n"; | 102 const char *kFileContents3 = "nothing much here...\n"; | 
| 99 | 103 | 
| 100 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 104 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
| 101 // Receives the tar bytestream from the TarGenerator. | 105 // Receives the tar bytestream from the TarGenerator. | 
| 102 // We validate the bytestream as it comes in... | 106 // We validate the bytestream as it comes in... | 
| 103 // | 107 // | 
| 104 class CallbackClient : public StreamProcessor { | 108 class CallbackClient : public StreamProcessor { | 
| 105  public: | 109  public: | 
| 106   // states for state machine, with each state representing one | 110   // states for state machine, with each state representing one | 
| 107   // received block of the tar stream. | 111   // received block of the tar stream. | 
| 108   // The blocks can be either headers (for directories and files) | 112   // The blocks can be either headers (for directories and files) | 
| 109   // or data blocks (zero padded at the end to make a full block) | 113   // or data blocks (zero padded at the end to make a full block) | 
| 110   enum ValidationState { | 114   enum ValidationState { | 
| 111     VALIDATE_DIRECTORY_HEADER1,  // header 1 is directory so no file data | 115     VALIDATE_DIRECTORY_HEADER1,  // header 1 is directory so no file data | 
| 112     VALIDATE_FILE_HEADER1, | 116     VALIDATE_FILE_HEADER1, | 
| 113     VALIDATE_FILE_DATA1,         // 1st file takes one block | 117     VALIDATE_FILE_DATA1,         // 1st file takes one block | 
| 114     VALIDATE_FILE_HEADER2, | 118     VALIDATE_FILE_HEADER2, | 
| 115     VALIDATE_FILE_DATA2_BLOCK1,  // 2nd file takes two blocks | 119     VALIDATE_FILE_DATA2_BLOCK1,  // 2nd file takes two blocks | 
| 116     VALIDATE_FILE_DATA2_BLOCK2, | 120     VALIDATE_FILE_DATA2_BLOCK2, | 
| 117     VALIDATE_DIRECTORY_HEADER2,  // 3rd file is in another directory | 121     VALIDATE_DIRECTORY_HEADER2,  // 3rd file is in another directory | 
| 118     VALIDATE_FILE_HEADER3, | 122     VALIDATE_FILE_HEADER3, | 
| 119     VALIDATE_FILE_DATA3, | 123     VALIDATE_FILE_DATA3, | 
|  | 124     VALIDATE_FILE_LONGNAME_HEADER4,  // 4th file has a long name. | 
|  | 125     VALIDATE_FILE_LONGNAME_DATA4, | 
|  | 126     VALIDATE_FILE_HEADER4, | 
|  | 127     VALIDATE_FILE_DATA4, | 
| 120     FINISHED | 128     FINISHED | 
| 121   }; | 129   }; | 
| 122 | 130 | 
| 123   CallbackClient() | 131   CallbackClient() | 
| 124       : state_(VALIDATE_DIRECTORY_HEADER1), | 132       : state_(VALIDATE_DIRECTORY_HEADER1), | 
| 125         total_bytes_received_(0), | 133         total_bytes_received_(0), | 
| 126         memory_block_(kBlockSize), | 134         memory_block_(kBlockSize), | 
| 127         write_stream_(memory_block_, kBlockSize) { | 135         write_stream_(memory_block_, kBlockSize) { | 
| 128   } | 136   } | 
| 129 | 137 | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 206           break; | 214           break; | 
| 207 | 215 | 
| 208         case VALIDATE_FILE_HEADER3: | 216         case VALIDATE_FILE_HEADER3: | 
| 209           ValidateHeader(memory_block_, kFileName3, strlen(kFileContents3)); | 217           ValidateHeader(memory_block_, kFileName3, strlen(kFileContents3)); | 
| 210           break; | 218           break; | 
| 211 | 219 | 
| 212         case VALIDATE_FILE_DATA3: | 220         case VALIDATE_FILE_DATA3: | 
| 213           ValidateData(memory_block_, kFileContents3); | 221           ValidateData(memory_block_, kFileContents3); | 
| 214           break; | 222           break; | 
| 215 | 223 | 
|  | 224         case VALIDATE_FILE_LONGNAME_HEADER4: | 
|  | 225           ValidateHeader(memory_block_, kLongLink, strlen(kFileName4)); | 
|  | 226           break; | 
|  | 227 | 
|  | 228         case VALIDATE_FILE_LONGNAME_DATA4: | 
|  | 229           ValidateData(memory_block_, kFileName4); | 
|  | 230           break; | 
|  | 231 | 
|  | 232         case VALIDATE_FILE_HEADER4: { | 
|  | 233           String first_99_chars(kFileName4, 99); | 
|  | 234           ValidateHeader(memory_block_, first_99_chars.c_str(), | 
|  | 235                          strlen(kFileContents3)); | 
|  | 236           break; | 
|  | 237         } | 
|  | 238 | 
|  | 239         case VALIDATE_FILE_DATA4: | 
|  | 240           ValidateData(memory_block_, kFileContents3); | 
|  | 241           break; | 
|  | 242 | 
| 216         case FINISHED: | 243         case FINISHED: | 
| 217           break; | 244           break; | 
| 218       } | 245       } | 
| 219 | 246 | 
| 220       // Advance to the next state | 247       // Advance to the next state | 
| 221       ++state_; | 248       ++state_; | 
| 222 | 249 | 
| 223       // So next time we write, we start at beginning of buffer | 250       // So next time we write, we start at beginning of buffer | 
| 224       write_stream_.Seek(0); | 251       write_stream_.Seek(0); | 
| 225     } | 252     } | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 309   EXPECT_EQ(0, header[kFileSizeOffset + 11]); | 336   EXPECT_EQ(0, header[kFileSizeOffset + 11]); | 
| 310 | 337 | 
| 311   EXPECT_TRUE(IsOctalString(header + kModifyTimeOffset)); | 338   EXPECT_TRUE(IsOctalString(header + kModifyTimeOffset)); | 
| 312   EXPECT_EQ(0, header[kModifyTimeOffset + 11]); | 339   EXPECT_EQ(0, header[kModifyTimeOffset + 11]); | 
| 313 | 340 | 
| 314   EXPECT_TRUE(IsOctalString(header + kHeaderCheckSumOffset)); | 341   EXPECT_TRUE(IsOctalString(header + kHeaderCheckSumOffset)); | 
| 315   EXPECT_EQ(0, header[kHeaderCheckSumOffset + 6]); | 342   EXPECT_EQ(0, header[kHeaderCheckSumOffset + 6]); | 
| 316 | 343 | 
| 317   // For now we only have directories '5' or normal files '0' | 344   // For now we only have directories '5' or normal files '0' | 
| 318   int link_flag = header[kLinkFlagOffset]; | 345   int link_flag = header[kLinkFlagOffset]; | 
| 319   EXPECT_TRUE(link_flag == '0' || link_flag == '5'); | 346   EXPECT_TRUE(link_flag == '0' || link_flag == '5' || link_flag == 'L'); | 
| 320 | 347 | 
| 321   EXPECT_EQ(0, strcmp((const char*)header + kMagicOffset, "ustar  ")); | 348   EXPECT_EQ(0, strcmp((const char*)header + kMagicOffset, "ustar  ")); | 
| 322 | 349 | 
| 323   EXPECT_EQ(0, header[kUserNameOffset + 31]); | 350   EXPECT_EQ(0, header[kUserNameOffset + 31]); | 
| 324   EXPECT_EQ(0, header[kGroupNameOffset + 31]); | 351   EXPECT_EQ(0, header[kGroupNameOffset + 31]); | 
| 325 | 352 | 
| 326   // Validate checksum | 353   // Validate checksum | 
| 327   int checksum = ComputeCheckSum(header); | 354   int checksum = ComputeCheckSum(header); | 
| 328   int header_checksum; | 355   int header_checksum; | 
| 329   sscanf((const char*)header + kHeaderCheckSumOffset, "%o", &header_checksum); | 356   sscanf((const char*)header + kHeaderCheckSumOffset, "%o", &header_checksum); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 350 // Creates a tar file with three files in two directories | 377 // Creates a tar file with three files in two directories | 
| 351 // | 378 // | 
| 352 TEST_F(TarGeneratorTest, CreateSimpleArchive) { | 379 TEST_F(TarGeneratorTest, CreateSimpleArchive) { | 
| 353   CallbackClient client; | 380   CallbackClient client; | 
| 354   TarGenerator generator(&client); | 381   TarGenerator generator(&client); | 
| 355 | 382 | 
| 356   const int kFileLength1 = strlen(kFileContents1); | 383   const int kFileLength1 = strlen(kFileContents1); | 
| 357   const int kFileLength2 = strlen(kFileContents2); | 384   const int kFileLength2 = strlen(kFileContents2); | 
| 358   const int kFileLength3 = strlen(kFileContents3); | 385   const int kFileLength3 = strlen(kFileContents3); | 
| 359 | 386 | 
| 360   generator.AddFile(kFileName1, kFileLength1); | 387   EXPECT_TRUE(generator.AddFile(kFileName1, kFileLength1)); | 
| 361   MemoryReadStream file1_stream(reinterpret_cast<const uint8*>(kFileContents1), | 388   MemoryReadStream file1_stream(reinterpret_cast<const uint8*>(kFileContents1), | 
| 362                                 kFileLength1); | 389                                 kFileLength1); | 
| 363   generator.AddFileBytes(&file1_stream, kFileLength1); | 390   generator.AddFileBytes(&file1_stream, kFileLength1); | 
| 364 | 391 | 
| 365   generator.AddFile(kFileName2, kFileLength2); | 392   EXPECT_TRUE(generator.AddFile(kFileName2, kFileLength2)); | 
| 366   MemoryReadStream file2_stream(reinterpret_cast<const uint8*>(kFileContents2), | 393   MemoryReadStream file2_stream(reinterpret_cast<const uint8*>(kFileContents2), | 
| 367                                 kFileLength2); | 394                                 kFileLength2); | 
| 368   generator.AddFileBytes(&file2_stream, kFileLength2); | 395   generator.AddFileBytes(&file2_stream, kFileLength2); | 
| 369 | 396 | 
| 370   generator.AddFile(kFileName3, kFileLength3); | 397   EXPECT_TRUE(generator.AddFile(kFileName3, kFileLength3)); | 
| 371   MemoryReadStream file3_stream(reinterpret_cast<const uint8*>(kFileContents3), | 398   MemoryReadStream file3_stream(reinterpret_cast<const uint8*>(kFileContents3), | 
| 372                                 kFileLength3); | 399                                 kFileLength3); | 
| 373   generator.AddFileBytes(&file3_stream, kFileLength3); | 400   generator.AddFileBytes(&file3_stream, kFileLength3); | 
|  | 401   EXPECT_TRUE(generator.AddFile(kFileName4, kFileLength3)); | 
|  | 402   MemoryReadStream file4_stream(reinterpret_cast<const uint8*>(kFileContents3), | 
|  | 403                                 kFileLength3); | 
|  | 404   generator.AddFileBytes(&file4_stream, kFileLength3); | 
| 374 | 405 | 
| 375   generator.Finalize(); | 406   generator.Finalize(); | 
| 376 | 407 | 
| 377   // Verify that the tar byte stream produced is exactly divisible by | 408   // Verify that the tar byte stream produced is exactly divisible by | 
| 378   // the block size | 409   // the block size | 
| 379   size_t bytes_received = client.GetTotalBytesReceived(); | 410   size_t bytes_received = client.GetTotalBytesReceived(); | 
| 380   EXPECT_EQ(0, bytes_received % kBlockSize); | 411   EXPECT_EQ(0, bytes_received % kBlockSize); | 
| 381 | 412 | 
| 382   // Make sure the state machine is in the expected state | 413   // Make sure the state machine is in the expected state | 
| 383   EXPECT_EQ(CallbackClient::FINISHED, client.GetState()); | 414   EXPECT_EQ(CallbackClient::FINISHED, client.GetState()); | 
| 384 } | 415 } | 
| 385 | 416 | 
| 386 }  // namespace | 417 }  // namespace | 
| OLD | NEW | 
|---|