-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
150 lines (122 loc) · 3.43 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <experimental/filesystem>
#include <fstream>
#include <cstring>
#include <iostream>
#include <chrono>
#if !defined(PLAT_UNIX)
#include <conio.h>
#endif
namespace fs = std::experimental::filesystem;
#if defined(PLAT_UNIX)
#define STRNICMP strncasecmp
#define WSTR "%s"
#else
#define STRNICMP _strnicmp
#define WSTR "%ls"
#endif
// FIXME Why doesn't it find anything in Windows Debug?!
int main()
{
const char* SearchPath = "Content";
const char* SearchExt = ".UASSET";
const uintmax_t SearchMaxFileSize = (10 * 1024 * 1024);
if (!fs::exists(SearchPath) || !fs::is_directory(SearchPath))
{
printf("Can't find search path '%s', aborting.\n", SearchPath);
return 0;
}
const size_t SearchExtLen = strlen(SearchExt);
// TODO Check is longer than 1 and 1st char is '.'
const int SearchTermMinSize = 4;
std::string SearchTerm = "FirstPersonTemplateWeaponFire02";
#if 1
printf("\n> What are ya searchin'? ");
std::cin >> SearchTerm;
printf("\n");
#endif
const auto TimeStart = std::chrono::high_resolution_clock::now();
const int SearchTermLen = (int) SearchTerm.length();
if (SearchTermLen < SearchTermMinSize)
{
printf("Search term must be at least '%d' chars long, aborting.\n", SearchTermMinSize);
return 0;
}
const char FirstChar = SearchTerm[0];
const int ReadBufSz = SearchTermLen;
char* ReadBuf = new char[ReadBufSz];
if (!ReadBuf)
{
printf("Failed to allocate small buffer for reading files, aborting.\n");
return 0;
}
for (const auto& Entry : fs::recursive_directory_iterator(SearchPath))
{
const fs::file_status& Status = Entry.status();
if (fs::is_regular_file(Status) && fs::exists(Status))
{
const fs::path& Path = Entry.path();
const uintmax_t Size = fs::file_size(Path);
if ((Size >= SearchTermMinSize) && (Size <= SearchMaxFileSize) &&
Path.has_extension() && !STRNICMP(Path.extension().string().c_str(), SearchExt, SearchExtLen))
{
//printf("Entry: %ls: %lu\n", Path.c_str(), Size);
std::fstream File (Path, (std::fstream::in|std::fstream::binary));
while (File.good())
{
File.read(ReadBuf, ReadBufSz);
if (!File.good())
{
break;
}
// TODO Need to support ignoring case
const bool bMatches = (SearchTerm.compare(ReadBuf) == 0);
if (bMatches)
{
printf("Match => " WSTR "\n", Path.c_str());
break;
}
int FoundSubIdx = -1;
for (int i = 1; i < ReadBufSz; ++i)
{
// TODO Need to support case insensitive here
if (ReadBuf[i] == FirstChar)
{
FoundSubIdx = i;
break;
}
}
if (FoundSubIdx >= 0)
{
const int RewindDelta = (FoundSubIdx - SearchTermLen);
File.seekg(RewindDelta, std::fstream::cur);
}
}
#if 1
// FIXME Sometimes Windows fails to find anything, even in Release, so logging errors here to help track it down
if (!File.good())
{
if (File.bad())
{
printf(" ERROR: bad: " WSTR "\n", Path.c_str());
break;
}
else if (File.fail() && !File.eof())
{
printf(" ERROR: fail: " WSTR "\n", Path.c_str());
break;
}
}
#endif
}
}
}
delete[] ReadBuf;
const std::chrono::duration<double> TimeTaken = (std::chrono::high_resolution_clock::now() - TimeStart);
printf("\nTime taken: %g seconds", TimeTaken.count());
#if !defined(PLAT_UNIX)
printf(". Press any key to exit... ");
_getch();
#endif
printf("\n\n");
return 0;
}