Skip to content

Commit 4d46c2b

Browse files
committed
refactor: Modulize
1 parent a941a7f commit 4d46c2b

File tree

12 files changed

+262
-247
lines changed

12 files changed

+262
-247
lines changed

src/binary_parser.cr

Lines changed: 4 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require "./binary_parser/macros/*"
2+
13
class BinaryParser
24
def load(filename : String)
35
io = File.open(filename)
@@ -39,252 +41,7 @@ class BinaryParser
3941
def to_io(io : IO, format : IO::ByteFormat)
4042
write(io)
4143
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
28944
end
29045

46+
require "./binary_parser/byte_size"
47+

src/binary_parser/byte_size.cr

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class BinaryParser
2+
module ByteSize
3+
macro included
4+
@static_size : Int32?
5+
6+
def bytesize
7+
dyn_size = 0
8+
{% for func in @type.methods %}
9+
{% if func.name.starts_with? "_size_dyn" %}
10+
dyn_size += {{func.name}}
11+
{% end %}
12+
{% end %}
13+
static_size + dyn_size
14+
end
15+
16+
private def static_size
17+
return @static_size.not_nil! if @static_size
18+
size = 0
19+
{% for func in @type.methods %}
20+
{% if func.name.starts_with? "_size_static" %}
21+
size += {{func.name}}
22+
{% end %}
23+
{% end %}
24+
@static_size = size
25+
end
26+
end
27+
end
28+
end

src/binary_parser/macros/array.cr

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class BinaryParser
2+
macro array(name, opt)
3+
{% raise "Must have count and type" unless opt[:type] && opt[:count] %}
4+
property! :{{name.id}}
5+
@{{name.id}} = [] of {{opt[:type]}}
6+
7+
def _read_{{name.id}}(io : IO)
8+
{% if opt[:count].is_a?(NumberLiteral) %}
9+
@{{name.id}} = Array({{opt[:type]}}).new({{opt[:count]}}) do
10+
io.read_bytes({{opt[:type]}})
11+
end
12+
{% elsif opt[:count].id != "eof" %}
13+
@{{name.id}} = Array({{opt[:type]}}).new(@{{opt[:count].id}}.not_nil!) do
14+
io.read_bytes({{opt[:type]}})
15+
end
16+
{% else %}
17+
@{{name.id}} = [] of {{opt[:type]}}
18+
# TODO: support :eof
19+
{% end %}
20+
end
21+
22+
def _write_{{name.id}}(io : IO)
23+
@{{name.id}}.not_nil!.each do |item|
24+
io.write_bytes(item)
25+
end
26+
end
27+
28+
def _size_dyn_{{name.id}}
29+
{% if opt[:type].resolve < BinaryParser %}
30+
res = @{{name.id}}.reduce(0) do |size, x|
31+
size + x.bytesize
32+
end
33+
res
34+
{% else %}
35+
@{{name.id}}.size * sizeof({{opt[:type]}})
36+
{% end %}
37+
end
38+
end
39+
end

src/binary_parser/macros/char.cr

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class BinaryParser
2+
macro char(name)
3+
property! :{{name.id}}
4+
@{{name.id}} = '\0'
5+
6+
def _read_{{name.id}}(io : IO)
7+
@{{name.id}} = io.not_nil!.read_char
8+
end
9+
10+
def _size_static_{{name.id}}
11+
sizeof(Char)
12+
end
13+
end
14+
end

src/binary_parser/macros/int16.cr

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class BinaryParser
2+
macro int16(name)
3+
property! :{{name.id}}
4+
@{{name.id}} = 0i16
5+
6+
def _read_{{name.id}}(io : IO)
7+
@{{name.id}} = io.not_nil!.read_bytes(Int16).as(Int16)
8+
end
9+
10+
def _write_{{name.id}}(io : IO)
11+
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
12+
end
13+
14+
def _size_static_{{name.id}}
15+
sizeof(Int16)
16+
end
17+
end
18+
end

src/binary_parser/macros/int32.cr

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class BinaryParser
2+
macro int32(name)
3+
property! :{{name.id}}
4+
@{{name.id}} = 0i32
5+
6+
def _read_{{name.id}}(io : IO)
7+
@{{name.id}} = io.not_nil!.read_bytes(Int32).as(Int32)
8+
end
9+
10+
def _write_{{name.id}}(io : IO)
11+
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
12+
end
13+
14+
def _size_static_{{name.id}}
15+
sizeof(Int32)
16+
end
17+
end
18+
end

0 commit comments

Comments
 (0)