@@ -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
197289end
0 commit comments