forked from shokai/node-asearch
-
Notifications
You must be signed in to change notification settings - Fork 1
/
asearch.coffee
71 lines (58 loc) · 1.62 KB
/
asearch.coffee
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
class Asearch
INITPAT = 0x80000000
MAXCHAR = 0x10000
INITSTATE = [INITPAT, 0, 0, 0]
isupper: (c) ->
return (c >= 0x41) and (c <= 0x5a)
islower: (c) ->
return (c >= 0x61) and (c <= 0x7a)
tolower: (c) ->
return if (@isupper c) then (c + 0x20) else c
toupper: (c) ->
return if (@islower c) then (c - 0x20) else c
constructor: (@source) ->
@shiftpat = []
@epsilon = 0
@acceptpat = 0
mask = INITPAT
for c in [0...MAXCHAR]
@shiftpat[c] = 0
for c in @unpack(@source)
if c is 0x20
@epsilon |= mask
else
@shiftpat[c] |= mask
@shiftpat[@toupper c] |= mask
@shiftpat[@tolower c] |= mask
mask >>>= 1
@acceptpat = mask
return @
state: (state=INITSTATE, str = '') ->
i0 = state[0]
i1 = state[1]
i2 = state[2]
i3 = state[3]
for c in @unpack(str)
mask = @shiftpat[c]
i3 = (i3 & @epsilon) | ((i3 & mask) >>> 1) | (i2 >>> 1) | i2
i2 = (i2 & @epsilon) | ((i2 & mask) >>> 1) | (i1 >>> 1) | i1
i1 = (i1 & @epsilon) | ((i1 & mask) >>> 1) | (i0 >>> 1) | i0
i0 = (i0 & @epsilon) | ((i0 & mask) >>> 1)
i1 |= (i0 >>> 1)
i2 |= (i1 >>> 1)
i3 |= (i2 >>> 1)
return [i0, i1, i2, i3]
match: (str, ambig = 0) ->
s = @state INITSTATE, str
ambig = INITSTATE.length-1 unless ambig < INITSTATE.length
return (s[ambig] & @acceptpat) != 0
unpack: (str) ->
bytes = []
for c in str.split('')
code = c.charCodeAt(0)
bytes.push(code)
return bytes
if module? and module.exports?
module.exports = Asearch
else if window?
window.Asearch = Asearch