8
8
9
9
# # This module implements Python struct for Nim
10
10
11
- import strutils
12
- import endians
13
- import macros
11
+ import strutils, endians, macros
14
12
15
13
type
16
14
SomeByte * = byte | char | int8 | uint8
17
-
18
15
StructError * = object of OSError
19
16
20
- StructKind * = enum # # possible JSON node types
17
+ StructKind * = enum
21
18
StructChar ,
22
19
StructBool ,
23
20
StructInt ,
48
45
repeat: int
49
46
index: int
50
47
51
-
52
48
const
53
- VERSION * = " 0.1.1 "
49
+ STRUCT_VERSION * = " 0.2.2 "
54
50
55
51
proc getSize (t: char ): int {.noSideEffect , inline .} =
56
52
case t
@@ -64,8 +60,7 @@ proc newStructChar*(c: char): StructNode = StructNode(kind: StructChar, ch: c)
64
60
65
61
proc newStructBool * (b: bool ): StructNode = StructNode (kind: StructBool , bval: b)
66
62
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 )
69
64
70
65
proc newStructFloat * (d: BiggestFloat ): StructNode = StructNode (kind: StructFloat , fval: d)
71
66
@@ -150,15 +145,15 @@ proc parse_prefix(ctx: var StructContext, f: char) =
150
145
151
146
proc load_16 * [T: SomeByte ](a, b: T, endian: Endianness ): int16 {.inline .} =
152
147
if endian == littleEndian:
153
- a.int16 + b.int16 shl 8
148
+ a.int16 or b.int16 shl 8
154
149
else :
155
- b.int16 + a.int16 shl 8
150
+ b.int16 or a.int16 shl 8
156
151
157
152
proc load_32 * [T: SomeByte ](a, b, c, d: T, endian: Endianness ): int32 {.inline .} =
158
153
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
160
155
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
162
157
163
158
proc load_32f * [T: SomeByte ](a, b, c, d: T, endian: Endianness ): float32 {.inline .} =
164
159
var o = cast [cstring ](addr result )
@@ -211,42 +206,52 @@ proc extract_64*[T:float64|int64|uint64](v: T, endian: Endianness): array[0..7,
211
206
bigEndian64 (addr result , addr v)
212
207
213
208
proc unpack_char (vars: var seq [StructNode ], ctx: var StructContext ) =
214
- for i in 0 .. ctx.repeat- 1 :
209
+ for i in 0 ..< ctx.repeat:
215
210
vars.add (newStructChar (ctx.buffer[ctx.offset]))
216
211
inc (ctx.offset)
217
212
218
213
proc unpack_bool (vars: var seq [StructNode ], ctx: var StructContext ) =
219
- for i in 0 .. ctx.repeat- 1 :
214
+ for i in 0 ..< ctx.repeat:
220
215
vars.add (newStructBool (ctx.buffer[ctx.offset].bool ))
221
216
inc (ctx.offset)
222
217
223
218
proc 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)
226
223
vars.add (newStructInt (value))
227
224
inc (ctx.offset, ctx.repeat * getSize (f))
228
225
229
226
proc 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)
232
231
vars.add (newStructInt (value))
233
232
inc (ctx.offset, ctx.repeat * getSize (f))
234
233
235
234
proc 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)
238
239
vars.add (newStructInt (value))
239
240
inc (ctx.offset, ctx.repeat * getSize (f))
240
241
241
242
proc 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)
244
247
vars.add (newStructFloat (value.float32 ))
245
248
inc (ctx.offset, ctx.repeat * getSize ('f' ))
246
249
247
250
proc 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)
250
255
vars.add (newStructFloat (value))
251
256
inc (ctx.offset, ctx.repeat * getSize ('d' ))
252
257
@@ -273,7 +278,6 @@ proc unpack*(fmt, buf: string): seq[StructNode] =
273
278
var repeat = newString (0 )
274
279
for i in 0 .. fmt.len- 1 :
275
280
let f: char = fmt[i]
276
-
277
281
if f in '0' .. '9' :
278
282
repeat.add ($ f)
279
283
continue
@@ -315,14 +319,14 @@ proc unpack*(fmt, buf: string): seq[StructNode] =
315
319
raise newException (ValueError , " bad char in struct format" )
316
320
317
321
proc 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:
319
323
assert vars[ctx.offset].kind == StructChar
320
324
result [ctx.index + i] = vars[ctx.offset].ch
321
325
inc (ctx.offset)
322
326
inc (ctx.index, ctx.repeat)
323
327
324
328
proc 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:
326
330
assert vars[ctx.offset].kind == StructBool
327
331
if vars[ctx.offset].bval == true :
328
332
result [ctx.index] = '\x01 '
@@ -333,7 +337,7 @@ proc pack_bool(result: var string, vars: openarray[StructNode], ctx: var StructC
333
337
inc (ctx.index, ctx.repeat)
334
338
335
339
proc 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:
337
341
let value =
338
342
if signed:
339
343
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
347
351
inc (ctx.index, 2 * ctx.repeat)
348
352
349
353
proc 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:
351
355
var value: array [0 .. 3 , char ]
352
356
case vars[ctx.offset].kind:
353
357
of StructFloat :
@@ -367,8 +371,7 @@ proc pack_32(result: var string, vars: openarray[StructNode], ctx: var StructCon
367
371
inc (ctx.index, 4 * ctx.repeat)
368
372
369
373
proc 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:
372
375
var value: array [0 .. 7 , char ]
373
376
case vars[ctx.offset].kind:
374
377
of StructFloat :
@@ -398,13 +401,11 @@ proc pack_string(result: var string, vars: openarray[StructNode], ctx: var Struc
398
401
result [ctx.index + i] = '\x00 '
399
402
400
403
inc (ctx.offset)
401
-
402
404
inc (ctx.index, ctx.repeat)
403
405
404
406
proc pack_pad (result: var string , ctx: var StructContext ) =
405
- for i in 0 .. ctx.repeat- 1 :
407
+ for i in 0 ..< ctx.repeat:
406
408
result [ctx.index + i] = '\x00 '
407
-
408
409
inc (ctx.index, ctx.repeat)
409
410
410
411
proc pack * (fmt: string , vars: varargs [StructNode ]): string =
0 commit comments