Skip to content

Commit 0191622

Browse files
committed
Update README
1 parent 8f6a80e commit 0191622

File tree

4 files changed

+91
-32
lines changed

4 files changed

+91
-32
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
nimcache/
22
struct
3-
test*
3+
test

README.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,62 @@
11
# struct.nim
2-
Python-like 'struct' for Nim
2+
** Python-like '[struct](http://docs.python.org/2/library/struct.html)' for Nim**
33

4-
## NOT READY YET
4+
Format String
5+
======
6+
7+
Byte Order
8+
------
9+
<table>
10+
<tr><td>Character</td><td>Byte order</td></tr>
11+
<tr><td>@</td><td>native</td></tr>
12+
<tr><td>=</td><td>native</td></tr>
13+
<tr><td><</td><td>little-endian</td></tr>
14+
<tr><td>></td><td>big-endian</td></tr>
15+
<tr><td>!</td><td>network (= big-endian)</td></tr>
16+
</table>
17+
18+
**Notes:**
19+
- Unlike Python -byte-order can specified once as first character, with this implementation, you can change byte-order anywhere and anytime you want
20+
21+
Format Characters:
22+
------
23+
<table>
24+
<tr><td>Format</td><td>C Type</td><td>Python Type</td><td>Nim Type</td><td>Size (bytes)</td></tr>
25+
<tr><td>x</td><td>pad byte</td><td>no value</td><td></td><td></td></tr>
26+
<tr><td>b</td><td>char</td><td>string of length 1</td><td>char</td><td>1</td></tr>
27+
<tr><td>?</td><td>_Bool</td><td>bool</td><td>bool</td><td>1</td></tr>
28+
<tr><td>h</td><td>short</td><td>integer</td>integer<td>int16</td><td>2</td></tr>
29+
<tr><td>H</td><td>usigned short</td><td>integer</td>integer<td>uint16</td><td>2</td></tr>
30+
<tr><td>i</td><td>int</td><td>integer</td>integer<td>int32</td><td>4</td></tr>
31+
<tr><td>I</td><td>unsigned int</td><td>integer</td>integer<td>uint32</td><td>4</td></tr>
32+
<tr><td>q</td><td>long long</td><td>integer</td><td>int64</td><td>8</td></tr>
33+
<tr><td>Q</td><td>unsigned long long</td><td>integer</td><td>uint64</td><td>8</td></tr>
34+
<tr><td>f</td><td>float</td><td>float</td><td>float32</td><td>4</td></tr>
35+
<tr><td>d</td><td>double</td><td>float</td><td>float64</td><td>8</td></tr>
36+
<tr><td>s</td><td>char[]</td><td>string</td><td>string</td><td></td></tr>
37+
</table>
38+
39+
**Notes:**
40+
- Format character can has a number prefix, you can use "*3?*" instead of "*???*" for pack/unpack three bool value
41+
- For string , number prefix is the length of value
42+
43+
Usage
44+
======
45+
46+
````
47+
# >>> from struct import *
48+
import struct
49+
50+
# >>> pack('hhi', 1, 2, 3)
51+
var st = newStruct("hhi")
52+
var output = st.add(1.int16).add(2.int16).add(3.int32).pack()
53+
54+
# alternative way to pack
55+
# output = pack("hhi", newStructShort(1), newStructShort(1), newStructInt(3))
56+
57+
# >>> unpack('hhi', '\x00\x01\x00\x02\x00\x00\x00\x03')
58+
var result = unpack("hhi", output);
59+
echo result[0].getShort
60+
echo result[1].getShort
61+
echo result[2].getInt
62+
````

struct.nim

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ type
5151

5252
StructContext = ref object of RootObj
5353
byteOrder: Endianness
54-
nativeAlignment: int
55-
nativeSize: int
5654
buffer: string
5755
offset: int
5856
repeat: int
@@ -67,9 +65,7 @@ const
6765
'h': sizeof(int16),
6866
'H': sizeof(uint16),
6967
'i': sizeof(int32),
70-
'l': sizeof(int32),
7168
'I': sizeof(uint32),
72-
'L': sizeof(uint32),
7369
'q': sizeof(int64),
7470
'Q': sizeof(uint64),
7571
'f': sizeof(float32),
@@ -137,8 +133,6 @@ proc newStructString*(s: string): StructNode =
137133
proc newStructContext(): StructContext =
138134
new(result)
139135
result.byteOrder = system.cpuEndian
140-
result.nativeSize = 1
141-
result.nativeAlignment = 1
142136
result.offset = 0
143137
result.repeat = 1
144138

@@ -229,20 +223,12 @@ proc parse_prefix(ctx: StructContext, f: char) =
229223
case f
230224
of '=':
231225
ctx.byteOrder = system.cpuEndian
232-
ctx.nativeSize = 0
233-
ctx.nativeAlignment = 0
234226
of '<':
235227
ctx.byteOrder = littleEndian
236-
ctx.nativeSize = 0
237-
ctx.nativeAlignment = 0
238228
of '>', '!':
239229
ctx.byteOrder = bigEndian
240-
ctx.nativeSize = 0
241-
ctx.nativeAlignment = 0
242230
else:
243231
ctx.byteOrder = system.cpuEndian
244-
ctx.nativeSize = 1
245-
ctx.nativeAlignment = 1
246232

247233
proc load_16*[T:byte|char|int8|uint8](a, b: T, endian: Endianness): int16 {.inline.} =
248234
if endian == littleEndian:
@@ -328,7 +314,7 @@ proc unpack_bool(vars: var seq[StructNode], ctx: StructContext) =
328314
proc unpack_short(vars: var seq[StructNode], ctx: StructContext, f: char, signed: bool = false) =
329315
for i in 0..ctx.repeat-1:
330316
var value = load_16(ctx.buffer[ctx.offset], ctx.buffer[ctx.offset+1], ctx.byteOrder)
331-
if signed:
317+
if not signed:
332318
vars.add(newStructShort(value))
333319
else:
334320
vars.add(newStructUShort(value.uint16))
@@ -337,7 +323,7 @@ proc unpack_short(vars: var seq[StructNode], ctx: StructContext, f: char, signed
337323
proc unpack_int(vars: var seq[StructNode], ctx: StructContext, f: char, signed: bool = false) =
338324
for i in 0..ctx.repeat-1:
339325
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)
340-
if signed:
326+
if not signed:
341327
vars.add(newStructInt(value))
342328
else:
343329
vars.add(newStructUInt(value.uint32))
@@ -346,7 +332,7 @@ proc unpack_int(vars: var seq[StructNode], ctx: StructContext, f: char, signed:
346332
proc unpack_quad(vars: var seq[StructNode], ctx: StructContext, f: char, signed: bool = false) =
347333
for i in 0..ctx.repeat-1:
348334
var value = load_64(ctx.buffer[ctx.offset..ctx.offset+7], ctx.byteOrder)
349-
if signed:
335+
if not signed:
350336
vars.add(newStructQuad(value))
351337
else:
352338
vars.add(newStructUQuad(value.uint64))
@@ -544,52 +530,52 @@ proc pack*(fmt: string, vars: varargs[StructNode]): string =
544530
raise newException(ValueError, "bad char in struct format")
545531

546532

547-
proc newStruct(fmt: string): Struct =
533+
proc newStruct*(fmt: string): Struct =
548534
new(result)
549535
result.fmt = fmt
550536
result.vars = @[]
551537

552-
proc add(s: Struct, c: char): Struct =
538+
proc add*(s: Struct, c: char): Struct =
553539
result = s
554540
s.vars.add(newStructChar(c))
555541

556-
proc add(s: Struct, b: bool): Struct =
542+
proc add*(s: Struct, b: bool): Struct =
557543
result = s
558544
s.vars.add(newStructBool(b))
559545

560-
proc add(s: Struct, i: int16): Struct =
546+
proc add*(s: Struct, i: int16): Struct =
561547
result = s
562548
s.vars.add(newStructShort(i))
563549

564-
proc add(s: Struct, i: uint16): Struct =
550+
proc add*(s: Struct, i: uint16): Struct =
565551
result = s
566552
s.vars.add(newStructUShort(i))
567553

568-
proc add(s: Struct, i: int32): Struct =
554+
proc add*(s: Struct, i: int32): Struct =
569555
result = s
570556
s.vars.add(newStructInt(i))
571557

572-
proc add(s: Struct, i: uint32): Struct =
558+
proc add*(s: Struct, i: uint32): Struct =
573559
result = s
574560
s.vars.add(newStructUint(i))
575561

576-
proc add(s: Struct, i: int64): Struct =
562+
proc add*(s: Struct, i: int64): Struct =
577563
result = s
578564
s.vars.add(newStructQuad(i))
579565

580-
proc add(s: Struct, i: uint64): Struct =
566+
proc add*(s: Struct, i: uint64): Struct =
581567
result = s
582568
s.vars.add(newStructUQuad(i))
583569

584-
proc add(s: Struct, f: float32): Struct =
570+
proc add*(s: Struct, f: float32): Struct =
585571
result = s
586572
s.vars.add(newStructFloat(f))
587573

588-
proc add(s: Struct, d: float64): Struct =
574+
proc add*(s: Struct, d: float64): Struct =
589575
result = s
590576
s.vars.add(newStructDouble(d))
591577

592-
proc add(s: Struct, str: string): Struct =
578+
proc add*(s: Struct, str: string): Struct =
593579
result = s
594580
s.vars.add(newStructString(str))
595581

test.nim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# >>> from struct import *
2+
import struct
3+
4+
# >>> pack('hhi', 1, 2, 3)
5+
var st = newStruct("hhi")
6+
var output = st.add(1.int16).add(2.int16).add(3.int32).pack()
7+
8+
# alternative way to pack
9+
# output = pack("hhi", newStructShort(1), newStructShort(1), newStructInt(3))
10+
11+
# >>> unpack('hhi', '\x00\x01\x00\x02\x00\x00\x00\x03')
12+
var result = unpack("hhi", output);
13+
echo result[0].getShort
14+
echo result[1].getShort
15+
echo result[2].getInt

0 commit comments

Comments
 (0)