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
|
#import "XADFastLZSSHandle.h"
// TODO: Seeking
@implementation XADFastLZSSHandle
-(id)initWithName:(NSString *)descname windowSize:(int)windowsize
{
return [self initWithName:descname length:CSHandleMaxLength windowSize:windowsize];
}
-(id)initWithName:(NSString *)descname length:(off_t)length windowSize:(int)windowsize
{
if((self=[super initWithName:descname length:length]))
{
InitializeLZSS(&lzss,windowsize);
}
return self;
}
-(id)initWithHandle:(CSHandle *)handle windowSize:(int)windowsize
{
return [self initWithHandle:handle length:CSHandleMaxLength windowSize:windowsize];
}
-(id)initWithHandle:(CSHandle *)handle length:(off_t)length windowSize:(int)windowsize
{
if((self=[super initWithHandle:handle length:length]))
{
InitializeLZSS(&lzss,windowsize);
}
return self;
}
-(void)dealloc
{
CleanupLZSS(&lzss);
[super dealloc];
}
-(void)resetStream
{
RestartLZSS(&lzss);
[self resetLZSSHandle];
}
-(int)streamAtMost:(int)num toBuffer:(void *)buffer
{
bufferpointer=buffer;
bufferpos=streampos;
bufferend=streampos+num;
XADLZSSFlushToBuffer(self);
if(bufferpos!=bufferend)
{
flushbarrier=LZSSPosition(&lzss)+LZSSWindowSize(&lzss);
[self expandFromPosition:LZSSPosition(&lzss)];
XADLZSSFlushToBuffer(self);
}
return bufferpos-streampos;
}
-(void)resetLZSSHandle {}
-(void)expandFromPosition:(off_t)pos {}
-(void)endLZSSHandle { [self endStream]; }
// TODO: remove usage of bufferpos entirely, it's somewhat redundant.
void XADLZSSFlushToBuffer(XADFastLZSSHandle *self)
{
off_t end=LZSSPosition(&self->lzss);
if(end>self->bufferend) end=self->bufferend;
int available=end-self->bufferpos;
if(available==0) return;
//if(available<0) [XADException raiseUnknownException]; // TODO: better error
CopyBytesFromLZSSWindow(&self->lzss,self->bufferpointer,self->bufferpos,available);
self->bufferpos+=available;
self->bufferpointer+=available;
self->flushbarrier+=available;
}
@end
|