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
|
#import "Scanning.h"
typedef struct ByteString
{
uint8_t *bytes;
int length;
} ByteString;
static int MatchByteString(const uint8_t *bytes,int available,off_t offset,void *context)
{
ByteString *bs=context;
if(available<bs->length) return NO;
return memcmp(bytes,bs->bytes,bs->length)==0;
}
@implementation CSHandle (Scanning)
-(BOOL)scanForByteString:(uint8_t *)bytes length:(int)length
{
ByteString bs={ .bytes=bytes, .length=length };
return [self scanUsingMatchingFunction:MatchByteString maximumLength:length context:&bs];
}
-(int)scanUsingMatchingFunction:(CSByteMatchingFunctionPointer)function
maximumLength:(int)maximumlength
{
return [self scanUsingMatchingFunction:function maximumLength:maximumlength context:NULL];
}
-(int)scanUsingMatchingFunction:(CSByteMatchingFunctionPointer)function
maximumLength:(int)maximumlength context:(void *)contextptr
{
uint8_t buffer[65536];
off_t pos=0;
int actual=[self readAtMost:sizeof(buffer) toBuffer:buffer];
while(actual>=maximumlength)
{
for(int i=0;i<=actual-maximumlength;i++)
{
int res=function(&buffer[i],actual-i,pos++,contextptr);
if(res)
{
[self skipBytes:i-actual];
return res;
}
}
memcpy(buffer,&buffer[actual-maximumlength+1],maximumlength-1);
actual=[self readAtMost:sizeof(buffer)-maximumlength+1 toBuffer:&buffer[maximumlength-1]]+maximumlength-1;
}
for(int i=0;i<actual;i++)
{
int res=function(&buffer[i],actual-i,pos++,contextptr);
if(res)
{
[self skipBytes:i-actual];
return res;
}
}
return 0;
}
@end
|