88
99# # This module implements Python struct for Nim
1010
11- import strutils
12- import endians
13- import macros
11+ import strutils, endians, macros
1412
1513type
1614 SomeByte * = byte | char | int8 | uint8
17-
1815 StructError * = object of OSError
1916
20- StructKind * = enum # # possible JSON node types
17+ StructKind * = enum
2118 StructChar ,
2219 StructBool ,
2320 StructInt ,
4845 repeat: int
4946 index: int
5047
51-
5248const
53- VERSION * = " 0.1.1 "
49+ STRUCT_VERSION * = " 0.2.2 "
5450
5551proc getSize (t: char ): int {.noSideEffect , inline .} =
5652 case t
@@ -64,8 +60,7 @@ proc newStructChar*(c: char): StructNode = StructNode(kind: StructChar, ch: c)
6460
6561proc newStructBool * (b: bool ): StructNode = StructNode (kind: StructBool , bval: b)
6662
67- proc newStructInt * [T: SomeInteger ](i: T): StructNode =
68- result = StructNode (kind: StructInt , num: i.BiggestInt )
63+ proc newStructInt * [T: SomeInteger ](i: T): StructNode = StructNode (kind: StructInt , num: i.BiggestInt )
6964
7065proc newStructFloat * (d: BiggestFloat ): StructNode = StructNode (kind: StructFloat , fval: d)
7166
@@ -150,15 +145,15 @@ proc parse_prefix(ctx: var StructContext, f: char) =
150145
151146proc load_16 * [T: SomeByte ](a, b: T, endian: Endianness ): int16 {.inline .} =
152147 if endian == littleEndian:
153- a.int16 + b.int16 shl 8
148+ a.int16 or b.int16 shl 8
154149 else :
155- b.int16 + a.int16 shl 8
150+ b.int16 or a.int16 shl 8
156151
157152proc load_32 * [T: SomeByte ](a, b, c, d: T, endian: Endianness ): int32 {.inline .} =
158153 if endian == littleEndian:
159- a.int32 + b.int32 shl 8 + c.int32 shl 16 + d.int32 shl 24
154+ a.int32 or b.int32 shl 8 or c.int32 shl 16 or d.int32 shl 24
160155 else :
161- d.int32 + c.int32 shl 8 + b.int32 shl 16 + a.int32 shl 24
156+ d.int32 or c.int32 shl 8 or b.int32 shl 16 or a.int32 shl 24
162157
163158proc load_32f * [T: SomeByte ](a, b, c, d: T, endian: Endianness ): float32 {.inline .} =
164159 var o = cast [cstring ](addr result )
@@ -211,42 +206,52 @@ proc extract_64*[T:float64|int64|uint64](v: T, endian: Endianness): array[0..7,
211206 bigEndian64 (addr result , addr v)
212207
213208proc unpack_char (vars: var seq [StructNode ], ctx: var StructContext ) =
214- for i in 0 .. ctx.repeat- 1 :
209+ for i in 0 ..< ctx.repeat:
215210 vars.add (newStructChar (ctx.buffer[ctx.offset]))
216211 inc (ctx.offset)
217212
218213proc unpack_bool (vars: var seq [StructNode ], ctx: var StructContext ) =
219- for i in 0 .. ctx.repeat- 1 :
214+ for i in 0 ..< ctx.repeat:
220215 vars.add (newStructBool (ctx.buffer[ctx.offset].bool ))
221216 inc (ctx.offset)
222217
223218proc unpack_short (vars: var seq [StructNode ], ctx: var StructContext , f: char , signed: bool = false ) =
224- for i in 0 .. ctx.repeat- 1 :
225- var value = load_16 (ctx.buffer[ctx.offset], ctx.buffer[ctx.offset+ 1 ], ctx.byteOrder)
219+ for i in 0 ..< ctx.repeat:
220+ let
221+ offset = ctx.offset + i * 2
222+ value = load_16 (ctx.buffer[offset], ctx.buffer[offset+ 1 ], ctx.byteOrder)
226223 vars.add (newStructInt (value))
227224 inc (ctx.offset, ctx.repeat * getSize (f))
228225
229226proc unpack_int (vars: var seq [StructNode ], ctx: var StructContext , f: char , signed: bool = false ) =
230- for i in 0 .. ctx.repeat- 1 :
231- var value = load_32 (ctx.buffer[ctx.offset], ctx.buffer[ctx.offset+ 1 ], ctx.buffer[ctx.offset+ 2 ], ctx.buffer[ctx.offset+ 3 ], ctx.byteOrder)
227+ for i in 0 ..< ctx.repeat:
228+ let
229+ offset = ctx.offset + i * 4
230+ value = load_32 (ctx.buffer[offset], ctx.buffer[offset+ 1 ], ctx.buffer[offset+ 2 ], ctx.buffer[offset+ 3 ], ctx.byteOrder)
232231 vars.add (newStructInt (value))
233232 inc (ctx.offset, ctx.repeat * getSize (f))
234233
235234proc unpack_quad (vars: var seq [StructNode ], ctx: var StructContext , f: char , signed: bool = false ) =
236- for i in 0 .. ctx.repeat- 1 :
237- var value = load_64 (ctx.buffer[ctx.offset.. ctx.offset+ 7 ], ctx.byteOrder)
235+ for i in 0 ..< ctx.repeat:
236+ let
237+ offset = ctx.offset + i * 8
238+ value = load_64 (ctx.buffer[offset.. offset+ 7 ], ctx.byteOrder)
238239 vars.add (newStructInt (value))
239240 inc (ctx.offset, ctx.repeat * getSize (f))
240241
241242proc unpack_float (vars: var seq [StructNode ], ctx: var StructContext ) =
242- for i in 0 .. ctx.repeat- 1 :
243- var value = load_32f (ctx.buffer[ctx.offset], ctx.buffer[ctx.offset+ 1 ], ctx.buffer[ctx.offset+ 2 ], ctx.buffer[ctx.offset+ 3 ], ctx.byteOrder)
243+ for i in 0 ..< ctx.repeat:
244+ let
245+ offset = ctx.offset + i * 4
246+ value = load_32f (ctx.buffer[offset], ctx.buffer[offset+ 1 ], ctx.buffer[offset+ 2 ], ctx.buffer[offset+ 3 ], ctx.byteOrder)
244247 vars.add (newStructFloat (value.float32 ))
245248 inc (ctx.offset, ctx.repeat * getSize ('f' ))
246249
247250proc unpack_double (vars: var seq [StructNode ], ctx: var StructContext ) =
248- for i in 0 .. ctx.repeat- 1 :
249- var value = load_64f (ctx.buffer[ctx.offset.. ctx.offset+ 7 ], ctx.byteOrder)
251+ for i in 0 ..< ctx.repeat:
252+ let
253+ offset = ctx.offset + i * 8
254+ value = load_64f (ctx.buffer[offset.. offset+ 7 ], ctx.byteOrder)
250255 vars.add (newStructFloat (value))
251256 inc (ctx.offset, ctx.repeat * getSize ('d' ))
252257
@@ -273,7 +278,6 @@ proc unpack*(fmt, buf: string): seq[StructNode] =
273278 var repeat = newString (0 )
274279 for i in 0 .. fmt.len- 1 :
275280 let f: char = fmt[i]
276-
277281 if f in '0' .. '9' :
278282 repeat.add ($ f)
279283 continue
@@ -315,14 +319,14 @@ proc unpack*(fmt, buf: string): seq[StructNode] =
315319 raise newException (ValueError , " bad char in struct format" )
316320
317321proc pack_char (result: var string , vars: openarray [StructNode ], ctx: var StructContext ) =
318- for i in 0 .. ctx.repeat- 1 :
322+ for i in 0 ..< ctx.repeat:
319323 assert vars[ctx.offset].kind == StructChar
320324 result [ctx.index + i] = vars[ctx.offset].ch
321325 inc (ctx.offset)
322326 inc (ctx.index, ctx.repeat)
323327
324328proc pack_bool (result: var string , vars: openarray [StructNode ], ctx: var StructContext ) =
325- for i in 0 .. ctx.repeat- 1 :
329+ for i in 0 ..< ctx.repeat:
326330 assert vars[ctx.offset].kind == StructBool
327331 if vars[ctx.offset].bval == true :
328332 result [ctx.index] = '\x01 '
@@ -333,7 +337,7 @@ proc pack_bool(result: var string, vars: openarray[StructNode], ctx: var StructC
333337 inc (ctx.index, ctx.repeat)
334338
335339proc pack_16 (result: var string , vars: openarray [StructNode ], ctx: var StructContext , signed: bool ) =
336- for i in 0 .. ctx.repeat- 1 :
340+ for i in 0 ..< ctx.repeat:
337341 let value =
338342 if signed:
339343 extract_16 (vars[ctx.offset].num.int16 , ctx.byteOrder)
@@ -347,7 +351,7 @@ proc pack_16(result: var string, vars: openarray[StructNode], ctx: var StructCon
347351 inc (ctx.index, 2 * ctx.repeat)
348352
349353proc pack_32 (result: var string , vars: openarray [StructNode ], ctx: var StructContext , signed: bool ) =
350- for i in 0 .. ctx.repeat- 1 :
354+ for i in 0 ..< ctx.repeat:
351355 var value: array [0 .. 3 , char ]
352356 case vars[ctx.offset].kind:
353357 of StructFloat :
@@ -367,8 +371,7 @@ proc pack_32(result: var string, vars: openarray[StructNode], ctx: var StructCon
367371 inc (ctx.index, 4 * ctx.repeat)
368372
369373proc pack_64 (result: var string , vars: openarray [StructNode ], ctx: var StructContext , signed: bool ) =
370-
371- for i in 0 .. ctx.repeat- 1 :
374+ for i in 0 ..< ctx.repeat:
372375 var value: array [0 .. 7 , char ]
373376 case vars[ctx.offset].kind:
374377 of StructFloat :
@@ -398,13 +401,11 @@ proc pack_string(result: var string, vars: openarray[StructNode], ctx: var Struc
398401 result [ctx.index + i] = '\x00 '
399402
400403 inc (ctx.offset)
401-
402404 inc (ctx.index, ctx.repeat)
403405
404406proc pack_pad (result: var string , ctx: var StructContext ) =
405- for i in 0 .. ctx.repeat- 1 :
407+ for i in 0 ..< ctx.repeat:
406408 result [ctx.index + i] = '\x00 '
407-
408409 inc (ctx.index, ctx.repeat)
409410
410411proc pack * (fmt: string , vars: varargs [StructNode ]): string =
0 commit comments