File: XADCABBlockReader.m

package info (click to toggle)
unar 1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,664 kB
  • sloc: ansic: 52,939; objc: 39,563; cpp: 4,074; makefile: 99; perl: 10
file content (120 lines) | stat: -rw-r--r-- 2,537 bytes parent folder | download | duplicates (2)
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
#import "XADCABBlockReader.h"
#import "XADException.h"

@implementation XADCABBlockReader

-(id)initWithHandle:(CSHandle *)handle reservedBytes:(int)reserved
{
	if((self=[super init]))
	{
		parent=[handle retain];
		extbytes=reserved;
		numfolders=0;
	}
	return self;
}

-(void)dealloc
{
	[parent release];
	[super dealloc];
}



-(void)addFolderAtOffset:(off_t)startoffs numberOfBlocks:(int)num
{
	if(numfolders==sizeof(offsets)/sizeof(offsets[0])) [XADException raiseNotSupportedException];

	offsets[numfolders]=startoffs;
	numblocks[numfolders]=num;
	numfolders++;
}

-(void)scanLengths
{
	complen=0;
	uncomplen=0;

	for(int folder=0;folder<numfolders;folder++)
	{
		[parent seekToFileOffset:offsets[folder]];

		for(int block=0;block<numblocks[folder];block++)
		{
			/*uint32_t check=*/[parent readUInt32LE];
			int compbytes=[parent readUInt16LE];
			int uncompbytes=[parent readUInt16LE];
			[parent skipBytes:extbytes+compbytes];

			complen+=compbytes;
			uncomplen+=uncompbytes;
		}
	}
}



-(CSHandle *)handle { return parent; }

-(off_t)compressedLength { return complen; }

-(off_t)uncompressedLength { return uncomplen; }

-(void)restart
{
	[parent seekToFileOffset:offsets[0]];
	currentfolder=0;
	currentblock=0;
}

-(BOOL)readNextBlockToBuffer:(uint8_t *)buffer compressedLength:(int *)compptr
uncompressedLength:(int *)uncompptr
{
	if(currentfolder>=numfolders) [XADException raiseDecrunchException];

	uint32_t check=[parent readUInt32LE];
	int compbytes=[parent readUInt16LE];
	int uncompbytes=[parent readUInt16LE];
	[parent skipBytes:extbytes];

	if(compbytes>32768+6144) [XADException raiseIllegalDataException];

	[parent readBytes:compbytes toBuffer:buffer];

	int totalbytes=compbytes;
	while(uncompbytes==0)
	{
		currentblock=0;
		currentfolder++;

		if(currentfolder>=numfolders) [XADException raiseIllegalDataException];

		[parent seekToFileOffset:offsets[currentfolder]];
		check=[parent readUInt32LE];
		compbytes=[parent readUInt16LE];
		uncompbytes=[parent readUInt16LE];
		[parent skipBytes:extbytes];

		if(compbytes+totalbytes>32768+6144) [XADException raiseIllegalDataException];

		[parent readBytes:compbytes toBuffer:&buffer[totalbytes]];
		totalbytes+=compbytes;
	}

	currentblock++;
	if(currentblock>=numblocks[currentfolder])
	{
		// Can this happen? Not sure, supporting it anyway.
		currentblock=0;
		currentfolder++;
		[parent seekToFileOffset:offsets[currentfolder]];
	}

	if(compptr) *compptr=totalbytes;
	if(uncompptr) *uncompptr=uncompbytes;

	return currentfolder>=numfolders;
}

@end