Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

@FILEREADB?

May
12,935
171
I'm using @FILEREADB to try to find (hex) 68 FF FF FF FF in a file. Reading 5 bytes at a time, and checking for (decimal) 104 255 255 255 255 works but is quite slow. I could read more and look for that string with @INDEX but if it's found, determining a position in the file would be quite hard. Is there a built-in way to turn @FILEREADB's output into 2-digit hex?

I'll post a suggestion that @FILEREADB be given an optional 3rd parameter ([,h]) indicating that its output should be 2-digit hex (00 - FF).
 
I'm not sure if you've tried this or if you are attempting to automate something, but V can search for hex data.
 
I'm not sure if you've tried this or if you are attempting to automate something, but V can search for hex data.
I'm trying to automate. I dashed off a plugin
Code:
v:\> echo %@dec2hex[104 255 255 255]
68 FF FF FF
(might be nice of @CONVERT worked like that)
and used it (reading 1024 bytes at a time) to turn @FILEREADB's output (%read) into 2-digit hex (%hex).
Then the offset of the found string from the beginning of the @FILEREADB is just
Code:
%@eval[%@index[%hex,68 FF FF FF FF] / 3]
This (reading more than 5 bytes at a time) got the time to find the bytes down from 52 sec to .09 sec. when the bytes were found about 21,000 bytes into the file

Then I figured out how to do it with only built-in stuff. Basically, read 1024 bytes ... if the decimal version of the target bytes is found, count the spaces before it ... that'll be the offset from the beginning of the @FILEREADB. My loop looks like this.
Code:
do forever
   set readstart=%@fileseek[%h,0,1]
   set read=%@filereadb[%h,1024]
   set found=%@index[%read,104 255 255 255 255]
   iff %found GE 0 then
       set chop=%@left[%@inc[%found],%read]
       set offset=%@index[%chop,^s,0]
       echo Found at 0x%@eval[%readstart + %offset=h]
       leave
   endiff
   if %@fileseek[%h,0,1] GE %size] (echo Not found & leave)
   echo %@fileseek[%h,-4,1] > nul
enddo
 
Then I figured out how to do it with only built-in stuff. Basically, read 1024 bytes ...
I'm glad you mentioned that. I was about to ask if "68 FF FF FF FF" was guaranteed to be on a 5 byte boundary, otherwise you might never find it.
 
I'm glad you mentioned that. I was about to ask if "68 FF FF FF FF" was guaranteed to be on a 5 byte boundary, otherwise you might never find it.
I actually didn't mention that in my first attempt, I would read 5 bytes and then back up 4 bytes for the next read. Even when reading 1024 bytes at a time, I would back up 4 bytes before the next read.
 
Back
Top