mirror of https://github.com/status-im/nim-rlp.git
88 lines
2.1 KiB
Nim
88 lines
2.1 KiB
Nim
import
|
|
ranges/ptr_arith
|
|
|
|
type
|
|
Bytes* = seq[byte]
|
|
|
|
BytesRange* = object
|
|
bytes*: Bytes
|
|
ibegin*, iend*: int
|
|
|
|
proc initBytesRange*(s: var Bytes, ibegin = 0, iend = -1): BytesRange =
|
|
let e = if iend < 0: s.len + iend + 1
|
|
else: iend
|
|
assert ibegin >= 0 and e <= s.len
|
|
|
|
shallow(s)
|
|
result.bytes = s
|
|
result.ibegin = ibegin
|
|
result.iend = e
|
|
|
|
var
|
|
zeroBytes*: Bytes = @[]
|
|
zeroBytesRange* = initBytesRange(zeroBytes)
|
|
|
|
proc `[]`*(r: BytesRange, i: int): byte =
|
|
r.bytes[r.ibegin + i]
|
|
|
|
proc `[]`*(r: var BytesRange, i: int): var byte =
|
|
r.bytes[r.ibegin + i]
|
|
|
|
# XXX: change this to a template after fixing
|
|
# https://github.com/nim-lang/Nim/issues/7097
|
|
proc `[]=`*(r: var BytesRange, i: int, v: byte) =
|
|
r.bytes[r.ibegin + i] = v
|
|
|
|
proc len*(r: BytesRange): int {.inline.} =
|
|
r.iend - r.ibegin
|
|
|
|
proc slice*(r: BytesRange, ibegin: int, iend = -1): BytesRange =
|
|
result.bytes = r.bytes
|
|
result.ibegin = r.ibegin + ibegin
|
|
let e = if iend < 0: r.iend + iend + 1
|
|
else: r.ibegin + iend
|
|
assert ibegin >= 0 and e <= result.bytes.len
|
|
result.iend = e
|
|
|
|
iterator items*(r: BytesRange): byte =
|
|
for i in r.ibegin ..< r.iend:
|
|
yield r.bytes[i]
|
|
|
|
proc toRange*(s: Bytes): BytesRange =
|
|
var seqCopy = s
|
|
return initBytesRange(seqCopy)
|
|
|
|
proc toRange*(s: var Bytes): BytesRange =
|
|
return initBytesRange(s)
|
|
|
|
# XXX: This could be a template once the following issue is fixed:
|
|
# https://github.com/nim-lang/Nim/issues/7223
|
|
proc rangeBeginAddr*(r: BytesRange): pointer {.inline.} =
|
|
baseAddr(r.bytes).shift(r.ibegin)
|
|
|
|
proc baseAddr*(r: BytesRange): pointer =
|
|
baseAddr(r.bytes).shift(r.ibegin)
|
|
|
|
proc toBytes*(r: BytesRange, output: var openarray[byte]) =
|
|
let sz = r.len
|
|
assert(output.len >= sz)
|
|
copyMem(addr output[0], unsafeAddr r.bytes[r.ibegin], sz)
|
|
|
|
proc toBytes*(r: BytesRange): Bytes =
|
|
result = newSeq[byte](r.len)
|
|
r.toBytes(result)
|
|
|
|
when false:
|
|
import
|
|
ptr_arith, keccak_tiny
|
|
|
|
type
|
|
KeccakHash* = Hash[256]
|
|
|
|
proc toInputRange*(r: BytesRange): keccak_tiny.InputRange =
|
|
result[0] = r.bytes.seqBaseAddr.shift(r.ibegin)
|
|
result[1] = r.len
|
|
|
|
proc keccak*(r: BytesRange): KeccakHash = keccak_256(r)
|
|
|