-
Notifications
You must be signed in to change notification settings - Fork 2
/
byte_order_writer.nim
134 lines (98 loc) · 4.1 KB
/
byte_order_writer.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#[
Authors: Dr. John Lindsay
Created: January 18, 2018
Last Modified: January 18, 2018
License: MIT
Notes: This module provides convience procs for writing multi-byte values from a byte buffer
taking byte endianness into account.
]#
import system, endians
###################
# ByteOrderWriter #
###################
type
ByteOrderWriter* = object
data*: seq[uint8]
endian: Endianness
pos: int
proc newByteOrderWriter*(size: int, endian: Endianness, pos = 0): ByteOrderWriter =
var d = newSeq[uint8](size)
result = ByteOrderWriter(data: d, endian: endian, pos: pos)
proc `pos=`*(b: var ByteOrderWriter, value: int) {.inline.} = b.pos = value
proc pos*(b: var ByteOrderWriter): int {.inline.} = return b.pos
proc `endian=`*(b: var ByteOrderWriter, value: Endianness) {.inline.} = b.endian = value
proc endian*(b: var ByteOrderWriter): Endianness {.inline.} = return b.endian
proc writeUint8*(b: var ByteOrderWriter, value: uint8) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
b.data[b.pos] = value
b.pos += 1
proc writeUint16*(b: var ByteOrderWriter, value: var uint16) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian16(addr b.data[b.pos], addr value)
else:
bigEndian16(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeUint32*(b: var ByteOrderWriter, value: var uint32) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian32(addr b.data[b.pos], addr value)
else:
bigEndian32(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeUint64*(b: var ByteOrderWriter, value: var uint64) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian64(addr b.data[b.pos], addr value)
else:
bigEndian64(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeInt8*(b: var ByteOrderWriter, value: var int8) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
b.data[b.pos] = cast[uint8](value)
b.pos += 1
proc writeInt16*(b: var ByteOrderWriter, value: var int16) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian16(addr b.data[b.pos], addr value)
else:
bigEndian16(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeInt32*(b: var ByteOrderWriter, value: var int32) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian32(addr b.data[b.pos], addr value)
else:
bigEndian32(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeInt64*(b: var ByteOrderWriter, value: var int64) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian64(addr b.data[b.pos], addr value)
else:
bigEndian64(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeFloat32*(b: var ByteOrderWriter, value: var float32) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian32(addr b.data[b.pos], addr value)
else:
bigEndian32(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)
proc writeFloat64*(b: var ByteOrderWriter, value: var float64) {.inline.} =
if b.pos + sizeOf(value) > b.data.len or b.pos < 0:
raise newException(IndexError, "Write past data length")
if b.endian == littleEndian:
littleEndian64(addr b.data[b.pos], addr value)
else:
bigEndian64(addr b.data[b.pos], addr value)
b.pos += sizeOf(value)