MCPcopy Create free account
hub / github.com/OpenSteam001/OpenSteamTool / FindInFileRange

Function FindInFileRange

src/OSTPlatform/Windows/ByteSearch.cpp:97–269  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

95}
96
97std::optional<uint64_t> FindInFileRange(
98 const std::filesystem::path& path,
99 uint64_t offset,
100 uint64_t size,
101 std::span<const uint8_t> pattern,
102 size_t chunkBytes) {
103 const Stopwatch totalTimer;
104 FixedPatternScanner scanner(pattern);
105 const size_t patternSize = scanner.PatternSize();
106 if (patternSize == 0 || size == 0) return std::nullopt;
107
108 Windows::UniqueFileHandle file = OpenForOverlappedSequentialRead(path);
109 if (!file) {
110 OSTP_LOG_DEBUG("ByteSearch::FindInFileRange open failed path={} offset=0x{:X} size={} err={}",
111 path.string(), offset, size, ::GetLastError());
112 return std::nullopt;
113 }
114
115 LARGE_INTEGER sizeLi{};
116 if (!::GetFileSizeEx(file.get(), &sizeLi) || sizeLi.QuadPart <= 0) {
117 OSTP_LOG_DEBUG("ByteSearch::FindInFileRange empty/invalid file path={} offset=0x{:X} size={}",
118 path.string(), offset, size);
119 return std::nullopt;
120 }
121
122 const uint64_t fileSize = static_cast<uint64_t>(sizeLi.QuadPart);
123 if (offset >= fileSize) {
124 OSTP_LOG_DEBUG("ByteSearch::FindInFileRange offset past EOF path={} offset=0x{:X} file_size={}",
125 path.string(), offset, fileSize);
126 return std::nullopt;
127 }
128
129 const uint64_t rangeEnd = offset + (std::min)(size, fileSize - offset);
130
131 chunkBytes = (std::max)(chunkBytes, patternSize);
132 // Consecutive chunks overlap by (patternSize - 1) bytes: a match straddling a
133 // chunk boundary runs off chunk i's tail (BMH won't see it there) but is fully
134 // contained at the head of chunk i+1. Because the overlap is re-read from disk
135 // rather than carry-copied from the previous buffer, the read of chunk i+1 has
136 // no data dependency on the scan of chunk i — so the two can truly overlap.
137 const uint64_t stride = static_cast<uint64_t>(chunkBytes) - (patternSize - 1);
138
139 // Double buffering: while BMH scans chunk i in one buffer, the kernel streams
140 // chunk i+1 into the other. make_unique_for_overwrite skips the zero-fill the
141 // buffers are about to be overwritten anyway.
142 std::unique_ptr<uint8_t[]> buffers[2] = {
143 std::make_unique_for_overwrite<uint8_t[]>(chunkBytes),
144 std::make_unique_for_overwrite<uint8_t[]>(chunkBytes),
145 };
146 Windows::UniqueHandle events[2] = {
147 Windows::UniqueHandle(::CreateEventW(nullptr, TRUE, FALSE, nullptr)),
148 Windows::UniqueHandle(::CreateEventW(nullptr, TRUE, FALSE, nullptr)),
149 };
150 if (!events[0] || !events[1]) {
151 OSTP_LOG_DEBUG("ByteSearch::FindInFileRange event create failed path={} err={}",
152 path.string(), ::GetLastError());
153 return std::nullopt;
154 }

Callers 2

TryOepPatternFunction · 0.85
FindInFileFunction · 0.85

Calls 5

PatternSizeMethod · 0.80
getMethod · 0.45
ElapsedMsMethod · 0.45
FindMethod · 0.45

Tested by

no test coverage detected