-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathstruct.lua
117 lines (85 loc) · 1.92 KB
/
struct.lua
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
-- Copyright 2014 David Mentler
function skip( count )
return function( stream )
stream:Skip( count )
end
end
function array( decoder, count )
return function( stream )
local array = {}
for index = 1, count do
array[index] = decoder( stream )
end
return array
end
end
function str( size )
return function( stream )
local raw = stream:Read( size )
if ( !raw ) then
error( "EOF" )
end
for index = 1, size do
if ( raw:byte( index ) == 0 ) then
return raw:sub( 1, index -1 )
end
end
error( "Missing null terminator" )
end
end
function struct( ... )
local struct = {}
local args = { ... }
for index = 1, #args, 2 do
local entry = {}
entry.decoder = args[index +0]
entry.member = args[index +1]
table.insert( struct, entry )
end
return function( stream )
local base = stream:Tell()
local obj = {}
for _, entry in pairs ( struct ) do
local value = entry.decoder( stream, obj, base )
if ( entry.member ) then
obj[ entry.member ] = value
end
end
return obj
end
end
function lump( id, content )
return function( stream, header )
local data = {}
local index = 1
local lump = header.lumps[id +1]
local limit = lump.off + lump.len
stream:Seek( lump.off )
while ( stream:Tell() < limit ) do
data[index] = content( stream )
index = index +1
end
return data
end
end
local _R = debug.getregistry()
t_int = _R.File.ReadLong
t_byte = _R.File.ReadByte
t_char = _R.File.ReadByte
t_short = _R.File.ReadShort
t_float = _R.File.ReadFloat
t_double = _R.File.ReadDouble
t_vector = function( stream )
return Vector( stream:ReadFloat(), stream:ReadFloat(), stream:ReadFloat() )
end
t_string = function( stream )
local raw = ""
for i = 0, 256 do
local chr = stream:ReadByte()
if ( chr == 0 ) then
return raw
end
raw = raw .. string.char( chr )
end
error( "Null terminated string over 256 long" )
end