PageRenderTime 14ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/decoders/binary/zlib.d

http://github.com/wilkie/djehuty
D | 183 lines | 85 code | 51 blank | 47 comment | 17 complexity | f5c1047763c002d8ee621d99fed71ed5 MD5 | raw file
  1/*
  2 * zlib.d
  3 *
  4 * This file implements the ZLIB standard. ZLIB is basically a wrapper around
  5 * the DEFLATE algorithm.
  6 *
  7 * Author: Dave Wilkinson
  8 *
  9 */
 10
 11module decoders.binary.zlib;
 12
 13import decoders.binary.decoder;
 14import decoders.binary.deflate;
 15
 16import core.stream;
 17import core.definitions;
 18
 19// Section: Codecs/Binary
 20
 21// Description: This represents the ZLIB Codec.
 22class ZLIBDecoder : BinaryDecoder {
 23	StreamData decode(Stream stream, Stream toStream) {
 24		for (;;) {
 25			switch (decoderState) {
 26				// INIT DECODER //
 27			case ZLIB_STATE_INIT:
 28				// SET VARIABLES WITHIN IDP
 29
 30				// GOTO NEXT STEP
 31
 32				decoderState = ZLIB_STATE_READ_HEADER;
 33
 34				// READ STREAM HEADER //
 35			case ZLIB_STATE_READ_HEADER:
 36
 37				if (!(stream.read(&zlibStreamHeader,2))) {
 38					return StreamData.Required;
 39				}
 40
 41				// GET COMPRESSION METHOD, INFO
 42
 43				// CM:
 44				zlibCompressionMethod = cast(ubyte)(zlibStreamHeader.zlibCMF & 0xF);
 45
 46				// CINFO:
 47				zlibCompressionInfo = cast(ubyte)(zlibStreamHeader.zlibCMF >> 4);
 48
 49				// GET FLAGS
 50
 51				// FDICT
 52				zlibIsDictionary = cast(ubyte)(zlibStreamHeader.zlibFLG & 32);
 53
 54				// FCHECK
 55				zlibFCHECK = cast(ubyte)(zlibStreamHeader.zlibFLG & 0xF);
 56
 57				// FLEVEL
 58				zlibCompressionLevel = cast(ubyte)(zlibStreamHeader.zlibFLG >> 6);
 59
 60				if (zlibCompressionMethod == 8) {
 61					///write("zlib - using DEFLATE\n");
 62
 63					if (zlibCompressionInfo > 7) {
 64						//write("zlib - window size is invalid\n");
 65
 66						return StreamData.Invalid;
 67					}
 68					else if (zlibCompressionInfo == 7) {
 69	//					write("zlib - window size of 32K\n");
 70					}
 71
 72				}
 73				else {
 74					//ite("zlib - unsupported compression method\n");
 75					return StreamData.Invalid;
 76				}
 77
 78				if (zlibIsDictionary) {
 79					//write("zlib - has preset dictionary\n");
 80				}
 81
 82				switch (zlibCompressionLevel) {
 83				case 0:
 84					//write("zlib - compression level: fastest\n");
 85					break;
 86				case 1:
 87					//write("zlib - compression level: fast\n");
 88					break;
 89				case 2:
 90					//write("zlib - compression level: default\n");
 91					break;
 92				case 3:
 93					//write("zlib - compression level: maximum\n");
 94					break;
 95
 96				default:
 97					//write("zlib - compression level odd, continuing anyway\n");
 98					break;
 99				}
100
101				decoderState = ZLIB_STATE_STREAM_DEFLATE;
102
103			case ZLIB_STATE_STREAM_DEFLATE:
104
105				StreamData ret;
106
107				//stream.read(decoding, stream.getRemaining() - 4);
108
109				//decoding.rewind();
110	//	writeln("zlib deflate");
111
112				if (deflateDecompressor is null) {
113					deflateDecompressor = new DEFLATEDecoder();
114				}
115
116				if ((ret = deflateDecompressor.decode(stream, toStream)) != StreamData.Required) {
117					decoderState = ZLIB_STATE_READ_ADLER32;
118				}
119				else {
120					////OutputDebugStringA("zlib - returning early\n");
121					return ret;
122				}
123
124			case ZLIB_STATE_READ_ADLER32:
125	//	writeln("zlib read adler32");
126
127				//OutputDebugStringA("zlib - decompression done, reading ALDER32\n");
128
129				if (!(stream.skip(4))) {
130					//return StreamData.Required;
131				}
132				//OutputDebugStringA("zlib - returning\n");
133
134				return StreamData.Complete;
135
136
137			default:
138				break;
139			}
140
141			break;
142		}
143		
144		return StreamData.Invalid;
145	}
146
147private:
148
149	const auto ZLIB_STATE_INIT						= 0;
150
151	const auto ZLIB_STATE_READ_HEADER				= 1;
152	const auto ZLIB_STATE_STREAM_DEFLATE			= 2;
153	const auto ZLIB_STATE_READ_ADLER32				= 3;
154
155	align(1) struct _zlib_cmf_flg_header {
156		ubyte zlibCMF;
157		ubyte zlibFLG;
158	}
159protected:
160
161	// CMF, FLG
162	_zlib_cmf_flg_header zlibStreamHeader;
163
164	// CM
165	ubyte zlibCompressionMethod;
166
167	// CINFO
168	ubyte zlibCompressionInfo;
169
170	// FDICT
171	ubyte zlibIsDictionary;
172
173	//FLEVEL
174	ubyte zlibCompressionLevel;
175
176	//FCHECK
177	ubyte zlibFCHECK;
178
179
180	// USED WHEN STREAMING THE DECODER
181	DEFLATEDecoder deflateDecompressor;
182
183}