Skip to content

Commit d270bee

Browse files
Improve search in BIG archive
1 parent dd9d3f9 commit d270bee

File tree

2 files changed

+58
-33
lines changed

2 files changed

+58
-33
lines changed

src/Parsers/CSFParser.cpp

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,9 @@ using namespace StringExt;
2929
if (Path.ends_with(L".BIG"))
3030
{
3131
LOGMSG("BIG archive detected. Try to find CSF file inside...");
32-
33-
bool searchResult = false;
34-
char fourC[4] = {' ', ' ', ' ', ' '};
35-
std::streampos fourCharOffset = sizeof(char) * 4;
36-
37-
while (!searchResult && file.good())
38-
{
39-
file.read(fourC, fourCharOffset);
40-
searchResult = (fourC[0] == FSC[0]) && (fourC[1] == FSC[1]) && (fourC[2] == FSC[2]) && (fourC[3] == FSC[3]);
41-
}
42-
43-
if (!file.good())
44-
{
45-
LOGMSG(PROGRAM_CONSTANTS->CSF_NO_CSF_IN_BIG.arg(Path));
46-
throw Exception(L10N(PROGRAM_CONSTANTS->CSF_NO_CSF_IN_BIG).arg(Path));
47-
}
48-
49-
auto offset = file.tellg();
50-
file.clear();
51-
file.seekg(offset - fourCharOffset);
52-
53-
LOGMSG("CSF file data found at offset : " + reinterpret_cast<const uint64_t&>(offset));
54-
55-
Path = Path.substr(0, Path.find_last_of('\\') + 1) + L"Data\\English\\generals.csf";
32+
streampos offset = SetOffsetAtTheStringStart(file, " FSC"s);
33+
LOGMSG("CSF file data found at offset : " + static_cast<const uint64_t&>(offset));
34+
Path = Path.substr(0, Path.find_last_of('\\') + 1) + PROGRAM_CONSTANTS->BIG_ARCHIVE_CSF_PATH.toStdWString();
5635
}
5736

5837
LOGMSG("Attempt to read string table from \"" + Path.c_str() + "\" file...");
@@ -69,21 +48,65 @@ using namespace StringExt;
6948
void CSFParser::Parse(const std::string& strFilePath) { Parse(strFilePath.c_str()); }
7049
void CSFParser::Parse(const QString& strFilePath) { Parse(strFilePath.toStdString().c_str()); }
7150

51+
streampos CSFParser::SetOffsetAtTheStringStart(ifstream& file, const string& searchStr)
52+
{
53+
const streampos startOffset = file.tellg();
54+
const streampos delta = sizeof(char) * searchStr.length();
55+
const streampos testDelta = 1;
56+
57+
bool searchResult = false;
58+
string searchWindow = searchStr;
59+
char c = ' ';
60+
61+
while (!searchResult && file.good())
62+
{
63+
file.read(&c, testDelta);
64+
if (searchStr[0] == c)
65+
{
66+
// Return back to 1 character
67+
file.seekg(file.tellg() - testDelta);
68+
file.read(const_cast<char*>(searchWindow.c_str()), delta);
69+
searchResult = searchStr == searchWindow;
70+
// Return back search window position
71+
file.seekg(file.tellg() - delta + testDelta);
72+
}
73+
else
74+
continue;
75+
}
76+
77+
// Restore position before search string
78+
file.seekg(file.tellg() + delta - testDelta);
79+
80+
if (!file.good())
81+
{
82+
file.clear();
83+
file.seekg(startOffset);
84+
LOGMSG(PROGRAM_CONSTANTS->CSF_NO_CSF_IN_BIG.arg(Path));
85+
throw Exception(L10N(PROGRAM_CONSTANTS->CSF_NO_CSF_IN_BIG).arg(Path));
86+
}
87+
88+
streampos offset = file.tellg();
89+
file.clear();
90+
file.seekg(offset - delta);
91+
92+
return offset;
93+
}
94+
7295
void CSFParser::ReadHeader(ifstream* csfFile)
7396
{
7497
csfFile->read(reinterpret_cast<char*>(&Header), sizeof(Header));
7598

7699
LOGSTM << "File header data:" << endl;
77100

78-
LOGSTM << '\t' << "First 4th bytes of file header are : [" << Header.csfChars[0]
79-
<< Header.csfChars[1]
80-
<< Header.csfChars[2]
81-
<< Header.csfChars[3] << ']' << endl;
82-
LOGSTM << '\t' << "CSF file format version : " << Header.formatVersion << endl;
83-
LOGSTM << '\t' << "Number of labels in CSF file : " << Header.numberOfLabels << endl;
84-
LOGSTM << '\t' << "Number of strings in CSF file : " << Header.numberOfStrings << endl;
85-
LOGSTM << '\t' << "Useless bytes, i guess? : " << Header.uselessBytes << endl;
86-
LOGSTM << '\t' << "Language code : " << Header.languageCode << endl;
101+
LOGSTM << '\t' << "First 4th bytes of file header are : [" << Header.csfChars[0]
102+
<< Header.csfChars[1]
103+
<< Header.csfChars[2]
104+
<< Header.csfChars[3] << ']' << endl;
105+
LOGSTM << '\t' << "CSF file format version : " << Header.formatVersion << endl;
106+
LOGSTM << '\t' << "Number of labels in CSF file : " << Header.numberOfLabels << endl;
107+
LOGSTM << '\t' << "Number of strings in CSF file : " << Header.numberOfStrings << endl;
108+
LOGSTM << '\t' << "Useless bytes, i guess? : " << Header.uselessBytes << endl;
109+
LOGSTM << '\t' << "Language code : " << Header.languageCode << endl;
87110
}
88111

89112
void CSFParser::ReadBody(ifstream* csfFile)

src/Parsers/CSFParser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class CSFParser final
5252
void WriteHeader(std::ofstream* csfFile);
5353
void WriteBody(std::ofstream* csfFile);
5454

55+
std::streampos SetOffsetAtTheStringStart(std::ifstream& file, const std::string& str);
56+
5557
/// @brief Pure function-convertor from char array to std::string.
5658
std::string CharArrayToString(const size_t& arrayLength, const char* pArray) const;
5759
/// @brief Pure function-convertor from wchar_t array to std::wstring.

0 commit comments

Comments
 (0)