pygments.rb 0.5.2 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -0
- data/lexers +0 -0
- data/lib/pygments/version.rb +1 -1
- data/test/test_pygments.rb +1 -1
- data/vendor/custom_lexers/github.py +15 -9
- data/vendor/pygments-main/AUTHORS +12 -2
- data/vendor/pygments-main/CHANGES +52 -2
- data/vendor/pygments-main/REVISION +1 -1
- data/vendor/pygments-main/docs/src/lexerdevelopment.txt +52 -0
- data/vendor/pygments-main/external/lasso-builtins-generator-9.lasso +67 -44
- data/vendor/pygments-main/pygmentize +1 -1
- data/vendor/pygments-main/pygments/filters/__init__.py +2 -2
- data/vendor/pygments-main/pygments/formatter.py +3 -0
- data/vendor/pygments-main/pygments/lexers/__init__.py +11 -0
- data/vendor/pygments-main/pygments/lexers/_lassobuiltins.py +2880 -3124
- data/vendor/pygments-main/pygments/lexers/_mapping.py +30 -20
- data/vendor/pygments-main/pygments/lexers/_robotframeworklexer.py +1 -1
- data/vendor/pygments-main/pygments/lexers/_stan_builtins.py +206 -20
- data/vendor/pygments-main/pygments/lexers/agile.py +378 -5
- data/vendor/pygments-main/pygments/lexers/asm.py +2 -2
- data/vendor/pygments-main/pygments/lexers/compiled.py +235 -8
- data/vendor/pygments-main/pygments/lexers/dotnet.py +88 -47
- data/vendor/pygments-main/pygments/lexers/functional.py +195 -62
- data/vendor/pygments-main/pygments/lexers/github.py +15 -9
- data/vendor/pygments-main/pygments/lexers/jvm.py +14 -11
- data/vendor/pygments-main/pygments/lexers/math.py +284 -18
- data/vendor/pygments-main/pygments/lexers/other.py +132 -21
- data/vendor/pygments-main/pygments/lexers/shell.py +29 -15
- data/vendor/pygments-main/pygments/lexers/sql.py +1 -1
- data/vendor/pygments-main/pygments/lexers/templates.py +8 -8
- data/vendor/pygments-main/pygments/lexers/text.py +59 -9
- data/vendor/pygments-main/pygments/lexers/web.py +832 -210
- data/vendor/pygments-main/pygments/modeline.py +40 -0
- data/vendor/pygments-main/tests/examplefiles/Deflate.fs +578 -0
- data/vendor/pygments-main/tests/examplefiles/Get-CommandDefinitionHtml.ps1 +66 -0
- data/vendor/pygments-main/tests/examplefiles/IPDispatchC.nc +104 -0
- data/vendor/pygments-main/tests/examplefiles/IPDispatchP.nc +671 -0
- data/vendor/pygments-main/tests/examplefiles/RoleQ.pm6 +23 -0
- data/vendor/pygments-main/tests/examplefiles/example.ceylon +29 -10
- data/vendor/pygments-main/tests/examplefiles/example.clay +33 -0
- data/vendor/pygments-main/tests/examplefiles/example.hx +142 -0
- data/vendor/pygments-main/tests/examplefiles/example.lagda +19 -0
- data/vendor/pygments-main/tests/examplefiles/example.rexx +50 -0
- data/vendor/pygments-main/tests/examplefiles/example.stan +86 -75
- data/vendor/pygments-main/tests/examplefiles/garcia-wachs.kk +40 -30
- data/vendor/pygments-main/tests/examplefiles/grammar-test.p6 +22 -0
- data/vendor/pygments-main/tests/examplefiles/objc_example.m +7 -0
- data/vendor/pygments-main/tests/examplefiles/py3tb_test.py3tb +4 -0
- data/vendor/pygments-main/tests/examplefiles/swig_java.swg +1329 -0
- data/vendor/pygments-main/tests/examplefiles/swig_std_vector.i +225 -0
- data/vendor/pygments-main/tests/examplefiles/test.agda +102 -0
- data/vendor/pygments-main/tests/examplefiles/test.bb +95 -0
- data/vendor/pygments-main/tests/examplefiles/test.ebnf +31 -0
- data/vendor/pygments-main/tests/examplefiles/test.p6 +252 -0
- data/vendor/pygments-main/tests/examplefiles/type.lisp +16 -0
- data/vendor/pygments-main/tests/test_basic_api.py +3 -3
- data/vendor/pygments-main/tests/test_lexers_other.py +68 -0
- metadata +21 -2
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
pygments.modeline
|
4
|
+
~~~~~~~~~~~~~~~~~
|
5
|
+
|
6
|
+
A simple modeline parser (based on pymodeline).
|
7
|
+
|
8
|
+
:copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
|
9
|
+
:license: BSD, see LICENSE for details.
|
10
|
+
"""
|
11
|
+
|
12
|
+
import re
|
13
|
+
|
14
|
+
__all__ = ['get_filetype_from_buffer']
|
15
|
+
|
16
|
+
modeline_re = re.compile(r'''
|
17
|
+
(?: vi | vim | ex ) (?: [<=>]? \d* )? :
|
18
|
+
.* (?: ft | filetype | syn | syntax ) = ( [^:\s]+ )
|
19
|
+
''', re.VERBOSE)
|
20
|
+
|
21
|
+
def get_filetype_from_line(l):
|
22
|
+
m = modeline_re.search(l)
|
23
|
+
if m:
|
24
|
+
return m.group(1)
|
25
|
+
|
26
|
+
def get_filetype_from_buffer(buf, max_lines=5):
|
27
|
+
"""
|
28
|
+
Scan the buffer for modelines and return filetype if one is found.
|
29
|
+
"""
|
30
|
+
lines = buf.splitlines()
|
31
|
+
for l in lines[-1:-max_lines-1:-1]:
|
32
|
+
ret = get_filetype_from_line(l)
|
33
|
+
if ret:
|
34
|
+
return ret
|
35
|
+
for l in lines[max_lines:0:-1]:
|
36
|
+
ret = get_filetype_from_line(l)
|
37
|
+
if ret:
|
38
|
+
return ret
|
39
|
+
|
40
|
+
return None
|
@@ -0,0 +1,578 @@
|
|
1
|
+
// public domain
|
2
|
+
|
3
|
+
module Deflate
|
4
|
+
|
5
|
+
open System
|
6
|
+
open System.Collections.Generic
|
7
|
+
open System.IO
|
8
|
+
open System.Linq
|
9
|
+
open Crc
|
10
|
+
|
11
|
+
let maxbuf = 32768
|
12
|
+
let maxlen = 258
|
13
|
+
|
14
|
+
let getBit (b:byte) (bit:int) =
|
15
|
+
if b &&& (1uy <<< bit) = 0uy then 0 else 1
|
16
|
+
|
17
|
+
type BitReader(sin:Stream) =
|
18
|
+
let mutable bit = 8
|
19
|
+
let mutable cur = 0uy
|
20
|
+
|
21
|
+
member x.Skip() =
|
22
|
+
bit <- 8
|
23
|
+
|
24
|
+
member x.ReadBit() =
|
25
|
+
if bit = 8 then
|
26
|
+
bit <- 0
|
27
|
+
let b = sin.ReadByte()
|
28
|
+
if b = -1 then
|
29
|
+
failwith "バッファを超過しました"
|
30
|
+
cur <- byte b
|
31
|
+
let ret = if cur &&& (1uy <<< bit) = 0uy then 0 else 1
|
32
|
+
bit <- bit + 1
|
33
|
+
ret
|
34
|
+
|
35
|
+
member x.ReadLE n =
|
36
|
+
let mutable ret = 0
|
37
|
+
for i = 0 to n - 1 do
|
38
|
+
if x.ReadBit() = 1 then ret <- ret ||| (1 <<< i)
|
39
|
+
ret
|
40
|
+
|
41
|
+
member x.ReadBE n =
|
42
|
+
let mutable ret = 0
|
43
|
+
for i = 0 to n - 1 do
|
44
|
+
ret <- (ret <<< 1) ||| x.ReadBit()
|
45
|
+
ret
|
46
|
+
|
47
|
+
member x.ReadBytes len =
|
48
|
+
if bit <> 8 then bit <- 8
|
49
|
+
let buf = Array.zeroCreate<byte> len
|
50
|
+
ignore <| sin.Read(buf, 0, len)
|
51
|
+
buf
|
52
|
+
|
53
|
+
type WriteBuffer(sout:Stream) =
|
54
|
+
let mutable prev:byte[] = null
|
55
|
+
let mutable buf = Array.zeroCreate<byte> maxbuf
|
56
|
+
let mutable p = 0
|
57
|
+
|
58
|
+
let next newbuf =
|
59
|
+
prev <- buf
|
60
|
+
buf <- if newbuf then Array.zeroCreate<byte> maxbuf else null
|
61
|
+
p <- 0
|
62
|
+
|
63
|
+
member x.Close() =
|
64
|
+
next false
|
65
|
+
next false
|
66
|
+
|
67
|
+
interface IDisposable with
|
68
|
+
member x.Dispose() = x.Close()
|
69
|
+
|
70
|
+
member x.WriteByte (b:byte) =
|
71
|
+
buf.[p] <- b
|
72
|
+
sout.WriteByte b
|
73
|
+
p <- p + 1
|
74
|
+
if p = maxbuf then next true
|
75
|
+
|
76
|
+
member x.Write (src:byte[]) start len =
|
77
|
+
let maxlen = maxbuf - p
|
78
|
+
if len <= maxlen then
|
79
|
+
Array.Copy(src, start, buf, p, len)
|
80
|
+
sout.Write(src, start, len)
|
81
|
+
p <- p + len
|
82
|
+
if p = maxbuf then next true
|
83
|
+
else
|
84
|
+
x.Write src start maxlen
|
85
|
+
x.Write src (start + maxlen) (len - maxlen)
|
86
|
+
|
87
|
+
member x.Copy len dist =
|
88
|
+
if dist < 1 then
|
89
|
+
failwith <| sprintf "dist too small: %d < 1" dist
|
90
|
+
elif dist > maxbuf then
|
91
|
+
failwith <| sprintf "dist too big: %d > %d" dist maxbuf
|
92
|
+
let pp = p - dist
|
93
|
+
if pp < 0 then
|
94
|
+
if prev = null then
|
95
|
+
failwith <| sprintf "dist too big: %d > %d" dist p
|
96
|
+
let pp = pp + maxbuf
|
97
|
+
let maxlen = maxbuf - pp
|
98
|
+
if len <= maxlen then
|
99
|
+
x.Write prev pp len
|
100
|
+
else
|
101
|
+
x.Write prev pp maxlen
|
102
|
+
x.Copy (len - maxlen) dist
|
103
|
+
else
|
104
|
+
let maxlen = p - pp
|
105
|
+
if len <= maxlen then
|
106
|
+
x.Write buf pp len
|
107
|
+
else
|
108
|
+
if dist = 1 then
|
109
|
+
let b = buf.[pp]
|
110
|
+
for i = 1 to len do
|
111
|
+
x.WriteByte b
|
112
|
+
else
|
113
|
+
let buf' = buf
|
114
|
+
let mutable len' = len
|
115
|
+
while len' > 0 do
|
116
|
+
let len'' = Math.Min(len', maxlen)
|
117
|
+
x.Write buf' pp len''
|
118
|
+
len' <- len' - len''
|
119
|
+
|
120
|
+
type Huffman(lens:int[]) =
|
121
|
+
let vals = Array.zeroCreate<int> lens.Length
|
122
|
+
let min = lens.Where(fun x -> x > 0).Min()
|
123
|
+
let max = lens.Max()
|
124
|
+
let counts = Array.zeroCreate<int> (max + 1)
|
125
|
+
let firsts = Array.zeroCreate<int> (max + 1)
|
126
|
+
let nexts = Array.zeroCreate<int> (max + 1)
|
127
|
+
let tables = Array.zeroCreate<int[]>(max + 1)
|
128
|
+
|
129
|
+
do
|
130
|
+
for len in lens do
|
131
|
+
if len > 0 then counts.[len] <- counts.[len] + 1
|
132
|
+
for i = 1 to max do
|
133
|
+
firsts.[i] <- (firsts.[i - 1] + counts.[i - 1]) <<< 1
|
134
|
+
Array.Copy(firsts, 0, nexts, 0, max + 1)
|
135
|
+
for i = 0 to vals.Length - 1 do
|
136
|
+
let len = lens.[i]
|
137
|
+
if len > 0 then
|
138
|
+
vals.[i] <- nexts.[len]
|
139
|
+
nexts.[len] <- nexts.[len] + 1
|
140
|
+
|
141
|
+
for i = 0 to vals.Length - 1 do
|
142
|
+
let len = lens.[i]
|
143
|
+
if len > 0 then
|
144
|
+
let start = firsts.[len]
|
145
|
+
if tables.[len] = null then
|
146
|
+
let count = nexts.[len] - start
|
147
|
+
tables.[len] <- Array.zeroCreate<int> count
|
148
|
+
tables.[len].[vals.[i] - start] <- i
|
149
|
+
|
150
|
+
member x.GetValue h =
|
151
|
+
let rec getv i =
|
152
|
+
if i > max then -1 else
|
153
|
+
if h < nexts.[i] then
|
154
|
+
tables.[i].[h - firsts.[i]]
|
155
|
+
else
|
156
|
+
getv (i + 1)
|
157
|
+
getv min
|
158
|
+
|
159
|
+
member x.Read(br:BitReader) =
|
160
|
+
let rec read h i =
|
161
|
+
if h < nexts.[i] then
|
162
|
+
tables.[i].[h - firsts.[i]]
|
163
|
+
else
|
164
|
+
read ((h <<< 1) ||| br.ReadBit()) (i + 1)
|
165
|
+
read (br.ReadBE min) min
|
166
|
+
|
167
|
+
type [<AbstractClass>] HuffmanDecoder() =
|
168
|
+
abstract GetValue: unit->int
|
169
|
+
abstract GetDistance: unit->int
|
170
|
+
|
171
|
+
type FixedHuffman(br:BitReader) =
|
172
|
+
inherit HuffmanDecoder()
|
173
|
+
|
174
|
+
override x.GetValue() =
|
175
|
+
let v = br.ReadBE 7
|
176
|
+
if v < 24 then v + 256 else
|
177
|
+
let v = (v <<< 1) ||| br.ReadBit()
|
178
|
+
if v < 192 then v - 48
|
179
|
+
elif v < 200 then v + 88
|
180
|
+
else ((v <<< 1) ||| br.ReadBit()) - 256
|
181
|
+
|
182
|
+
override x.GetDistance() = br.ReadBE 5
|
183
|
+
|
184
|
+
type DynamicHuffman(br:BitReader) =
|
185
|
+
inherit HuffmanDecoder()
|
186
|
+
|
187
|
+
let lit, dist =
|
188
|
+
let hlit =
|
189
|
+
let hlit = (br.ReadLE 5) + 257
|
190
|
+
if hlit > 286 then failwith <| sprintf "hlit: %d > 286" hlit
|
191
|
+
hlit
|
192
|
+
|
193
|
+
let hdist =
|
194
|
+
let hdist = (br.ReadLE 5) + 1
|
195
|
+
if hdist > 32 then failwith <| sprintf "hdist: %d > 32" hdist
|
196
|
+
hdist
|
197
|
+
|
198
|
+
let hclen =
|
199
|
+
let hclen = (br.ReadLE 4) + 4
|
200
|
+
if hclen > 19 then failwith <| sprintf "hclen: %d > 19" hclen
|
201
|
+
hclen
|
202
|
+
|
203
|
+
let clen =
|
204
|
+
let hclens = Array.zeroCreate<int> 19
|
205
|
+
let order = [| 16; 17; 18; 0; 8; 7; 9; 6; 10; 5;
|
206
|
+
11; 4; 12; 3; 13; 2; 14; 1; 15 |]
|
207
|
+
for i = 0 to hclen - 1 do
|
208
|
+
hclens.[order.[i]] <- br.ReadLE 3
|
209
|
+
new Huffman(hclens)
|
210
|
+
|
211
|
+
let ld = Array.zeroCreate<int>(hlit + hdist)
|
212
|
+
let mutable i = 0
|
213
|
+
while i < ld.Length do
|
214
|
+
let v = clen.Read(br)
|
215
|
+
if v < 16 then
|
216
|
+
ld.[i] <- v
|
217
|
+
i <- i + 1
|
218
|
+
else
|
219
|
+
let r, v =
|
220
|
+
match v with
|
221
|
+
| 16 -> (br.ReadLE 2) + 3, ld.[i - 1]
|
222
|
+
| 17 -> (br.ReadLE 3) + 3, 0
|
223
|
+
| 18 -> (br.ReadLE 7) + 11, 0
|
224
|
+
| _ -> failwith "不正な値です。"
|
225
|
+
for j = 0 to r - 1 do
|
226
|
+
ld.[i + j] <- v
|
227
|
+
i <- i + r
|
228
|
+
|
229
|
+
new Huffman(ld.[0 .. hlit - 1]),
|
230
|
+
new Huffman(ld.[hlit .. hlit + hdist - 1])
|
231
|
+
|
232
|
+
override x.GetValue() = lit.Read br
|
233
|
+
override x.GetDistance() = dist.Read br
|
234
|
+
|
235
|
+
let getLitExLen v = if v < 265 || v = 285 then 0 else (v - 261) >>> 2
|
236
|
+
let getDistExLen d = if d < 4 then 0 else (d - 2) >>> 1
|
237
|
+
|
238
|
+
let litlens =
|
239
|
+
let litlens = Array.zeroCreate<int> 286
|
240
|
+
let mutable v = 3
|
241
|
+
for i = 257 to 284 do
|
242
|
+
litlens.[i] <- v
|
243
|
+
v <- v + (1 <<< (getLitExLen i))
|
244
|
+
litlens.[285] <- maxlen
|
245
|
+
litlens.[257..285]
|
246
|
+
|
247
|
+
let distlens =
|
248
|
+
let distlens = Array.zeroCreate<int> 30
|
249
|
+
let mutable v = 1
|
250
|
+
for i = 0 to 29 do
|
251
|
+
distlens.[i] <- v
|
252
|
+
v <- v + (1 <<< (getDistExLen i))
|
253
|
+
distlens
|
254
|
+
|
255
|
+
type Reader(sin:Stream) =
|
256
|
+
inherit Stream()
|
257
|
+
|
258
|
+
let br = new BitReader(sin)
|
259
|
+
let fh = new FixedHuffman(br)
|
260
|
+
|
261
|
+
let sout = new MemoryStream()
|
262
|
+
let dbuf = new WriteBuffer(sout)
|
263
|
+
|
264
|
+
let mutable cache:byte[] = null
|
265
|
+
let mutable canRead = true
|
266
|
+
|
267
|
+
let rec read (h:HuffmanDecoder) =
|
268
|
+
let v = h.GetValue()
|
269
|
+
if v > 285 then failwith <| sprintf "不正な値: %d" v
|
270
|
+
if v < 256 then
|
271
|
+
dbuf.WriteByte(byte v)
|
272
|
+
elif v > 256 then
|
273
|
+
let len =
|
274
|
+
if v < 265 then v - 254 else
|
275
|
+
litlens.[v - 257] + (br.ReadLE (getLitExLen v))
|
276
|
+
let dist =
|
277
|
+
let d = h.GetDistance()
|
278
|
+
if d > 29 then failwith <| sprintf "不正な距離: %d" d
|
279
|
+
if d < 4 then d + 1 else
|
280
|
+
distlens.[d] + (br.ReadLE (getDistExLen d))
|
281
|
+
dbuf.Copy len dist
|
282
|
+
if v <> 256 then read h
|
283
|
+
|
284
|
+
override x.CanRead = canRead
|
285
|
+
override x.CanWrite = false
|
286
|
+
override x.CanSeek = false
|
287
|
+
override x.Flush() = ()
|
288
|
+
|
289
|
+
override x.Close() =
|
290
|
+
dbuf.Close()
|
291
|
+
canRead <- false
|
292
|
+
|
293
|
+
override x.Read(buffer, offset, count) =
|
294
|
+
let offset =
|
295
|
+
if cache = null then 0 else
|
296
|
+
let clen = cache.Length
|
297
|
+
let len = Math.Min(clen, count)
|
298
|
+
Array.Copy(cache, 0, buffer, offset, len)
|
299
|
+
cache <- if len = clen then null
|
300
|
+
else cache.[len .. clen - 1]
|
301
|
+
len
|
302
|
+
let req = int64 <| count - offset
|
303
|
+
while canRead && sout.Length < req do
|
304
|
+
x.readBlock()
|
305
|
+
let len =
|
306
|
+
if sout.Length = 0L then 0 else
|
307
|
+
let data = sout.ToArray()
|
308
|
+
sout.SetLength(0L)
|
309
|
+
let dlen = data.Length
|
310
|
+
let len = Math.Min(int req, dlen)
|
311
|
+
Array.Copy(data, 0, buffer, offset, len)
|
312
|
+
if dlen > len then
|
313
|
+
cache <- data.[len..]
|
314
|
+
len
|
315
|
+
offset + len
|
316
|
+
|
317
|
+
override x.Position
|
318
|
+
with get() = raise <| new NotImplementedException()
|
319
|
+
and set(v) = raise <| new NotImplementedException()
|
320
|
+
|
321
|
+
override x.Length = raise <| new NotImplementedException()
|
322
|
+
override x.Seek(_, _) = raise <| new NotImplementedException()
|
323
|
+
override x.Write(_, _, _) = raise <| new NotImplementedException()
|
324
|
+
override x.SetLength(_) = raise <| new NotImplementedException()
|
325
|
+
|
326
|
+
member private x.readBlock() =
|
327
|
+
let bfinal = br.ReadBit()
|
328
|
+
match br.ReadLE 2 with
|
329
|
+
| 0 -> br.Skip()
|
330
|
+
let len = br.ReadLE 16
|
331
|
+
let nlen = br.ReadLE 16
|
332
|
+
if len + nlen <> 0x10000 then
|
333
|
+
failwith "不正な非圧縮長"
|
334
|
+
dbuf.Write (br.ReadBytes len) 0 len
|
335
|
+
| 1 -> read fh
|
336
|
+
| 2 -> read (new DynamicHuffman(br))
|
337
|
+
| _ -> failwith "不正なブロックタイプ"
|
338
|
+
if bfinal = 1 then
|
339
|
+
canRead <- false
|
340
|
+
x.Close()
|
341
|
+
|
342
|
+
type BitWriter(sout:Stream) =
|
343
|
+
let mutable bit = 0
|
344
|
+
let mutable cur = 0uy
|
345
|
+
|
346
|
+
member x.Skip() =
|
347
|
+
if bit > 0 then
|
348
|
+
sout.WriteByte(cur)
|
349
|
+
bit <- 0
|
350
|
+
cur <- 0uy
|
351
|
+
|
352
|
+
interface IDisposable with
|
353
|
+
member x.Dispose() =
|
354
|
+
x.Skip()
|
355
|
+
sout.Flush()
|
356
|
+
|
357
|
+
member x.WriteBit(b:int) =
|
358
|
+
cur <- cur ||| ((byte b) <<< bit)
|
359
|
+
bit <- bit + 1
|
360
|
+
if bit = 8 then
|
361
|
+
sout.WriteByte(cur)
|
362
|
+
bit <- 0
|
363
|
+
cur <- 0uy
|
364
|
+
|
365
|
+
member x.WriteLE (len:int) (b:int) =
|
366
|
+
for i = 0 to len - 1 do
|
367
|
+
x.WriteBit <| if (b &&& (1 <<< i)) = 0 then 0 else 1
|
368
|
+
|
369
|
+
member x.WriteBE (len:int) (b:int) =
|
370
|
+
for i = len - 1 downto 0 do
|
371
|
+
x.WriteBit <| if (b &&& (1 <<< i)) = 0 then 0 else 1
|
372
|
+
|
373
|
+
member x.WriteBytes(data:byte[]) =
|
374
|
+
x.Skip()
|
375
|
+
sout.Write(data, 0, data.Length)
|
376
|
+
|
377
|
+
type FixedHuffmanWriter(bw:BitWriter) =
|
378
|
+
member x.Write (b:int) =
|
379
|
+
if b < 144 then
|
380
|
+
bw.WriteBE 8 (b + 0b110000)
|
381
|
+
elif b < 256 then
|
382
|
+
bw.WriteBE 9 (b - 144 + 0b110010000)
|
383
|
+
elif b < 280 then
|
384
|
+
bw.WriteBE 7 (b - 256)
|
385
|
+
elif b < 288 then
|
386
|
+
bw.WriteBE 8 (b - 280 + 0b11000000)
|
387
|
+
|
388
|
+
member x.WriteLen (len:int) =
|
389
|
+
if len < 3 || len > maxlen then
|
390
|
+
failwith <| sprintf "不正な長さ: %d" len
|
391
|
+
let mutable ll = 285
|
392
|
+
while len < litlens.[ll - 257] do
|
393
|
+
ll <- ll - 1
|
394
|
+
x.Write ll
|
395
|
+
bw.WriteLE (getLitExLen ll) (len - litlens.[ll - 257])
|
396
|
+
|
397
|
+
member x.WriteDist (d:int) =
|
398
|
+
if d < 1 || d > maxbuf then
|
399
|
+
failwith <| sprintf "不正な距離: %d" d
|
400
|
+
let mutable dl = 29
|
401
|
+
while d < distlens.[dl] do
|
402
|
+
dl <- dl - 1
|
403
|
+
bw.WriteBE 5 dl
|
404
|
+
bw.WriteLE (getDistExLen dl) (d - distlens.[dl])
|
405
|
+
|
406
|
+
let maxbuf2 = maxbuf * 2
|
407
|
+
let buflen = maxbuf2 + maxlen
|
408
|
+
|
409
|
+
let inline getHash (buf:byte[]) pos =
|
410
|
+
((int buf.[pos]) <<< 4) ^^^ ((int buf.[pos + 1]) <<< 2) ^^^ (int buf.[pos + 2])
|
411
|
+
|
412
|
+
let inline addHash (hash:List<int>[]) (buf:byte[]) pos =
|
413
|
+
if buf.[pos] <> buf.[pos + 1] then
|
414
|
+
hash.[getHash buf pos].Add pos
|
415
|
+
|
416
|
+
let inline addHash2 (tables:int[,]) (counts:int[]) (buf:byte[]) pos =
|
417
|
+
if buf.[pos] <> buf.[pos + 1] then
|
418
|
+
let h = getHash buf pos
|
419
|
+
let c = counts.[h]
|
420
|
+
tables.[h, c &&& 15] <- pos
|
421
|
+
counts.[h] <- c + 1
|
422
|
+
|
423
|
+
type Writer(t:int, sin:Stream) =
|
424
|
+
let mutable length = buflen
|
425
|
+
let buf = Array.zeroCreate<byte> buflen
|
426
|
+
let tables, counts =
|
427
|
+
if t = 2 then Array2D.zeroCreate<int> 4096 16, Array.create 4096 0 else null, null
|
428
|
+
let hash = if tables = null then [| for _ in 0..4095 -> new List<int>() |] else null
|
429
|
+
let mutable crc = ~~~0u
|
430
|
+
|
431
|
+
let read pos len =
|
432
|
+
let rlen = sin.Read(buf, pos, len)
|
433
|
+
if rlen < len then length <- pos + rlen
|
434
|
+
for i = pos to pos + rlen - 1 do
|
435
|
+
let b = int(crc ^^^ (uint32 buf.[i])) &&& 0xff
|
436
|
+
crc <- (crc >>> 8) ^^^ crc32_table.[b]
|
437
|
+
if hash <> null then
|
438
|
+
for list in hash do list.Clear()
|
439
|
+
else
|
440
|
+
Array.fill counts 0 counts.Length 0
|
441
|
+
|
442
|
+
do
|
443
|
+
read 0 buflen
|
444
|
+
|
445
|
+
let search (pos:int) =
|
446
|
+
let mutable maxp = -1
|
447
|
+
let mutable maxl = 2
|
448
|
+
let mlen = Math.Min(maxlen, length - pos)
|
449
|
+
let last = Math.Max(0, pos - maxbuf)
|
450
|
+
let h = getHash buf pos
|
451
|
+
if hash <> null then
|
452
|
+
let list = hash.[h]
|
453
|
+
let mutable i = list.Count - 1
|
454
|
+
while i >= 0 do
|
455
|
+
let p = list.[i]
|
456
|
+
if p < last then i <- 0 else
|
457
|
+
let mutable len = 0
|
458
|
+
while len < mlen && buf.[p + len] = buf.[pos + len] do
|
459
|
+
len <- len + 1
|
460
|
+
if len > maxl then
|
461
|
+
maxp <- p
|
462
|
+
maxl <- len
|
463
|
+
i <- i - 1
|
464
|
+
else
|
465
|
+
let c = counts.[h]
|
466
|
+
let p1, p2 = if c < 16 then 0, c - 1 else c + 1, c + 16
|
467
|
+
let mutable i = p2
|
468
|
+
while i >= p1 do
|
469
|
+
let p = tables.[h, i &&& 15]
|
470
|
+
if p < last then i <- 0 else
|
471
|
+
let mutable len = 0
|
472
|
+
while len < mlen && buf.[p + len] = buf.[pos + len] do
|
473
|
+
len <- len + 1
|
474
|
+
if len > maxl then
|
475
|
+
maxp <- p
|
476
|
+
maxl <- len
|
477
|
+
i <- i - 1
|
478
|
+
maxp, maxl
|
479
|
+
|
480
|
+
member x.Crc = ~~~crc
|
481
|
+
|
482
|
+
member x.Compress (sout:Stream) =
|
483
|
+
use bw = new BitWriter(sout)
|
484
|
+
bw.WriteBit 1
|
485
|
+
bw.WriteLE 2 1
|
486
|
+
let hw = new FixedHuffmanWriter(bw)
|
487
|
+
let mutable p = 0
|
488
|
+
match t with
|
489
|
+
| 2 ->
|
490
|
+
while p < length do
|
491
|
+
let b = buf.[p]
|
492
|
+
if p < length - 4 && b = buf.[p + 1] && b = buf.[p + 2] && b = buf.[p + 3] then
|
493
|
+
let mutable len = 4
|
494
|
+
let mlen = Math.Min(maxlen + 1, length - p)
|
495
|
+
while len < mlen && b = buf.[p + len] do
|
496
|
+
len <- len + 1
|
497
|
+
hw.Write(int b)
|
498
|
+
hw.WriteLen(len - 1)
|
499
|
+
hw.WriteDist 1
|
500
|
+
p <- p + len
|
501
|
+
else
|
502
|
+
let maxp, maxl = search p
|
503
|
+
if maxp < 0 then
|
504
|
+
hw.Write(int b)
|
505
|
+
addHash2 tables counts buf p
|
506
|
+
p <- p + 1
|
507
|
+
else
|
508
|
+
hw.WriteLen maxl
|
509
|
+
hw.WriteDist (p - maxp)
|
510
|
+
for i = p to p + maxl - 1 do
|
511
|
+
addHash2 tables counts buf i
|
512
|
+
p <- p + maxl
|
513
|
+
if p > maxbuf2 then
|
514
|
+
Array.Copy(buf, maxbuf, buf, 0, maxbuf + maxlen)
|
515
|
+
if length < buflen then length <- length - maxbuf else
|
516
|
+
read (maxbuf + maxlen) maxbuf
|
517
|
+
p <- p - maxbuf
|
518
|
+
for i = 0 to p - 1 do
|
519
|
+
addHash2 tables counts buf i
|
520
|
+
| 1 ->
|
521
|
+
while p < length do
|
522
|
+
let b = buf.[p]
|
523
|
+
if p < length - 4 && b = buf.[p + 1] && b = buf.[p + 2] && b = buf.[p + 3] then
|
524
|
+
let mutable len = 4
|
525
|
+
let mlen = Math.Min(maxlen + 1, length - p)
|
526
|
+
while len < mlen && b = buf.[p + len] do
|
527
|
+
len <- len + 1
|
528
|
+
hw.Write(int b)
|
529
|
+
hw.WriteLen(len - 1)
|
530
|
+
hw.WriteDist 1
|
531
|
+
p <- p + len
|
532
|
+
else
|
533
|
+
let maxp, maxl = search p
|
534
|
+
if maxp < 0 then
|
535
|
+
hw.Write(int b)
|
536
|
+
addHash hash buf p
|
537
|
+
p <- p + 1
|
538
|
+
else
|
539
|
+
hw.WriteLen maxl
|
540
|
+
hw.WriteDist (p - maxp)
|
541
|
+
for i = p to p + maxl - 1 do
|
542
|
+
addHash hash buf i
|
543
|
+
p <- p + maxl
|
544
|
+
if p > maxbuf2 then
|
545
|
+
Array.Copy(buf, maxbuf, buf, 0, maxbuf + maxlen)
|
546
|
+
if length < buflen then length <- length - maxbuf else
|
547
|
+
read (maxbuf + maxlen) maxbuf
|
548
|
+
p <- p - maxbuf
|
549
|
+
for i = 0 to p - 1 do
|
550
|
+
addHash hash buf i
|
551
|
+
| _ ->
|
552
|
+
while p < length do
|
553
|
+
let maxp, maxl = search p
|
554
|
+
if maxp < 0 then
|
555
|
+
hw.Write(int buf.[p])
|
556
|
+
hash.[getHash buf p].Add p
|
557
|
+
p <- p + 1
|
558
|
+
else
|
559
|
+
hw.WriteLen maxl
|
560
|
+
hw.WriteDist (p - maxp)
|
561
|
+
for i = p to p + maxl - 1 do
|
562
|
+
hash.[getHash buf i].Add i
|
563
|
+
p <- p + maxl
|
564
|
+
if p > maxbuf2 then
|
565
|
+
Array.Copy(buf, maxbuf, buf, 0, maxbuf + maxlen)
|
566
|
+
if length < buflen then length <- length - maxbuf else
|
567
|
+
read (maxbuf + maxlen) maxbuf
|
568
|
+
p <- p - maxbuf
|
569
|
+
for i = 0 to p - 1 do
|
570
|
+
hash.[getHash buf i].Add i
|
571
|
+
hw.Write 256
|
572
|
+
|
573
|
+
let GetCompressBytes (sin:Stream) =
|
574
|
+
let now = DateTime.Now
|
575
|
+
let ms = new MemoryStream()
|
576
|
+
let w = new Writer(1, sin)
|
577
|
+
w.Compress ms
|
578
|
+
ms.ToArray(), w.Crc
|