|
| 1 | +require "./binary_parser/macros/*" |
| 2 | + |
1 | 3 | class BinaryParser |
2 | 4 | def load(filename : String) |
3 | 5 | io = File.open(filename) |
@@ -39,252 +41,7 @@ class BinaryParser |
39 | 41 | def to_io(io : IO, format : IO::ByteFormat) |
40 | 42 | write(io) |
41 | 43 | end |
42 | | - |
43 | | - macro uint32(name) |
44 | | - property! :{{name.id}} |
45 | | - @{{name.id}} = 0u32 |
46 | | - |
47 | | - def _read_{{name.id}}(io : IO) |
48 | | - @{{name.id}} = io.not_nil!.read_bytes(UInt32).as(UInt32) |
49 | | - end |
50 | | - |
51 | | - def _write_{{name.id}}(io : IO) |
52 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
53 | | - end |
54 | | - |
55 | | - def _size_static_{{name.id}} |
56 | | - sizeof(UInt32) |
57 | | - end |
58 | | - end |
59 | | - |
60 | | - macro uint16(name) |
61 | | - property! :{{name.id}} |
62 | | - @{{name.id}} = 0u16 |
63 | | - |
64 | | - def _read_{{name.id}}(io : IO) |
65 | | - @{{name.id}} = io.not_nil!.read_bytes(UInt16).as(UInt16) |
66 | | - end |
67 | | - |
68 | | - def _write_{{name.id}}(io : IO) |
69 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
70 | | - end |
71 | | - |
72 | | - def _size_static_{{name.id}} |
73 | | - sizeof(UInt16) |
74 | | - end |
75 | | - end |
76 | | - |
77 | | - macro uint8(name) |
78 | | - property! :{{name.id}} |
79 | | - @{{name.id}} = 0u8 |
80 | | - |
81 | | - def _read_{{name.id}}(io : IO) |
82 | | - @{{name.id}} = io.not_nil!.read_bytes(UInt8).as(UInt8) |
83 | | - end |
84 | | - |
85 | | - def _write_{{name.id}}(io : IO) |
86 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
87 | | - end |
88 | | - |
89 | | - def _size_static_{{name.id}} |
90 | | - sizeof(UInt8) |
91 | | - end |
92 | | - end |
93 | | - |
94 | | - macro int32(name) |
95 | | - property! :{{name.id}} |
96 | | - @{{name.id}} = 0i32 |
97 | | - |
98 | | - def _read_{{name.id}}(io : IO) |
99 | | - @{{name.id}} = io.not_nil!.read_bytes(Int32).as(Int32) |
100 | | - end |
101 | | - |
102 | | - def _write_{{name.id}}(io : IO) |
103 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
104 | | - end |
105 | | - |
106 | | - def _size_static_{{name.id}} |
107 | | - sizeof(Int32) |
108 | | - end |
109 | | - end |
110 | | - |
111 | | - macro int16(name) |
112 | | - property! :{{name.id}} |
113 | | - @{{name.id}} = 0i16 |
114 | | - |
115 | | - def _read_{{name.id}}(io : IO) |
116 | | - @{{name.id}} = io.not_nil!.read_bytes(Int16).as(Int16) |
117 | | - end |
118 | | - |
119 | | - def _write_{{name.id}}(io : IO) |
120 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
121 | | - end |
122 | | - |
123 | | - def _size_static_{{name.id}} |
124 | | - sizeof(Int16) |
125 | | - end |
126 | | - end |
127 | | - |
128 | | - macro int8(name) |
129 | | - property! :{{name.id}} |
130 | | - @{{name.id}} = 0i8 |
131 | | - |
132 | | - def _read_{{name.id}}(io : IO) |
133 | | - @{{name.id}} = io.not_nil!.read_bytes(Int8).as(Int8) |
134 | | - end |
135 | | - |
136 | | - def _write_{{name.id}}(io : IO) |
137 | | - io.not_nil!.write_bytes(@{{name.id}}.not_nil!) |
138 | | - end |
139 | | - |
140 | | - def _size_static_{{name.id}} |
141 | | - sizeof(Int8) |
142 | | - end |
143 | | - end |
144 | | - |
145 | | - macro char(name) |
146 | | - property! :{{name.id}} |
147 | | - @{{name.id}} = '\0' |
148 | | - |
149 | | - def _read_{{name.id}}(io : IO) |
150 | | - @{{name.id}} = io.not_nil!.read_char |
151 | | - end |
152 | | - |
153 | | - def _size_static_{{name.id}} |
154 | | - sizeof(Char) |
155 | | - end |
156 | | - end |
157 | | - |
158 | | - macro type(name, klass) |
159 | | - property! :{{name.id}} |
160 | | - @{{name.id}} = {{klass}}.new |
161 | | - |
162 | | - def _read_{{name.id}}(io : IO) |
163 | | - {% raise "Must inhert BinaryParser" if BinaryParser < klass.resolve %} |
164 | | - @{{name.id}} = io.read_bytes({{klass}}).as({{klass}}) |
165 | | - end |
166 | | - |
167 | | - def _write_{{name.id}}(io : IO) |
168 | | - io.write_bytes(@{{name.id}}.not_nil!) |
169 | | - end |
170 | | - |
171 | | - def _size_dyn_{{name.id}} |
172 | | - @{{name.id}}.bytesize |
173 | | - end |
174 | | - end |
175 | | - |
176 | | - macro array(name, opt) |
177 | | - {% raise "Must have count and type" unless opt[:type] && opt[:count] %} |
178 | | - property! :{{name.id}} |
179 | | - @{{name.id}} = [] of {{opt[:type]}} |
180 | | - |
181 | | - def _read_{{name.id}}(io : IO) |
182 | | - {% if opt[:count].is_a?(NumberLiteral) %} |
183 | | - @{{name.id}} = Array({{opt[:type]}}).new({{opt[:count]}}) do |
184 | | - io.read_bytes({{opt[:type]}}) |
185 | | - end |
186 | | - {% elsif opt[:count].id != "eof" %} |
187 | | - @{{name.id}} = Array({{opt[:type]}}).new(@{{opt[:count].id}}.not_nil!) do |
188 | | - io.read_bytes({{opt[:type]}}) |
189 | | - end |
190 | | - {% else %} |
191 | | - @{{name.id}} = [] of {{opt[:type]}} |
192 | | - # TODO: support :eof |
193 | | - {% end %} |
194 | | - end |
195 | | - |
196 | | - def _write_{{name.id}}(io : IO) |
197 | | - @{{name.id}}.not_nil!.each do |item| |
198 | | - io.write_bytes(item) |
199 | | - end |
200 | | - end |
201 | | - |
202 | | - def _size_dyn_{{name.id}} |
203 | | - {% if opt[:type].resolve < BinaryParser %} |
204 | | - res = @{{name.id}}.reduce(0) do |size, x| |
205 | | - size + x.bytesize |
206 | | - end |
207 | | - res |
208 | | - {% else %} |
209 | | - @{{name.id}}.size * sizeof({{opt[:type]}}) |
210 | | - {% end %} |
211 | | - end |
212 | | - end |
213 | | - |
214 | | - macro string(name, opt = { count: -1 }) |
215 | | - property! :{{name.id}} |
216 | | - @{{name.id}} = "" |
217 | | - |
218 | | - # TODO: Refactor |
219 | | - def _read_{{name.id}}(io : IO) |
220 | | - {% if opt[:count].is_a?(NumberLiteral) %} |
221 | | - {% if opt[:count] != -1 %} |
222 | | - buf = Slice(UInt8).new({{opt[:count]}}) |
223 | | - io.read(buf) |
224 | | - str = String.new(buf) |
225 | | - len = str.byte_index(0) || str.bytesize |
226 | | - @{{name.id}} = str.byte_slice(0, len) |
227 | | - {% else %} |
228 | | - @{{name.id}} = io.gets('\0') |
229 | | - {% end %} |
230 | | - {% else %} |
231 | | - buf = Slice(UInt8).new(@{{opt[:count].id}}.not_nil!) |
232 | | - io.read(buf) |
233 | | - str = String.new(buf) |
234 | | - len = str.byte_index(0) || str.bytesize |
235 | | - @{{name.id}} = str.byte_slice(0, len) |
236 | | - {% end %} |
237 | | - end |
238 | | - |
239 | | - def _write_{{name.id}}(io : IO) |
240 | | - {% if opt[:count].is_a?(NumberLiteral) %} |
241 | | - {% if opt[:count] != -1 %} |
242 | | - slice = Slice(UInt8).new({{opt[:count]}}) |
243 | | - slice.copy_from(@{{name.id}}.not_nil!.to_slice) |
244 | | - io.write(slice) |
245 | | - {% else %} |
246 | | - # FIXME |
247 | | - io.write(@{{name.id}}.not_nil!.to_slice) |
248 | | - {% end %} |
249 | | - {% else %} |
250 | | - io.write(@{{name.id}}.not_nil!.to_slice) |
251 | | - {% end %} |
252 | | - end |
253 | | - |
254 | | - def _size_dyn_{{name.id}} |
255 | | - {% if opt[:count].is_a?(NumberLiteral) && opt[:count] != -1 %} |
256 | | - {{opt[:count]}} |
257 | | - {% else %} |
258 | | - @{{name.id}}.size |
259 | | - {% end %} |
260 | | - end |
261 | | - end |
262 | | - |
263 | | - module ByteSize |
264 | | - macro included |
265 | | - @static_size : Int32? |
266 | | - |
267 | | - def bytesize |
268 | | - dyn_size = 0 |
269 | | - {% for func in @type.methods %} |
270 | | - {% if func.name.starts_with? "_size_dyn" %} |
271 | | - dyn_size += {{func.name}} |
272 | | - {% end %} |
273 | | - {% end %} |
274 | | - static_size + dyn_size |
275 | | - end |
276 | | - |
277 | | - private def static_size |
278 | | - return @static_size.not_nil! if @static_size |
279 | | - size = 0 |
280 | | - {% for func in @type.methods %} |
281 | | - {% if func.name.starts_with? "_size_static" %} |
282 | | - size += {{func.name}} |
283 | | - {% end %} |
284 | | - {% end %} |
285 | | - @static_size = size |
286 | | - end |
287 | | - end |
288 | | - end |
289 | 44 | end |
290 | 45 |
|
| 46 | +require "./binary_parser/byte_size" |
| 47 | + |
0 commit comments