Skip to content

Commit 1e5155d

Browse files
committed
feat: ByteSize module
1 parent d165583 commit 1e5155d

File tree

1 file changed

+101
-9
lines changed

1 file changed

+101
-9
lines changed

src/binary_parser.cr

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ class BinaryParser
5151
def _write_{{name.id}}(io : IO)
5252
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
5353
end
54+
55+
def _size_static_{{name.id}}
56+
sizeof(UInt32)
57+
end
5458
end
5559

5660
macro uint16(name)
@@ -64,6 +68,10 @@ class BinaryParser
6468
def _write_{{name.id}}(io : IO)
6569
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
6670
end
71+
72+
def _size_static_{{name.id}}
73+
sizeof(UInt16)
74+
end
6775
end
6876

6977
macro uint8(name)
@@ -77,6 +85,10 @@ class BinaryParser
7785
def _write_{{name.id}}(io : IO)
7886
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
7987
end
88+
89+
def _size_static_{{name.id}}
90+
sizeof(UInt8)
91+
end
8092
end
8193

8294
macro int32(name)
@@ -90,6 +102,10 @@ class BinaryParser
90102
def _write_{{name.id}}(io : IO)
91103
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
92104
end
105+
106+
def _size_static_{{name.id}}
107+
sizeof(Int32)
108+
end
93109
end
94110

95111
macro int16(name)
@@ -103,6 +119,10 @@ class BinaryParser
103119
def _write_{{name.id}}(io : IO)
104120
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
105121
end
122+
123+
def _size_static_{{name.id}}
124+
sizeof(Int16)
125+
end
106126
end
107127

108128
macro int8(name)
@@ -116,6 +136,10 @@ class BinaryParser
116136
def _write_{{name.id}}(io : IO)
117137
io.not_nil!.write_bytes(@{{name.id}}.not_nil!)
118138
end
139+
140+
def _size_static_{{name.id}}
141+
sizeof(Int8)
142+
end
119143
end
120144

121145
macro char(name)
@@ -125,20 +149,28 @@ class BinaryParser
125149
def _read_{{name.id}}(io : IO)
126150
@{{name.id}} = io.not_nil!.read_char
127151
end
152+
153+
def _size_static_{{name.id}}
154+
sizeof(Char)
155+
end
128156
end
129157

130158
macro type(name, klass)
131159
property! :{{name.id}}
132160
@{{name.id}} = {{klass}}.new
133161

134162
def _read_{{name.id}}(io : IO)
135-
{% raise "Must inhert BinaryParser" if @type >= klass.resolve %}
163+
{% raise "Must inhert BinaryParser" if BinaryParser < klass.resolve %}
136164
@{{name.id}} = io.read_bytes({{klass}}).as({{klass}})
137165
end
138166

139167
def _write_{{name.id}}(io : IO)
140168
io.write_bytes(@{{name.id}}.not_nil!)
141169
end
170+
171+
def _size_dyn_{{name.id}}
172+
@{{name.id}}.bytesize
173+
end
142174
end
143175

144176
macro array(name, opt)
@@ -166,32 +198,92 @@ class BinaryParser
166198
io.write_bytes(item)
167199
end
168200
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
169212
end
170213

171214
macro string(name, opt = { count: -1 })
172215
property! :{{name.id}}
173216
@{{name.id}} = ""
174217

218+
# TODO: Refactor
175219
def _read_{{name.id}}(io : IO)
176-
{% if opt[:count] != -1 %}
177-
buf = Slice(UInt8).new({{opt[:count]}})
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!)
178232
io.read(buf)
179233
str = String.new(buf)
180234
len = str.byte_index(0) || str.bytesize
181235
@{{name.id}} = str.byte_slice(0, len)
182-
{% else %}
183-
@{{name.id}} = io.gets('\0')
184236
{% end %}
185237
end
186238

187239
def _write_{{name.id}}(io : IO)
188-
{% if opt[:count] != -1 %}
189-
slice = Slice(UInt8).new({{opt[:count]}})
190-
slice.copy_from(@{{name.id}}.not_nil!.to_slice)
191-
io.write(slice)
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 %}
192249
{% else %}
193250
io.write(@{{name.id}}.not_nil!.to_slice)
194251
{% end %}
195252
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+
end
263+
264+
module ByteSize
265+
macro included
266+
@static_size : Int32?
267+
268+
def bytesize
269+
dyn_size = 0
270+
{% for func in @type.methods %}
271+
{% if func.name.starts_with? "_size_dyn" %}
272+
dyn_size += {{func.name}}
273+
{% end %}
274+
{% end %}
275+
static_size + dyn_size
276+
end
277+
278+
private def static_size
279+
return @static_size.not_nil! if @static_size
280+
size = 0
281+
{% for func in @type.methods %}
282+
{% if func.name.starts_with? "_size_static" %}
283+
size += {{func.name}}
284+
{% end %}
285+
{% end %}
286+
@static_size = size
287+
end
196288
end
197289
end

0 commit comments

Comments
 (0)