ObjFW  Check-in [a8c62e1c0d]

Overview
Comment:Better code sharing between Deflate and Deflate64
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a8c62e1c0db6762a10afd1626ef10438da4e1ca957302c1ea405d6e76a770fed
User & Date: js on 2014-05-31 02:16:40
Other Links: manifest | tags
Context
2014-05-31
16:34
Work around broken Apple libc headers check-in: dccc3ed8a9 user: js tags: trunk
02:16
Better code sharing between Deflate and Deflate64 check-in: a8c62e1c0d user: js tags: trunk
01:46
tests/Makefile: Symlink libobjfw.$major.dylib check-in: dc6bc8359e user: js tags: trunk
Changes

Modified src/OFDeflate64Stream.m from [17854efe61] to [b526060610].

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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFDeflate64Stream.h"

static const uint_fast8_t numDistanceCodes = 32;
static const uint8_t lengthCodes[29] = {
	/* indices are -257, values -3 */
	0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
	64, 80, 96, 112, 128, 160, 192, 224, 0
};
static const uint8_t lengthExtraBits[29] = {
	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
	5, 5, 5, 5, 16
};
static const uint16_t distanceCodes[32] = {
	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
	513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
	32769, 49153
};
static const uint8_t distanceExtraBits[32] = {
	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
	10, 11, 11, 12, 12, 13, 13, 14, 14
};

@implementation OFDeflate64Stream
- initWithStream: (OFStream*)stream
{
	self = [super initWithStream: stream];

	_slidingWindowMask = 0xFFFF;
	_codes.numDistanceCodes = numDistanceCodes;
	_codes.lengthCodes = lengthCodes;
	_codes.lengthExtraBits = lengthExtraBits;
	_codes.distanceCodes = distanceCodes;
	_codes.distanceExtraBits = distanceExtraBits;

	return self;
}
@end







<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
10
11
12
13
14
15
16

17
18




































 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */


#define DEFLATE64
#include "OFDeflateStream.m"




































Modified src/OFDeflateStream.h from [c9168b28f2] to [97a1014dfe].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	uint_fast16_t _bufferIndex, _bufferLength;
	uint8_t _byte;
	uint_fast8_t _bitIndex, _savedBitsLength;
	uint_fast16_t _savedBits;
@protected
	uint8_t *_slidingWindow;
	uint_fast16_t _slidingWindowIndex, _slidingWindowMask;
	struct {
		uint_fast8_t numDistanceCodes;
		const uint8_t *lengthCodes;
		const uint8_t *lengthExtraBits;
		const uint16_t *distanceCodes;
		const uint8_t *distanceExtraBits;
	} _codes;
	enum {
		OF_DEFLATE_STREAM_BLOCK_HEADER,
		OF_DEFLATE_STREAM_UNCOMPRESSED_BLOCK_HEADER,
		OF_DEFLATE_STREAM_UNCOMPRESSED_BLOCK,
		OF_DEFLATE_STREAM_HUFFMAN_TREE,
		OF_DEFLATE_STREAM_HUFFMAN_BLOCK
	} _state;







<
<
<
<
<
<
<







34
35
36
37
38
39
40







41
42
43
44
45
46
47
	uint_fast16_t _bufferIndex, _bufferLength;
	uint8_t _byte;
	uint_fast8_t _bitIndex, _savedBitsLength;
	uint_fast16_t _savedBits;
@protected
	uint8_t *_slidingWindow;
	uint_fast16_t _slidingWindowIndex, _slidingWindowMask;







	enum {
		OF_DEFLATE_STREAM_BLOCK_HEADER,
		OF_DEFLATE_STREAM_UNCOMPRESSED_BLOCK_HEADER,
		OF_DEFLATE_STREAM_UNCOMPRESSED_BLOCK,
		OF_DEFLATE_STREAM_HUFFMAN_TREE,
		OF_DEFLATE_STREAM_HUFFMAN_BLOCK
	} _state;

Modified src/OFDeflateStream.m from [cefc6bbea9] to [8d93d6070f].

19
20
21
22
23
24
25

26




27
28
29
30
31
32
33
#include "config.h"

#include <stdlib.h>
#include <string.h>

#include <assert.h>


#import "OFDeflateStream.h"




#import "OFDataArray.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFReadFailedException.h"








>
|
>
>
>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "config.h"

#include <stdlib.h>
#include <string.h>

#include <assert.h>

#ifndef DEFLATE64
# import "OFDeflateStream.h"
#else
# import "OFDeflate64Stream.h"
# define OFDeflateStream OFDeflate64Stream
#endif
#import "OFDataArray.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFReadFailedException.h"

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
#define MAX_BITS 15

struct huffman_tree {
	struct huffman_tree *leafs[2];
	uint16_t value;
};


static const uint_fast8_t numDistanceCodes = 30;
static const uint8_t lengthCodes[29] = {
	/* indices are -257, values -3 */
	0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
	64, 80, 96, 112, 128, 160, 192, 224, 255
};
static const uint8_t lengthExtraBits[29] = {
	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
	5, 5, 5, 5, 0
};
static const uint16_t distanceCodes[30] = {
	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
	513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
};
static const uint8_t distanceExtraBits[30] = {
	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
	10, 11, 11, 12, 12, 13, 13
};





















static const uint8_t codeLengthsOrder[19] = {
	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
static struct huffman_tree *fixedLitLenTree, *fixedDistTree;

static bool
tryReadBits(OFDeflateStream *stream, uint_fast16_t *bits, uint_fast8_t count)







>


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
#define MAX_BITS 15

struct huffman_tree {
	struct huffman_tree *leafs[2];
	uint16_t value;
};

#ifndef DEFLATE64
static const uint_fast8_t numDistanceCodes = 30;
static const uint8_t lengthCodes[29] = {
	/* indices are -257, values -3 */
	0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
	64, 80, 96, 112, 128, 160, 192, 224, 255
};
static const uint8_t lengthExtraBits[29] = {
	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
	5, 5, 5, 5, 0
};
static const uint16_t distanceCodes[30] = {
	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
	513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
};
static const uint8_t distanceExtraBits[30] = {
	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
	10, 11, 11, 12, 12, 13, 13
};
#else
static const uint_fast8_t numDistanceCodes = 32;
static const uint8_t lengthCodes[29] = {
	/* indices are -257, values -3 */
	0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
	64, 80, 96, 112, 128, 160, 192, 224, 0
};
static const uint8_t lengthExtraBits[29] = {
	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
	5, 5, 5, 5, 16
};
static const uint16_t distanceCodes[32] = {
	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
	513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
	32769, 49153
};
static const uint8_t distanceExtraBits[32] = {
	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
	10, 11, 11, 12, 12, 13, 13, 14, 14
};
#endif
static const uint8_t codeLengthsOrder[19] = {
	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
static struct huffman_tree *fixedLitLenTree, *fixedDistTree;

static bool
tryReadBits(OFDeflateStream *stream, uint_fast16_t *bits, uint_fast8_t count)
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295

	for (i = 0; i <= 31; i++)
		lengths[i] = 5;

	fixedDistTree = constructTree(lengths, 32);
}


+ (instancetype)streamWithStream: (OFStream*)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFStream*)stream
{
	self = [super init];

	_stream = [stream retain];
	_bitIndex = 8;	/* 0-7 address the bit, 8 means fetch next byte */
	_slidingWindowMask = 0x7FFF;
	_codes.numDistanceCodes = numDistanceCodes;
	_codes.lengthCodes = lengthCodes;
	_codes.lengthExtraBits = lengthExtraBits;
	_codes.distanceCodes = distanceCodes;
	_codes.distanceExtraBits = distanceExtraBits;

	return self;
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}


- (size_t)lowlevelReadIntoBuffer: (void*)buffer_
			  length: (size_t)length
{
	uint8_t *buffer = buffer_;
	uint_fast16_t bits, i, tmp;
	uint16_t value;







>

















<
<
<
<
<










>







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301





302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

	for (i = 0; i <= 31; i++)
		lengths[i] = 5;

	fixedDistTree = constructTree(lengths, 32);
}

#ifndef DEFLATE64
+ (instancetype)streamWithStream: (OFStream*)stream
{
	return [[[self alloc] initWithStream: stream] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithStream: (OFStream*)stream
{
	self = [super init];

	_stream = [stream retain];
	_bitIndex = 8;	/* 0-7 address the bit, 8 means fetch next byte */
	_slidingWindowMask = 0x7FFF;






	return self;
}

- (void)dealloc
{
	[_stream release];

	[super dealloc];
}
#endif

- (size_t)lowlevelReadIntoBuffer: (void*)buffer_
			  length: (size_t)length
{
	uint8_t *buffer = buffer_;
	uint_fast16_t bits, i, tmp;
	uint16_t value;
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

			/* Distance of length distance pair */
			if (CTX.state == AWAIT_DISTANCE) {
				if OF_UNLIKELY (!walkTree(self, &CTX.treeIter,
				    &value))
					return bytesWritten;

				if OF_UNLIKELY (value >=
				    _codes.numDistanceCodes)
					@throw [OFInvalidFormatException
					    exception];

				CTX.distance = _codes.distanceCodes[value];
				extraBits = _codes.distanceExtraBits[value];

				if (extraBits > 0) {
					if OF_UNLIKELY (!tryReadBits(self,
					    &bits, extraBits)) {
						CTX.state =
						    AWAIT_DISTANCE_EXTRA_BITS;
						CTX.extraBits = extraBits;







|
<



|
|







630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645
646
647
648
649

			/* Distance of length distance pair */
			if (CTX.state == AWAIT_DISTANCE) {
				if OF_UNLIKELY (!walkTree(self, &CTX.treeIter,
				    &value))
					return bytesWritten;

				if OF_UNLIKELY (value >= numDistanceCodes)

					@throw [OFInvalidFormatException
					    exception];

				CTX.distance = distanceCodes[value];
				extraBits = distanceExtraBits[value];

				if (extraBits > 0) {
					if OF_UNLIKELY (!tryReadBits(self,
					    &bits, extraBits)) {
						CTX.state =
						    AWAIT_DISTANCE_EXTRA_BITS;
						CTX.extraBits = extraBits;
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
			}

			if OF_UNLIKELY (value > 285)
				@throw [OFInvalidFormatException exception];

			/* Length of length distance pair */
			lengthCodeIndex = value - 257;
			CTX.length = _codes.lengthCodes[lengthCodeIndex] + 3;
			extraBits = _codes.lengthExtraBits[lengthCodeIndex];

			if (extraBits > 0) {
				if OF_UNLIKELY (!tryReadBits(self, &bits,
				    extraBits)) {
					CTX.extraBits = extraBits;
					CTX.state = AWAIT_LENGTH_EXTRA_BITS;
					return bytesWritten;







|
|







742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
			}

			if OF_UNLIKELY (value > 285)
				@throw [OFInvalidFormatException exception];

			/* Length of length distance pair */
			lengthCodeIndex = value - 257;
			CTX.length = lengthCodes[lengthCodeIndex] + 3;
			extraBits = lengthExtraBits[lengthCodeIndex];

			if (extraBits > 0) {
				if OF_UNLIKELY (!tryReadBits(self, &bits,
				    extraBits)) {
					CTX.extraBits = extraBits;
					CTX.state = AWAIT_LENGTH_EXTRA_BITS;
					return bytesWritten;
744
745
746
747
748
749
750

751
752
753
754

755
		break;
#undef CTX
	}

	OF_UNREACHABLE
}


- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}

@end







>




>

767
768
769
770
771
772
773
774
775
776
777
778
779
780
		break;
#undef CTX
	}

	OF_UNREACHABLE
}

#ifndef DEFLATE64
- (bool)lowlevelIsAtEndOfStream
{
	return _atEndOfStream;
}
#endif
@end