-
Notifications
You must be signed in to change notification settings - Fork 350
/
Copy pathinflate.js
120 lines (102 loc) · 2.95 KB
/
inflate.js
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
goog.provide('Zlib.Inflate');
goog.require('USE_TYPEDARRAY');
goog.require('Zlib.Adler32');
goog.require('Zlib.RawInflate');
goog.scope(function() {
/**
* @constructor
* @param {!(Uint8Array|Array)} input deflated buffer.
* @param {Object=} opt_params option parameters.
*
* opt_params は以下のプロパティを指定する事ができます。
* - index: input buffer の deflate コンテナの開始位置.
* - blockSize: バッファのブロックサイズ.
* - verify: 伸張が終わった後 adler-32 checksum の検証を行うか.
* - bufferType: Zlib.Inflate.BufferType の値によってバッファの管理方法を指定する.
* Zlib.Inflate.BufferType は Zlib.RawInflate.BufferType のエイリアス.
*/
Zlib.Inflate = function(input, opt_params) {
/** @type {number} */
var bufferSize;
/** @type {Zlib.Inflate.BufferType} */
var bufferType;
/** @type {number} */
var cmf;
/** @type {number} */
var flg;
/** @type {!(Uint8Array|Array)} */
this.input = input;
/** @type {number} */
this.ip = 0;
/** @type {Zlib.RawInflate} */
this.rawinflate;
/** @type {(boolean|undefined)} verify flag. */
this.verify;
// option parameters
if (opt_params || !(opt_params = {})) {
if (opt_params['index']) {
this.ip = opt_params['index'];
}
if (opt_params['verify']) {
this.verify = opt_params['verify'];
}
}
// Compression Method and Flags
cmf = input[this.ip++];
flg = input[this.ip++];
// compression method
switch (cmf & 0x0f) {
case Zlib.CompressionMethod.DEFLATE:
this.method = Zlib.CompressionMethod.DEFLATE;
break;
default:
throw new Error('unsupported compression method');
}
// fcheck
if (((cmf << 8) + flg) % 31 !== 0) {
throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31);
}
// fdict (not supported)
if (flg & 0x20) {
throw new Error('fdict flag is not supported');
}
// RawInflate
this.rawinflate = new Zlib.RawInflate(input, {
'index': this.ip,
'bufferSize': opt_params['bufferSize'],
'bufferType': opt_params['bufferType'],
'resize': opt_params['resize']
});
}
/**
* @enum {number}
*/
Zlib.Inflate.BufferType = Zlib.RawInflate.BufferType;
/**
* decompress.
* @return {!(Uint8Array|Array)} inflated buffer.
*/
Zlib.Inflate.prototype.decompress = function() {
/** @type {!(Array|Uint8Array)} input buffer. */
var input = this.input;
/** @type {!(Uint8Array|Array)} inflated buffer. */
var buffer;
/** @type {number} adler-32 checksum */
var adler32;
buffer = this.rawinflate.decompress();
this.ip = this.rawinflate.ip;
// verify adler-32
if (this.verify) {
adler32 = (
input[this.ip++] << 24 | input[this.ip++] << 16 |
input[this.ip++] << 8 | input[this.ip++]
) >>> 0;
if (adler32 !== Zlib.Adler32(buffer)) {
throw new Error('invalid adler-32 checksum');
}
}
return buffer;
};
// end of scope
});
/* vim:set expandtab ts=2 sw=2 tw=80: */