aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avast.com>2023-01-16 06:46:34 +0100
committerLadislav Zezula <ladislav.zezula@avast.com>2023-01-16 06:46:34 +0100
commit6f89c7ba8530c37f1f5a6048406cb18c40e5a458 (patch)
tree1635bdc43c7cb26b89c379ab3703ac322bf137ba /test
parent05d0f04c07a56618bf0a6a0652622b5e9a69d8ce (diff)
Fixed bug, refactor TLogHelper.cpp
Diffstat (limited to 'test')
-rw-r--r--test/StormTest.cpp170
-rw-r--r--test/TLogHelper.cpp722
-rw-r--r--test/stormlib-test.txt12
3 files changed, 479 insertions, 425 deletions
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index addbdfc..97a3663 100644
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -998,7 +998,7 @@ static DWORD VerifyFilePosition(
{
if(ByteOffset != ExpectedPosition)
{
- pLogger->PrintMessage(_T("The file position is different than expected (expected: ") I64u_t _T(", current: ") I64u_t, ExpectedPosition, ByteOffset);
+ pLogger->PrintMessage(_T("The file position is different than expected (expected: ") fmt_I64u_t _T(", current: ") fmt_I64u_t, ExpectedPosition, ByteOffset);
dwErrCode = ERROR_FILE_CORRUPT;
}
}
@@ -1304,7 +1304,7 @@ static void WINAPI CompactCallback(void * pvUserData, DWORD dwWork, ULONGLONG By
if(pLogger != NULL)
pLogger->PrintProgress("%s (%I64u of %I64u) ...", szWork, BytesDone, TotalBytes);
else
- printf("%s (" I64u_a " of " I64u_a ") ... \r", szWork, BytesDone, TotalBytes);
+ printf("%s (" fmt_I64u_a " of " fmt_I64u_a ") ... \r", szWork, BytesDone, TotalBytes);
}
}
@@ -1563,7 +1563,7 @@ static DWORD CompareTwoLocalFilesRR(
BytesToRead = (DWORD)(RandomNumber % cbBuffer);
// Show the progress message
- pLogger->PrintProgress("Comparing file: Offset: " I64u_a ", Length: %u", ByteOffset, BytesToRead);
+ pLogger->PrintProgress("Comparing file: Offset: " fmt_I64u_a ", Length: %u", ByteOffset, BytesToRead);
// Only perform read if the byte offset is below
if(ByteOffset < FileSize1)
@@ -1579,7 +1579,7 @@ static DWORD CompareTwoLocalFilesRR(
if(!CompareBlocks(pbBuffer1, pbBuffer2, BytesToRead, &Difference))
{
- pLogger->PrintMessage("Difference at %u (Offset " I64X_a ", Length %X)", Difference, ByteOffset, BytesToRead);
+ pLogger->PrintMessage("Difference at %u (Offset " fmt_I64X_a ", Length %X)", Difference, ByteOffset, BytesToRead);
dwErrCode = ERROR_FILE_CORRUPT;
break;
}
@@ -2271,7 +2271,7 @@ static void WINAPI TestReadFile_DownloadCallback(
TLogHelper * pLogger = (TLogHelper *)UserData;
if(ByteOffset != 0 && DataLength != 0)
- pLogger->PrintProgress("Downloading data (offset: " I64X_a ", length: %X)", ByteOffset, DataLength);
+ pLogger->PrintProgress("Downloading data (offset: " fmt_I64X_a ", length: %X)", ByteOffset, DataLength);
else
pLogger->PrintProgress("Download complete.");
}
@@ -4346,68 +4346,69 @@ static const TEST_INFO TestList_MasterMirror[] =
static const TEST_INFO Test_Mpqs[] =
{
+
// Correct or damaged archives
- //{_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"},
- //{_T("MPQ_1997_v1_patch_rt_SC1B.mpq"), NULL, TEST_DATA("43fe7d362955be68a708486e399576a7", 10)}, // From Starcraft 1 BETA
- //{_T("MPQ_1997_v1_StarDat_SC1B.mpq"), NULL, TEST_DATA("0094b23f28cfff7386071ef3bd19a577", 2468)}, // From Starcraft 1 BETA
- //{_T("MPQ_1997_v1_INSTALL_SC1B.EXE_"), NULL, TEST_DATA("3248460c89bb6f8e3b8fc3e08de7ffbb", 79)}, // From Starcraft 1 BETA
- //{_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, TEST_DATA("255d87a62f3c9518f72cf723a1818946", 221), "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016)
- //{_T("MPQ_2018_v1_icon_error.w3m"), NULL, TEST_DATA("fcefa25fb50c391e8714f2562d1e10ff", 19), "file00000002.blp"},
- //{_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), Bliz, TEST_DATA("5ef18ef9a26b5704d8d46a344d976c89", 2)}, // File whose archive's (signature) file has flags = 0x90000000
- //{_T("MPQ_2012_v2_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (found in WoW cache - it's just a header)
- //{_T("MPQ_2013_v4_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (created artificially - it's just a header)
- //{_T("MPQ_2013_v4_patch-base-16357.MPQ"), NULL, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 1)}, // Empty archive (found in WoW cache - it's just a header)
- //{_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"), NULL, TEST_DATA("be4b49ecc3942d1957249f9da0021659", 6)}, // Empty archive (with invalid HET entry count)
- //{_T("MPQ_2002_v1_BlockTableCut.MPQ"), NULL, TEST_DATA("a9499ab74d939303d8cda7c397c36275", 287)}, // Truncated archive
- //{_T("MPQ_2010_v2_HasUserData.s2ma"), NULL, TEST_DATA("feff9e2c86db716b6ff5ffc906181200", 52)}, // MPQ that actually has user data
- //{_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"), NULL, TEST_DATA("90451b7052eb0f1d6f4bf69b2daff7f5", 116)}, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
- //{_T("MPQ_2020_v1_AHF04patch.mix"), NULL, TEST_DATA("d3c6aac48bc12813ef5ce4ad113e58bf", 2891)}, // MIX file
- //{_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), NULL, TEST_DATA("0c8fc921466f07421a281a05fad08b01", 53)}, // MPQ archive v 3.0 (the only one I know)
- //{_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, TEST_DATA("10e4dcdbe95b7ad731c563ec6b71bc16", 82)}, // Encrypted archive from Starcraft II installer
- //{_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"),0, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 14263)}, // Partial MPQ with compressed hash table
- //{_T("blk4-file://streaming/model.MPQ.0"), NULL, TEST_DATA("e06b00efb2fc7e7469dd8b3b859ae15d", 39914)}, // Archive that is merged with multiple files
-
- //// Protected archives
- //{_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"), NULL, TEST_DATA("b900364cc134a51ddeca21a13697c3ca", 79)},
- //{_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"), NULL, TEST_DATA("db67e894da9de618a1cdf86d02d315ff", 117)},
- //{_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector
- //{_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector
- //{_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"), NULL, TEST_DATA("e55aad2dd33cf68b372ca8e30dcb78a7", 130)}, // Warcraft III map locked by the Spazzler protector
- //{_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"), NULL, TEST_DATA("7b725d87e07a2173c42fe2314b95fa6c", 17)}, // Warcraft III map locked by the BOBA protector
- //{_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"), NULL, TEST_DATA("44111a3edf7645bc44bb1afd3a813576", 1715)},
- //{_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"), NULL, TEST_DATA("b411f9a51a6e9a9a509150c8d66ba359", 92)},
- //{_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"), NULL, TEST_DATA("6e491bd055511435dcb4d9c8baed0516", 4089)}, // Warcraft III map locked by Spazy protector
- //{_T("MPQ_2015_v1_MessListFile.mpq"), NULL, TEST_DATA("15e25d5be124d8ad71519f967997efc2", 8)},
- //{_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"), NULL, TEST_DATA("ad81b43cbd37bbfa27e4bed4c17e6a81", 176)},
- //{_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"), NULL, TEST_DATA("d6e712c275a26dc51f16b3a02f6187df", 228)},
- //{_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"), NULL, TEST_DATA("457cdbf97a9ca41cfe8ea130dafaa0bb", 21)}, // Something like Somj 2.0
- //{_T("MPQ_2016_v1_WME4_4.w3x"), NULL, TEST_DATA("7ec2f4d0f3982d8b12d88bc08ef0c1fb", 640)}, // Protector from China (2016-05-27)
- //{_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"), NULL, TEST_DATA("b6f6d56f4f8aaef04c2c4b1f08881a8b", 16)},
- //{_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"), NULL, TEST_DATA("3c7908b29d3feac9ec952282390a242d", 5027)},
- //{_T("MPQ_2016_v1_KoreanFile.w3m"), NULL, TEST_DATA("805d1f75712472a81c6df27b2a71f946", 18)},
- //{_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"), NULL, TEST_DATA("cbe1fd7ed5ed2fc005fba9beafcefe40", 16334)}, // Protected by PG1.11.973
- //{_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, TEST_DATA("f4d2ee9d85d2c4107e0b2d00ff302dd7", 9086)},
- //{_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, TEST_DATA("f203e3979247a4dbf7f3828695ac810c", 5)},
- //{_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, TEST_DATA("12c0f4e15c7361b7c13acd37a181d83b", 857), "BlueCrystal.mdx"},
- //{_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"), NULL, TEST_DATA("f45392f6523250c943990a017c230b41", 24)}, // Archive that has two fake headers before the real one
- //{_T("MPQ_2020_v4_NP_Protect_1.s2ma"), NULL, TEST_DATA("1a1ea40ac1165bcdb4f2e434edfc7636", 21)}, // SC2 map that is protected by the NP_Protect
- //{_T("MPQ_2020_v4_NP_Protect_2.s2ma"), NULL, TEST_DATA("7d1a379da8bd966da1f4fa6e4646049b", 55)}, // SC2 map that is protected by the NP_Protect
- //{_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_DATA("1c4c13e627658c473e84d94371e31f37", 20)},
- //{_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_DATA("5250975ed917375fc6540d7be436d4de", 114)},
- //{_T("MPQ_2021_v1_CantExtractCHK.scx"), NULL, TEST_DATA("055fd548a789c910d9dd37472ecc1e66", 28)},
- //{_T("MPQ_2022_v1_Sniper.scx"), NULL, TEST_DATA("2e955271b70b79344ad85b698f6ce9d8", 64)}, // Multiple items in hash table for staredit\scenario.chk (locale=0, platform=0)
- //{_T("MPQ_2022_v1_OcOc_Bound_2.scx"), NULL, TEST_DATA("25cad16a2fb4e883767a1f512fc1dce7", 16)},
-
- //// ASI plugins
- //{_T("MPQ_2020_v1_HS0.1.asi"), NULL, TEST_DATA("50cba7460a6e6d270804fb9776a7ec4f", 6022)},
- //{_T("MPQ_2022_v1_hs0.8.asi"), NULL, TEST_DATA("6a40f733428001805bfe6e107ca9aec1", 11352)}, // Items in hash table have platform = 0xFF
- //{_T("MPQ_2022_v1_MoeMoeMod.asi"), NULL, TEST_DATA("89b923c7cde06de48815844a5bbb0ec4", 2578)},
-
- //// MPQ modifications from Chinese games
- //{_T("MPx_2013_v1_LongwuOnline.mpk"), NULL, TEST_DATA("548f7db88284097f7e94c95a08c5bc24", 469)}, // MPK archive from Longwu online
- //{_T("MPx_2013_v1_WarOfTheImmortals.sqp"), WotI, TEST_DATA("a048f37f7c6162a96253d8081722b6d9", 9396)}, // SQP archive from War of the Immortals
- {_T("MPx_2022_v1_Music.mpk"), NULL, TEST_DATA("fc369cff4ff4b573dd024de963e4cdd5", 650)}, // MPK archive from Warriors of the Ghost Valley
- {_T("MPx_2022_v1_Scp.mpk"), NULL, TEST_DATA("9cb453dc159f2e667c14f48957fd9e77", 113)}, // MPK archive from Warriors of the Ghost Valley
+ {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"},
+ {_T("MPQ_1997_v1_patch_rt_SC1B.mpq"), NULL, TEST_DATA("43fe7d362955be68a708486e399576a7", 10)}, // From Starcraft 1 BETA
+ {_T("MPQ_1997_v1_StarDat_SC1B.mpq"), NULL, TEST_DATA("0094b23f28cfff7386071ef3bd19a577", 2468)}, // From Starcraft 1 BETA
+ {_T("MPQ_1997_v1_INSTALL_SC1B.EXE_"), NULL, TEST_DATA("3248460c89bb6f8e3b8fc3e08de7ffbb", 79)}, // From Starcraft 1 BETA
+ {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, TEST_DATA("255d87a62f3c9518f72cf723a1818946", 221), "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016)
+ {_T("MPQ_2018_v1_icon_error.w3m"), NULL, TEST_DATA("fcefa25fb50c391e8714f2562d1e10ff", 19), "file00000002.blp"},
+ {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), Bliz, TEST_DATA("5ef18ef9a26b5704d8d46a344d976c89", 2)}, // File whose archive's (signature) file has flags = 0x90000000
+ {_T("MPQ_2012_v2_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (found in WoW cache - it's just a header)
+ {_T("MPQ_2013_v4_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (created artificially - it's just a header)
+ {_T("MPQ_2013_v4_patch-base-16357.MPQ"), NULL, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 1)}, // Empty archive (found in WoW cache - it's just a header)
+ {_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"), NULL, TEST_DATA("be4b49ecc3942d1957249f9da0021659", 6)}, // Empty archive (with invalid HET entry count)
+ {_T("MPQ_2002_v1_BlockTableCut.MPQ"), NULL, TEST_DATA("a9499ab74d939303d8cda7c397c36275", 287)}, // Truncated archive
+ {_T("MPQ_2010_v2_HasUserData.s2ma"), NULL, TEST_DATA("feff9e2c86db716b6ff5ffc906181200", 52)}, // MPQ that actually has user data
+ {_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"), NULL, TEST_DATA("90451b7052eb0f1d6f4bf69b2daff7f5", 116)}, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
+ {_T("MPQ_2020_v1_AHF04patch.mix"), NULL, TEST_DATA("d3c6aac48bc12813ef5ce4ad113e58bf", 2891)}, // MIX file
+ {_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), NULL, TEST_DATA("0c8fc921466f07421a281a05fad08b01", 53)}, // MPQ archive v 3.0 (the only one I know)
+ {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, TEST_DATA("10e4dcdbe95b7ad731c563ec6b71bc16", 82)}, // Encrypted archive from Starcraft II installer
+ {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"),0, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 14263)}, // Partial MPQ with compressed hash table
+ {_T("blk4-file://streaming/model.MPQ.0"), NULL, TEST_DATA("e06b00efb2fc7e7469dd8b3b859ae15d", 39914)}, // Archive that is merged with multiple files
+
+ // Protected archives
+ {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"), NULL, TEST_DATA("b900364cc134a51ddeca21a13697c3ca", 79)},
+ {_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"), NULL, TEST_DATA("db67e894da9de618a1cdf86d02d315ff", 117)},
+ {_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector
+ {_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector
+ {_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"), NULL, TEST_DATA("e55aad2dd33cf68b372ca8e30dcb78a7", 130)}, // Warcraft III map locked by the Spazzler protector
+ {_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"), NULL, TEST_DATA("7b725d87e07a2173c42fe2314b95fa6c", 17)}, // Warcraft III map locked by the BOBA protector
+ {_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"), NULL, TEST_DATA("44111a3edf7645bc44bb1afd3a813576", 1715)},
+ {_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"), NULL, TEST_DATA("b411f9a51a6e9a9a509150c8d66ba359", 92)},
+ {_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"), NULL, TEST_DATA("6e491bd055511435dcb4d9c8baed0516", 4089)}, // Warcraft III map locked by Spazy protector
+ {_T("MPQ_2015_v1_MessListFile.mpq"), NULL, TEST_DATA("15e25d5be124d8ad71519f967997efc2", 8)},
+ {_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"), NULL, TEST_DATA("ad81b43cbd37bbfa27e4bed4c17e6a81", 176)},
+ {_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"), NULL, TEST_DATA("d6e712c275a26dc51f16b3a02f6187df", 228)},
+ {_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"), NULL, TEST_DATA("457cdbf97a9ca41cfe8ea130dafaa0bb", 21)}, // Something like Somj 2.0
+ {_T("MPQ_2016_v1_WME4_4.w3x"), NULL, TEST_DATA("7ec2f4d0f3982d8b12d88bc08ef0c1fb", 640)}, // Protector from China (2016-05-27)
+ {_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"), NULL, TEST_DATA("b6f6d56f4f8aaef04c2c4b1f08881a8b", 16)},
+ {_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"), NULL, TEST_DATA("3c7908b29d3feac9ec952282390a242d", 5027)},
+ {_T("MPQ_2016_v1_KoreanFile.w3m"), NULL, TEST_DATA("805d1f75712472a81c6df27b2a71f946", 18)},
+ {_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"), NULL, TEST_DATA("cbe1fd7ed5ed2fc005fba9beafcefe40", 16334)}, // Protected by PG1.11.973
+ {_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, TEST_DATA("f4d2ee9d85d2c4107e0b2d00ff302dd7", 9086)},
+ {_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, TEST_DATA("f203e3979247a4dbf7f3828695ac810c", 5)},
+ {_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, TEST_DATA("12c0f4e15c7361b7c13acd37a181d83b", 857), "BlueCrystal.mdx"},
+ {_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"), NULL, TEST_DATA("f45392f6523250c943990a017c230b41", 24)}, // Archive that has two fake headers before the real one
+ {_T("MPQ_2020_v4_NP_Protect_1.s2ma"), NULL, TEST_DATA("1a1ea40ac1165bcdb4f2e434edfc7636", 21)}, // SC2 map that is protected by the NP_Protect
+ {_T("MPQ_2020_v4_NP_Protect_2.s2ma"), NULL, TEST_DATA("7d1a379da8bd966da1f4fa6e4646049b", 55)}, // SC2 map that is protected by the NP_Protect
+ {_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_DATA("1c4c13e627658c473e84d94371e31f37", 20)},
+ {_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_DATA("5250975ed917375fc6540d7be436d4de", 114)},
+ {_T("MPQ_2021_v1_CantExtractCHK.scx"), NULL, TEST_DATA("055fd548a789c910d9dd37472ecc1e66", 28)},
+ {_T("MPQ_2022_v1_Sniper.scx"), NULL, TEST_DATA("2e955271b70b79344ad85b698f6ce9d8", 64)}, // Multiple items in hash table for staredit\scenario.chk (locale=0, platform=0)
+ {_T("MPQ_2022_v1_OcOc_Bound_2.scx"), NULL, TEST_DATA("25cad16a2fb4e883767a1f512fc1dce7", 16)},
+
+ // ASI plugins
+ {_T("MPQ_2020_v1_HS0.1.asi"), NULL, TEST_DATA("50cba7460a6e6d270804fb9776a7ec4f", 6022)},
+ {_T("MPQ_2022_v1_hs0.8.asi"), NULL, TEST_DATA("6a40f733428001805bfe6e107ca9aec1", 11352)}, // Items in hash table have platform = 0xFF
+ {_T("MPQ_2022_v1_MoeMoeMod.asi"), NULL, TEST_DATA("89b923c7cde06de48815844a5bbb0ec4", 2578)},
+
+ // MPQ modifications from Chinese games
+ {_T("MPx_2013_v1_LongwuOnline.mpk"), NULL, TEST_DATA("548f7db88284097f7e94c95a08c5bc24", 469)}, // MPK archive from Longwu online
+ {_T("MPx_2013_v1_WarOfTheImmortals.sqp"), WotI, TEST_DATA("a048f37f7c6162a96253d8081722b6d9", 9396)}, // SQP archive from War of the Immortals
+ {_T("MPx_2022_v1_Music.mpk"), NULL, TEST_DATA("fc369cff4ff4b573dd024de963e4cdd5", 650)}, // MPK archive from Warriors of the Ghost Valley
+ {_T("MPx_2022_v1_Scp.mpk"), NULL, TEST_DATA("9cb453dc159f2e667c14f48957fd9e77", 113)}, // MPK archive from Warriors of the Ghost Valley
{_T("MPx_2022_v1_UI.mpk"), NULL, TEST_DATA("677a36b458d528a3158ced3dfb711e49", 3086)}, // MPK archive from Warriors of the Ghost Valley
};
@@ -4429,6 +4430,13 @@ static const TEST_INFO Patched_Mpqs[] =
//-----------------------------------------------------------------------------
// Main
+#define TEST_COMMAND_LINE
+#define TEST_LOCAL_LISTFILE
+#define TEST_STREAM_OPERATIONS
+#define TEST_MASTER_MIRROR
+#define TEST_SINGLE_MPQS
+#define TEST_PATCHED_MPQS
+
int _tmain(int argc, TCHAR * argv[])
{
DWORD dwErrCode = ERROR_SUCCESS;
@@ -4441,30 +4449,26 @@ int _tmain(int argc, TCHAR * argv[])
printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING);
dwErrCode = InitializeMpqDirectory(argv, argc);
- //
+#ifdef TEST_COMMAND_LINE
// Test-open MPQs from the command line. They must be plain name
// and must be placed in the Test-MPQs folder
- //
-
for(int i = 2; i < argc; i++)
{
TestArchive(argv[i], Bliz, 0, "Scripts\\War3map.j", NULL);
}
+#endif // TEST_COMMAND_LINE
- //
+#ifdef TEST_LOCAL_LISTFILE
// Tests on a local listfile
- //
-
if(dwErrCode == ERROR_SUCCESS)
{
TestOnLocalListFile(_T("FLAT-MAP:ListFile_Blizzard.txt"));
dwErrCode = TestOnLocalListFile(_T("ListFile_Blizzard.txt"));
}
+#endif // TEST_LOCAL_LISTFILE
- //
+#ifdef TEST_STREAM_OPERATIONS
// Test file stream operations
- //
-
if(dwErrCode == ERROR_SUCCESS)
{
for(size_t i = 0; i < _countof(TestList_StreamOps); i++)
@@ -4474,11 +4478,10 @@ int _tmain(int argc, TCHAR * argv[])
break;
}
}
+#endif TEST_STREAM_OPERATIONS
- //
+#ifdef TEST_MASTER_MIRROR
// Test master-mirror reading operations
- //
-
if(dwErrCode == ERROR_SUCCESS)
{
for(size_t i = 0; i < _countof(TestList_MasterMirror); i++)
@@ -4490,11 +4493,10 @@ int _tmain(int argc, TCHAR * argv[])
break;
}
}
+#endif // TEST_MASTER_MIRROR
- //
+#ifdef TEST_SINGLE_MPQS
// Test opening various archives - correct, damaged, protected
- //
-
if(dwErrCode == ERROR_SUCCESS)
{
for(size_t i = 0; i < _countof(Test_Mpqs); i++)
@@ -4508,11 +4510,10 @@ int _tmain(int argc, TCHAR * argv[])
dwErrCode = ERROR_SUCCESS;
}
}
+#endif // TEST_LOCAL_MPQs
- //
+#ifdef TEST_PATCHED_MPQS
// Test opening patched archives - correct, damaged, protected
- //
-
if(dwErrCode == ERROR_SUCCESS)
{
for(size_t i = 0; i < _countof(Patched_Mpqs); i++)
@@ -4527,6 +4528,7 @@ int _tmain(int argc, TCHAR * argv[])
dwErrCode = ERROR_SUCCESS;
}
}
+#endif // TEST_PATCHED_MPQS
// Veryfy SHA1 of each MPQ that we have in the list
if(dwErrCode == ERROR_SUCCESS)
diff --git a/test/TLogHelper.cpp b/test/TLogHelper.cpp
index 3a82368..cdfa692 100644
--- a/test/TLogHelper.cpp
+++ b/test/TLogHelper.cpp
@@ -6,457 +6,503 @@
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
-/* 26.11.13 1.00 Lad The first version of TLogHelper.cpp */
+/* 26.11.13 1.00 Lad Created */
/*****************************************************************************/
//-----------------------------------------------------------------------------
-// Definition of the TLogHelper class
-
-class TLogHelper
-{
- public:
-
- TLogHelper(const char * szNewMainTitle = NULL, const TCHAR * szNewSubTitle1 = NULL, const TCHAR * szNewSubTitle2 = NULL);
- ~TLogHelper();
-
-#if defined(UNICODE) || defined(UNICODE)
- // TCHAR-based functions. They are only needed on UNICODE builds.
- // On ANSI builds is TCHAR = char, so we don't need them at all
- int PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine);
- void PrintProgress(const TCHAR * szFormat, ...);
- void PrintMessage(const TCHAR * szFormat, ...);
- int PrintErrorVa(const TCHAR * szFormat, ...);
- int PrintError(const TCHAR * szFormat, const TCHAR * szFileName = NULL);
-#endif // defined(UNICODE) || defined(UNICODE)
-
- // ANSI functions
- DWORD PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine);
- void PrintProgress(const char * szFormat, ...);
- void PrintMessage(const char * szFormat, ...);
- DWORD PrintErrorVa(const char * szFormat, ...);
- DWORD PrintError(const char * szFormat, const char * szFileName = NULL);
-
- // Print final verdict
- DWORD PrintVerdict(DWORD dwErrCode = ERROR_SUCCESS);
-
- const char * UserString;
- unsigned int UserCount;
- unsigned int UserTotal;
- bool bDontPrintResult;
-
- protected:
+// String replacements for format strings
-#if defined(UNICODE) || defined(UNICODE)
- TCHAR * CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat);
+#if defined(STORMLIB_WINDOWS) || defined(CASCLIB_PLATFORM_WINDOWS)
+#define TEST_PLATFORM_WINDOWS
#endif
- char * CopyFormatCharacter(char * szBuffer, const char *& szFormat);
- int GetConsoleWidth();
-
- const char * szMainTitle; // Title of the text (usually name)
- const TCHAR * szSubTitle1; // Title of the text (can be name of the tested file)
- const TCHAR * szSubTitle2; // Title of the text (can be name of the tested file)
- size_t nTextLength; // Length of the previous progress message
- bool bMessagePrinted;
-};
-
-//-----------------------------------------------------------------------------
-// String replacements for format strings
#ifdef _MSC_VER
-#define I64u_t _T("%I64u")
-#define I64u_a "%I64u"
-#define I64X_t _T("%I64X")
-#define I64X_a "%I64X"
+#define fmt_I64u_t _T("%I64u")
+#define fmt_I64u_a "%I64u"
+#define fmt_I64X_t _T("%I64X")
+#define fmt_I64X_a "%I64X"
#else
-#define I64u_t _T("%llu")
-#define I64u_a "%llu"
-#define I64X_t _T("%llX")
-#define I64X_a "%llX"
+#define fmt_I64u_t _T("%llu")
+#define fmt_I64u_a "%llu"
+#define fmt_I64X_t _T("%llX")
+#define fmt_I64X_a "%llX"
#endif
-//-----------------------------------------------------------------------------
-// Constructor and destructor
+#ifdef __STORMLIB_SELF__
+#define TEST_MIN STORMLIB_MIN
+#else
+#define TEST_MIN CASCLIB_MIN
+#endif
+//-----------------------------------------------------------------------------
+// Local functions
-TLogHelper::TLogHelper(const char * szNewMainTitle, const TCHAR * szNewSubTitle1, const TCHAR * szNewSubTitle2)
+inline DWORD TestInterlockedIncrement(DWORD * PtrValue)
{
- TCHAR szMainTitleT[0x80];
-
- UserString = "";
- UserCount = 1;
- UserTotal = 1;
+#ifdef TEST_PLATFORM_WINDOWS
+ return (DWORD)InterlockedIncrement((LONG *)(PtrValue));
+#elif defined(__GNUC__)
+ return __sync_add_and_fetch(PtrValue, 1);
+#else
+#define INTERLOCKED_NOT_SUPPORTED
+ return ++(*PtrValue);
+#endif
+}
- // Fill the test line structure
- szMainTitle = szNewMainTitle;
- szSubTitle1 = szNewSubTitle1;
- szSubTitle2 = szNewSubTitle2;
- nTextLength = 0;
- bMessagePrinted = false;
- bDontPrintResult = false;
+inline DWORD Test_GetLastError()
+{
+#if defined(CASCLIB_PLATFORM_WINDOWS)
+ return GetCascError();
+#else
+ return GetLastError();
+#endif
+}
- // Copy the UNICODE main title
- StringCopy(szMainTitleT, _countof(szMainTitleT), szMainTitle);
+void TestStrCopy(char * szTarget, size_t cchTarget, const char * szSource, size_t cchSource = -1)
+{
+ size_t cchToCopy;
- // Print the initial information
- if(szMainTitle != NULL)
+ if(cchTarget > 0)
{
- if(szSubTitle1 != NULL && szSubTitle2 != NULL)
- _tprintf(_T("Running %s (%s+%s) ..."), szMainTitleT, szSubTitle1, szSubTitle2);
- else if(szSubTitle1 != NULL)
- _tprintf(_T("Running %s (%s) ..."), szMainTitleT, szSubTitle1);
- else
- _tprintf(_T("Running %s ..."), szMainTitleT);
+ // Make sure we know the length
+ if(cchSource == -1)
+ cchSource = strlen(szSource);
+ cchToCopy = TEST_MIN((cchTarget - 1), cchSource);
+
+ // Copy the string
+ memcpy(szTarget, szSource, cchToCopy);
+ szTarget[cchToCopy] = 0;
}
}
-TLogHelper::~TLogHelper()
+void TestStrCopy(char * szTarget, size_t cchTarget, const wchar_t * szSource, size_t cchSource = -1)
{
- // Print a verdict, if no verdict was printed yet
- if(bMessagePrinted == false)
- {
- PrintVerdict(ERROR_SUCCESS);
- }
+ size_t cchToCopy;
-#if defined(_MSC_VER) && defined(_DEBUG)
- if(_CrtDumpMemoryLeaks())
+ if(cchTarget > 0)
{
- PrintMessage(_T("Memory leak(s) detected.\n"));
+ // Make sure we know the length
+ if(cchSource == -1)
+ cchSource = wcslen(szSource);
+ cchToCopy = TEST_MIN((cchTarget - 1), cchSource);
+
+ wcstombs(szTarget, szSource, cchToCopy);
+ szTarget[cchToCopy] = 0;
}
-#endif // _MSC_VER
}
-//-----------------------------------------------------------------------------
-// TCHAR-based functions. They are only needed on UNICODE builds.
-// On ANSI builds is TCHAR = char, so we don't need them at all
-
-#if defined(UNICODE) || defined(UNICODE)
-int TLogHelper::PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine)
+wchar_t * CopyFormatCharacter(wchar_t * szBuffer, const wchar_t *& szFormat)
{
- TCHAR szFormatBuff[0x200];
- TCHAR szMessage[0x200];
- TCHAR * szBuffer = szFormatBuff;
- int nRemainingWidth;
- int nConsoleWidth = GetConsoleWidth();
- int nLength = 0;
- int nError = GetLastError();
-
- // Always start the buffer with '\r'
- *szBuffer++ = '\r';
-
- // Print the prefix, if needed
- if(szMainTitle != NULL && bPrintPrefix)
- {
- while(szMainTitle[nLength] != 0)
- *szBuffer++ = szMainTitle[nLength++];
-
- *szBuffer++ = ':';
- *szBuffer++ = ' ';
- }
+ static const wchar_t * szStringFormat = _T("%s");
+ static const wchar_t * szUint64Format = fmt_I64u_t;
- // Copy the message format itself. Replace %s with "%s", unless it's (%s)
- if(szFormat != NULL)
+ // String format
+ if(szFormat[0] == '%')
{
- while(szFormat[0] != 0)
+ if(szFormat[1] == 's')
{
- szBuffer = CopyFormatCharacter(szBuffer, szFormat);
+ _tcscpy(szBuffer, szStringFormat);
+ szFormat += 2;
+ return szBuffer + _tcslen(szStringFormat);
}
- }
- // Append the last error
- if(bPrintLastError)
- {
- nLength = _stprintf(szBuffer, _T(" (error code: %u)"), nError);
- szBuffer += nLength;
+ // Replace %I64u with the proper platform-dependent suffix
+ if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u')
+ {
+ _tcscpy(szBuffer, szUint64Format);
+ szFormat += 5;
+ return szBuffer + _tcslen(szUint64Format);
+ }
}
- // Create the result string
- szBuffer[0] = 0;
- nLength = _vstprintf(szMessage, szFormatBuff, argList);
- szBuffer = szMessage + nLength;
+ // Copy the character as-is
+ *szBuffer++ = *szFormat++;
+ return szBuffer;
+}
- // Shall we pad the string?
- if(nLength < nConsoleWidth)
+char * CopyFormatCharacter(char * szBuffer, const char *& szFormat)
+{
+ static const char * szStringFormat = "\"%s\"";
+ static const char * szUint64Format = fmt_I64u_a;
+
+ // String format
+ if(szFormat[0] == '%')
{
- // Calculate the remaining width
- nRemainingWidth = nConsoleWidth - nLength - 1;
+ if(szFormat[1] == 's')
+ {
+ TestStrCopy(szBuffer, 32, szStringFormat);
+ szFormat += 2;
+ return szBuffer + strlen(szStringFormat);
+ }
- // Pad the string with spaces to fill it up to the end of the line
- for(int i = 0; i < nRemainingWidth; i++)
- *szBuffer++ = 0x20;
+ // Replace %I64u with the proper platform-dependent suffix
+ if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u')
+ {
+ TestStrCopy(szBuffer, 32, szUint64Format);
+ szFormat += 5;
+ return szBuffer + strlen(szUint64Format);
+ }
}
- // Put the newline, if requested
- *szBuffer++ = bPrintEndOfLine ? '\n' : 0;
- *szBuffer = 0;
-
- // Remember if we printed a message
- if(bPrintEndOfLine)
- bMessagePrinted = true;
+ // Copy the character as-is
+ *szBuffer++ = *szFormat++;
+ return szBuffer;
+}
- // Spit out the text in one single printf
- _tprintf(_T("%s"), szMessage);
- return nError;
+size_t TestStrPrintfV(char * buffer, size_t nCount, const char * format, va_list argList)
+{
+ return vsnprintf(buffer, nCount, format, argList);
}
-void TLogHelper::PrintProgress(const TCHAR * szFormat, ...)
+size_t TestStrPrintf(char * buffer, size_t nCount, const char * format, ...)
{
va_list argList;
+ size_t length;
- va_start(argList, szFormat);
- PrintWithClreol(szFormat, argList, true, false, false);
+ // Start the argument list
+ va_start(argList, format);
+ length = TestStrPrintfV(buffer, nCount, format, argList);
va_end(argList);
+
+ return length;
}
-void TLogHelper::PrintMessage(const TCHAR * szFormat, ...)
+size_t TestStrPrintfV(wchar_t * buffer, size_t nCount, const wchar_t * format, va_list argList)
{
- va_list argList;
-
- va_start(argList, szFormat);
- PrintWithClreol(szFormat, argList, true, false, true);
- va_end(argList);
+#ifdef TEST_PLATFORM_WINDOWS
+ return _vsnwprintf(buffer, nCount, format, argList);
+#else
+ return vswprintf(buffer, nCount, format, argList);
+#endif
}
-int TLogHelper::PrintErrorVa(const TCHAR * szFormat, ...)
+size_t TestStrPrintf(wchar_t * buffer, size_t nCount, const wchar_t * format, ...)
{
va_list argList;
- int nResult;
+ size_t length;
- va_start(argList, szFormat);
- nResult = PrintWithClreol(szFormat, argList, true, true, true);
+ // Start the argument list
+ va_start(argList, format);
+ length = TestStrPrintfV(buffer, nCount, format, argList);
va_end(argList);
- return nResult;
+ return length;
}
-int TLogHelper::PrintError(const TCHAR * szFormat, const TCHAR * szFileName)
-{
- return PrintErrorVa(szFormat, szFileName);
-}
-#endif // defined(UNICODE) || defined(UNICODE)
-
//-----------------------------------------------------------------------------
-// ANSI functions
+// Definition of the TLogHelper class
-DWORD TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine)
+class TLogHelper
{
- char szFormatBuff[0x200];
- char szMessage[0x200];
- char * szBuffer = szFormatBuff;
- int nRemainingWidth;
- int nConsoleWidth = GetConsoleWidth();
- int nLength = 0;
- DWORD dwErrCode = GetLastError();
-
- // Always start the buffer with '\r'
- *szBuffer++ = '\r';
-
- // Print the prefix, if needed
- if(szMainTitle != NULL && bPrintPrefix)
- {
- while(szMainTitle[nLength] != 0)
- *szBuffer++ = (char)szMainTitle[nLength++];
+ public:
- *szBuffer++ = ':';
- *szBuffer++ = ' ';
- }
+ //
+ // Constructor and destructor
+ //
- // Copy the message format itself. Replace %s with "%s", unless it's (%s)
- if(szFormat != NULL)
+ TLogHelper(const char * szNewMainTitle = NULL, const TCHAR * szNewSubTitle1 = NULL, const TCHAR * szNewSubTitle2 = NULL)
{
- while(szFormat[0] != 0)
+ TCHAR szMainTitleT[0x80];
+
+ // Fill the variables
+ memset(this, 0, sizeof(TLogHelper));
+
+ UserString = "";
+ UserCount = 1;
+ UserTotal = 1;
+
+ // Fill the test line structure
+ szMainTitle = szNewMainTitle;
+ szSubTitle1 = szNewSubTitle1;
+ szSubTitle2 = szNewSubTitle2;
+
+ // Copy the UNICODE main title
+ StringCopy(szMainTitleT, _countof(szMainTitleT), szMainTitle);
+
+ // Print the initial information
+ if(szNewMainTitle != NULL)
{
- szBuffer = CopyFormatCharacter(szBuffer, szFormat);
+ if(szSubTitle1 != NULL && szSubTitle2 != NULL)
+ nPrevPrinted = _tprintf(_T("Running %s (%s+%s) ..."), szMainTitleT, szSubTitle1, szSubTitle2);
+ else if(szSubTitle1 != NULL)
+ nPrevPrinted = _tprintf(_T("Running %s (%s) ..."), szMainTitleT, szSubTitle1);
+ else
+ nPrevPrinted = _tprintf(_T("Running %s ..."), szMainTitleT);
}
}
- // Append the last error
- if(bPrintLastError)
+ TLogHelper::~TLogHelper()
{
- nLength = sprintf(szBuffer, " (error code: %u)", dwErrCode);
- szBuffer += nLength;
+ // Print a verdict, if no verdict was printed yet
+ if(bMessagePrinted == false)
+ {
+ PrintVerdict(ERROR_SUCCESS);
+ }
+
+
+ printf("\n");
}
- // Create the result string
- szBuffer[0] = 0;
- nLength = vsprintf(szMessage, szFormatBuff, argList);
+ //
+ // Measurement of elapsed time
+ //
- // Shall we pad the string?
- szBuffer = szMessage + nLength;
- if(nLength < nConsoleWidth)
+ bool TimeElapsed(DWORD Milliseconds)
{
- // Calculate the remaining width
- nRemainingWidth = nConsoleWidth - nLength - 1;
+ bool bTimeElapsed = false;
+
+#ifdef TEST_PLATFORM_WINDOWS
+ if(GetTickCount() > (TickCount + Milliseconds))
+ {
+ TickCount = GetTickCount();
+ if(TestInterlockedIncrement(&TimeTrigger) == 1)
+ {
+ bTimeElapsed = true;
+ }
+ }
- // Pad the string with spaces to fill it up to the end of the line
- for(int i = 0; i < nRemainingWidth; i++)
- *szBuffer++ = 0x20;
+#endif
+ return bTimeElapsed;
}
- // Put the newline, if requested
- *szBuffer++ = bPrintEndOfLine ? '\n' : '\r';
- *szBuffer = 0;
+ //
+ // Printing functions
+ //
- // Remember if we printed a message
- if(bPrintEndOfLine)
- bMessagePrinted = true;
+ template <typename XCHAR>
+ DWORD PrintWithClreol(const XCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine)
+ {
+ char * szBufferPtr;
+ char * szBufferEnd;
+ size_t nNewPrinted;
+ size_t nLength = 0;
+ DWORD dwErrCode = Test_GetLastError();
+ XCHAR szMessage[0x200];
+ char szBuffer[0x200];
+
+ // Always start the buffer with '\r'
+ szBufferEnd = szBuffer + _countof(szBuffer);
+ szBufferPtr = szBuffer;
+ *szBufferPtr++ = '\r';
+
+ // Print the prefix, if needed
+ if(szMainTitle != NULL && bPrintPrefix)
+ {
+ while(szMainTitle[nLength] != 0)
+ *szBufferPtr++ = szMainTitle[nLength++];
- // Spit out the text in one single printf
- printf("%s", szMessage);
- return dwErrCode;
-}
+ *szBufferPtr++ = ':';
+ *szBufferPtr++ = ' ';
+ }
-void TLogHelper::PrintProgress(const char * szFormat, ...)
-{
- va_list argList;
+ // Construct the message
+ nLength = TestStrPrintfV(szMessage, _countof(szMessage), szFormat, argList);
+ TestStrCopy(szBufferPtr, (szBufferEnd - szBufferPtr), szMessage);
+ szBufferPtr += nLength;
- va_start(argList, szFormat);
- PrintWithClreol(szFormat, argList, true, false, false);
- va_end(argList);
-}
+ // Append the last error
+ if(bPrintLastError)
+ {
+ nLength = TestStrPrintf(szBufferPtr, (szBufferEnd - szBufferPtr), " (error code: %u)", dwErrCode);
+ szBufferPtr += nLength;
+ }
-void TLogHelper::PrintMessage(const char * szFormat, ...)
-{
- va_list argList;
+ // Remember how much did we print
+ nNewPrinted = (szBufferPtr - szBuffer);
- va_start(argList, szFormat);
- PrintWithClreol(szFormat, argList, true, false, true);
- va_end(argList);
-}
+ // Shall we pad the string?
+ if((nLength = (szBufferPtr - szBuffer - 1)) < nPrevPrinted)
+ {
+ size_t nPadding = nPrevPrinted - nLength;
-DWORD TLogHelper::PrintErrorVa(const char * szFormat, ...)
-{
- va_list argList;
- DWORD dwErrCode;
+ if((size_t)(nLength + nPadding) > (size_t)(szBufferEnd - szBufferPtr))
+ nPadding = (szBufferEnd - szBufferPtr);
- va_start(argList, szFormat);
- dwErrCode = PrintWithClreol(szFormat, argList, true, true, true);
- va_end(argList);
+ memset(szBufferPtr, ' ', nPadding);
+ szBufferPtr += nPadding;
+ }
- return dwErrCode;
-}
+ // Shall we add new line?
+ if((bPrintEndOfLine != false) && (szBufferPtr < szBufferEnd))
+ *szBufferPtr++ = '\n';
+ *szBufferPtr = 0;
-DWORD TLogHelper::PrintError(const char * szFormat, const char * szFileName)
-{
- return PrintErrorVa(szFormat, szFileName);
-}
+ // Remember if we printed a message
+ if(bPrintEndOfLine != false)
+ {
+ bMessagePrinted = true;
+ nPrevPrinted = 0;
+ }
+ else
+ {
+ nPrevPrinted = nNewPrinted;
+ }
-//-----------------------------------------------------------------------------
-// Print final verdict
+ // Finally print the message
+ printf("%s", szBuffer);
+ nMessageCounter++;
+ return dwErrCode;
+ }
-DWORD TLogHelper::PrintVerdict(DWORD dwErrCode)
-{
- LPCTSTR szSaveSubTitle1 = szSubTitle1;
- LPCTSTR szSaveSubTitle2 = szSubTitle2;
- TCHAR szSaveMainTitle[0x80];
-
- // Set both to NULL so they won't be printed
- StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle);
- szSubTitle1 = NULL;
- szSubTitle2 = NULL;
- szMainTitle = NULL;
-
- // Print the final information
- if(szSaveMainTitle[0] != 0)
+ template <typename XCHAR>
+ void PrintProgress(const XCHAR * szFormat, ...)
{
- if(bDontPrintResult == false)
- {
- LPCTSTR szVerdict = (dwErrCode == ERROR_SUCCESS) ? _T("succeeded") : _T("failed");
+ va_list argList;
- if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL)
- PrintMessage(_T("%s (%s+%s) %s."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2, szVerdict);
- else if(szSaveSubTitle1 != NULL)
- PrintMessage(_T("%s (%s) %s."), szSaveMainTitle, szSaveSubTitle1, szVerdict);
- else
- PrintMessage(_T("%s %s."), szSaveMainTitle, szVerdict);
- }
- else
+ // Always reset the time trigger
+ TimeTrigger = 0;
+
+ // Only print progress when the cooldown is ready
+ if(ProgressReady())
{
- PrintProgress(" ");
- printf("\r");
+ va_start(argList, szFormat);
+ PrintWithClreol(szFormat, argList, true, false, false);
+ va_end(argList);
}
}
- // Return the error code so the caller can pass it fuhrter
- return dwErrCode;
-}
+ template <typename XCHAR>
+ void PrintMessage(const XCHAR * szFormat, ...)
+ {
+ va_list argList;
-//-----------------------------------------------------------------------------
-// Protected functions
+ va_start(argList, szFormat);
+ PrintWithClreol(szFormat, argList, true, false, true);
+ va_end(argList);
+ }
-#ifdef _UNICODE
-TCHAR * TLogHelper::CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat)
-{
-// static LPCTSTR szStringFormat = _T("\"%s\"");
- static LPCTSTR szStringFormat = _T("%s");
- static LPCTSTR szUint64Format = I64u_t;
+ void PrintTotalTime()
+ {
+ DWORD TotalTime = SetEndTime();
- // String format
- if(szFormat[0] == '%')
+ if(TotalTime != 0)
+ PrintMessage("TotalTime: %u.%u second(s)", (TotalTime / 1000), (TotalTime % 1000));
+ PrintMessage("Work complete.");
+ }
+
+ template <typename XCHAR>
+ int PrintErrorVa(const XCHAR * szFormat, ...)
{
- if(szFormat[1] == 's')
- {
- _tcscpy(szBuffer, szStringFormat);
- szFormat += 2;
- return szBuffer + _tcslen(szStringFormat);
- }
+ va_list argList;
+ int nResult;
- // Replace %I64u with the proper platform-dependent suffix
- if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u')
+ va_start(argList, szFormat);
+ nResult = PrintWithClreol(szFormat, argList, true, true, true);
+ va_end(argList);
+
+ return nResult;
+ }
+
+ template <typename XCHAR>
+ int PrintError(const XCHAR * szFormat, const XCHAR * szFileName = NULL)
+ {
+ return PrintErrorVa(szFormat, szFileName);
+ }
+
+ // Print final verdict
+ DWORD PrintVerdict(DWORD dwErrCode = ERROR_SUCCESS)
+ {
+ LPCTSTR szSaveSubTitle1 = szSubTitle1;
+ LPCTSTR szSaveSubTitle2 = szSubTitle2;
+ TCHAR szSaveMainTitle[0x80];
+
+ // Set both to NULL so they won't be printed
+ StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle);
+ szSubTitle1 = NULL;
+ szSubTitle2 = NULL;
+ szMainTitle = NULL;
+
+ // Print the final information
+ if(szSaveMainTitle[0] != 0)
{
- _tcscpy(szBuffer, szUint64Format);
- szFormat += 5;
- return szBuffer + _tcslen(szUint64Format);
+ if(DontPrintResult == false)
+ {
+ LPCTSTR szVerdict = (dwErrCode == ERROR_SUCCESS) ? _T("succeeded") : _T("failed");
+
+ if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL)
+ PrintMessage(_T("%s (%s+%s) %s."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2, szVerdict);
+ else if(szSaveSubTitle1 != NULL)
+ PrintMessage(_T("%s (%s) %s."), szSaveMainTitle, szSaveSubTitle1, szVerdict);
+ else
+ PrintMessage(_T("%s %s."), szSaveMainTitle, szVerdict);
+ }
+ else
+ {
+ PrintProgress(" ");
+ printf("\r");
+ }
}
+
+ // Return the error code so the caller can pass it fuhrter
+ return dwErrCode;
}
- // Copy the character as-is
- *szBuffer++ = *szFormat++;
- return szBuffer;
-}
-#endif
+ //
+ // Time functions
+ //
-char * TLogHelper::CopyFormatCharacter(char * szBuffer, const char *& szFormat)
-{
- static const char * szStringFormat = "\"%s\"";
- static const char * szUint64Format = I64u_a;
+ ULONGLONG GetCurrentThreadTime()
+ {
+#ifdef _WIN32
+ ULONGLONG TempTime = 0;
- // String format
- if(szFormat[0] == '%')
+ GetSystemTimeAsFileTime((LPFILETIME)(&TempTime));
+ return ((TempTime) / 10 / 1000);
+
+ //ULONGLONG KernelTime = 0;
+ //ULONGLONG UserTime = 0;
+ //ULONGLONG TempTime = 0;
+
+ //GetThreadTimes(GetCurrentThread(), (LPFILETIME)&TempTime, (LPFILETIME)&TempTime, (LPFILETIME)&KernelTime, (LPFILETIME)&UserTime);
+ //return ((KernelTime + UserTime) / 10 / 1000);
+#else
+ return time(NULL) * 1000;
+#endif
+ }
+
+ bool ProgressReady()
{
- if(szFormat[1] == 's')
- {
- strcpy(szBuffer, szStringFormat);
- szFormat += 2;
- return szBuffer + strlen(szStringFormat);
- }
+ time_t dwTickCount = time(NULL);
+ bool bResult = false;
- // Replace %I64u with the proper platform-dependent suffix
- if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u')
+ if(dwTickCount > dwPrevTickCount)
{
- strcpy(szBuffer, szUint64Format);
- szFormat += 5;
- return szBuffer + strlen(szUint64Format);
+ dwPrevTickCount = dwTickCount;
+ bResult = true;
}
+
+ return bResult;
}
- // Copy the character as-is
- *szBuffer++ = *szFormat++;
- return szBuffer;
-}
+ ULONGLONG SetStartTime()
+ {
+ StartTime = GetCurrentThreadTime();
+ return StartTime;
+ }
-int TLogHelper::GetConsoleWidth()
-{
-#ifdef STORMLIB_WINDOWS
+ DWORD SetEndTime()
+ {
+ EndTime = GetCurrentThreadTime();
+ return (DWORD)(EndTime - StartTime);
+ }
- CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ScreenInfo);
- return (int)(ScreenInfo.srWindow.Right - ScreenInfo.srWindow.Left);
+ ULONGLONG StartTime; // Start time of an operation, in milliseconds
+ ULONGLONG EndTime; // End time of an operation, in milliseconds
+ const char * UserString;
+ unsigned int UserCount;
+ unsigned int UserTotal;
+ DWORD TickCount;
+ DWORD TimeTrigger; // For triggering elapsed timers
+ DWORD DontPrintResult:1; // If true, supress printing result from the destructor
-#else
- // On non-Windows platforms, we assume that width of the console line
- // is 80 characters
- return 120;
+ protected:
-#endif
-}
+ const char * szMainTitle; // Title of the text (usually name)
+ const TCHAR * szSubTitle1; // Title of the text (can be name of the tested file)
+ const TCHAR * szSubTitle2; // Title of the text (can be name of the tested file)
+ size_t nMessageCounter;
+ size_t nPrevPrinted; // Length of the previously printed message
+ time_t dwPrevTickCount;
+ bool bMessagePrinted;
+};
diff --git a/test/stormlib-test.txt b/test/stormlib-test.txt
index 947a387..2cdaed2 100644
--- a/test/stormlib-test.txt
+++ b/test/stormlib-test.txt
@@ -1,4 +1,4 @@
-Microsoft Windows [Version 10.0.19044.2006]
+Microsoft Windows [Version 10.0.19045.2486]
(c) Microsoft Corporation. All rights reserved.
E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release>StormLib_test.exe
@@ -35,8 +35,6 @@ TestMpq (MPQ_2014_v1_AttributesOneEntryLess.w3x) succeeded.
TestMpq (MPQ_2020_v1_AHF04patch.mix) succeeded.
TestMpq (MPQ_2010_v3_expansion-locale-frFR.MPQ) succeeded.
TestMpq (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded.
-TestMpq (MPx_2013_v1_LongwuOnline.mpk) succeeded.
-TestMpq (MPx_2013_v1_WarOfTheImmortals.sqp) succeeded.
TestMpq (part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part) succeeded.
TestMpq (blk4-file://streaming/model.MPQ.0) succeeded.
TestMpq (MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x) succeeded.
@@ -71,6 +69,11 @@ TestMpq (MPQ_2022_v1_OcOc_Bound_2.scx) succeeded.
TestMpq (MPQ_2020_v1_HS0.1.asi) succeeded.
TestMpq (MPQ_2022_v1_hs0.8.asi) succeeded.
TestMpq (MPQ_2022_v1_MoeMoeMod.asi) succeeded.
+TestMpq (MPx_2013_v1_LongwuOnline.mpk) succeeded.
+TestMpq (MPx_2013_v1_WarOfTheImmortals.sqp) succeeded.
+TestMpq (MPx_2022_v1_Music.mpk) succeeded.
+TestMpq (MPx_2022_v1_Scp.mpk) succeeded.
+TestMpq (MPx_2022_v1_UI.mpk) succeeded.
PatchedMPQ (MPQ_1998_v1_StarCraft.mpq) succeeded.
PatchedMPQ (MPQ_2012_v4_OldWorld.MPQ) succeeded.
PatchedMPQ (MPQ_2013_v4_world.MPQ) succeeded.
@@ -176,6 +179,9 @@ VerifyFileHash succeeded.
VerifyFileHash succeeded.
VerifyFileHash succeeded.
VerifyFileHash succeeded.
+VerifyFileHash succeeded.
+VerifyFileHash succeeded.
+VerifyFileHash succeeded.
OpenEachMpqTest ((10)DustwallowKeys.w3m) succeeded.
OpenEachMpqTest (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded.
OpenEachMpqTest (MPQ_1997_v1_Diablo1_single_0.sv) succeeded.