This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdff-parser2.coffee
98 lines (81 loc) · 2.02 KB
/
dff-parser2.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
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
Dissolve = require "dissolve"
fs = require "fs"
sectionTypes =
0x0000: "rwID_NAOBJECT"
0x0001: "rwID_STRUCT"
0x0002: "rwID_STRING"
0x0003: "rwID_EXTENSION"
0x0010: "rwID_CLUMP"
0x0202: "eof"
dataSections = ["rwID_STRUCT", "rwID_STRING"]
loaderCount = 0
# Utility base class
class BaseStreamParser extends Dissolve
constructor: ->
Dissolve.call @
unparse: (names...) ->
@tap -> delete @vars[name] for name in names
return @
counted: (name, countVar, cb) ->
currentCount = 0
@uint32le countVar
.loop name, (end) ->
return end true if currentCount++ is @vars[countVar]
cb.call @
exactlyCounted: (name, count, cb) ->
currentCount = 0
@loop name, (end) ->
return end true if currentCount++ is count
cb.call @
flatten: (item, prop) ->
@tap ->
for i in [0...@vars[item].length]
@vars[item][i] = @vars[item][i][prop]
class StreamParser extends BaseStreamParser
constructor: ->
BaseStreamParser.call @
@sectionList().tap ->
# Pop eof chunk
@vars.entries.pop()
@push @vars
section: ->
@header()
.tap ->
switch @vars.type
when "eof"
@stopParsing = true
return
when "rwID_STRING"
@buffer "data", @vars.size
.unparse "data"
when "rwID_STRUCT"
@buffer "data", @vars.size
.unparse "data"
else
@buffer "data", @vars.size
.tap ->
vars = @vars
parser = new StreamParser()
parser.on "data", (chunkList) ->
vars.children = chunkList.entries
loaderCount--
parser.write @vars.data
delete @vars.data
loaderCount++
header: ->
@uint32le "type"
.uint32le "size"
.uint32le "version"
.tap ->
@vars.type = sectionTypes[@vars.type] or "rwID_ERROR@#{@vars.type}"
sectionList: ->
@loop "entries", (end) ->
return end true if @stopParsing
@section()
exports.StreamParser = StreamParser
# Handle utility call directly from console
if require.main is module
parser = new StreamParser()
parser.on "data", (model) ->
console.log JSON.stringify model, null, 4
process.stdin.pipe parser