disable the IntLike concept

The Stint types don't conform to it at the moment anyway and this
simplifies the error messages in many situations.
This commit is contained in:
Zahary Karadjov 2018-06-27 02:40:49 +03:00
parent 9959863512
commit d75b09795b
2 changed files with 36 additions and 12 deletions

12
rlp.nim
View File

@ -96,9 +96,13 @@ proc lengthBytesCount(self: Rlp): int =
return int(marker - LEN_PREFIXED_LIST_MARKER)
return 0
proc isSingleByte(self: Rlp): bool =
proc isSingleByte*(self: Rlp): bool =
hasData() and bytes[position] < BLOB_START_MARKER
proc getByteValue*(self: Rlp): byte =
assert self.isSingleByte()
return bytes[position]
proc payloadOffset(self: Rlp): int =
if isSingleByte(): 0 else: 1 + lengthBytesCount()
@ -175,7 +179,9 @@ proc isInt*(self: Rlp): bool =
template maxBytes*(o: typedesc[Ordinal | uint64 | uint]): int = sizeof(o)
proc toInt*(self: Rlp, IntType: typedesc): IntType =
mixin maxBytes
# XXX: work-around a Nim issue with typedesc parameters
type OutputType = IntType
mixin maxBytes, to
# XXX: self insertions are not working in generic procs
# https://github.com/nim-lang/Nim/issues/5053
@ -193,7 +199,7 @@ proc toInt*(self: Rlp, IntType: typedesc): IntType =
raise newException(RlpTypeMismatch, "The RLP contains a larger than expected Int value")
for i in payloadStart ..< (payloadStart + payloadSize):
result = cast[IntType](result shl 8) or cast[IntType](self.bytes[self.position + i])
result = (result shl 8) or OutputType(self.bytes[self.position + i])
proc toString*(self: Rlp): string =
if not isBlob():

View File

@ -13,17 +13,23 @@ type
PrematureFinalizationError* = object of Exception
IntLike* = concept x, y, type T
IntLike* = concept x, y
type T = type(x)
# arithmetic ops
x + y is T
x * y is T
x - y is T
x div y is T
x mod y is T
x shr y is T
x shl y is T
x and int # for masking
Integer* = SomeInteger or IntLike
# some int compatibility required for big endian encoding:
x shr int is T
x shl int is T
x and 0xff is int
x < 128 is bool
Integer* = SomeInteger # or IntLike
const
wrapObjectsInList* = true
@ -35,14 +41,16 @@ proc bytesNeeded(num: Integer): int =
inc result
n = n shr 8
proc writeBigEndian(outStream: var Bytes, number: int,
proc writeBigEndian(outStream: var Bytes, number: Integer,
lastByteIdx: int, numberOfBytes: int) =
mixin `and`, `shr`
var n = number
for i in countdown(lastByteIdx, lastByteIdx - int(numberOfBytes) + 1):
outStream[i] = byte(n and 0xff)
n = n shr 8
proc writeBigEndian(outStream: var Bytes, number: int,
proc writeBigEndian(outStream: var Bytes, number: Integer,
numberOfBytes: int) {.inline.} =
outStream.setLen(outStream.len + numberOfBytes)
outStream.writeBigEndian(number, outStream.len - 1, numberOfBytes)
@ -161,7 +169,9 @@ proc appendBytesRange(self; data: BytesRange) =
proc appendImpl(self; data: MemRange) =
appendBlob(self, data, BLOB_START_MARKER)
proc appendImpl(self; i: Integer) =
proc appendInt(self; i: Integer) =
# this is created as a separate proc as an extra precaution against
# any overloading resolution problems when matching the IntLike concept.
type IntType = type(i)
if i == IntType(0):
@ -171,10 +181,13 @@ proc appendImpl(self; i: Integer) =
else:
let bytesNeeded = i.bytesNeeded
self.output.writeCount(bytesNeeded, BLOB_START_MARKER)
self.output.writeBigEndian(i.int, bytesNeeded)
self.output.writeBigEndian(i, bytesNeeded)
self.maybeClosePendingLists()
template appendImpl(self; i: Integer) =
appendInt(self, i)
template appendImpl(self; e: enum) =
appendImpl(self, int(e))
@ -235,6 +248,11 @@ proc encode*[T](v: T): BytesRange =
writer.append(v)
return writer.finish
proc encodeInt*(i: Integer): BytesRange =
var writer = initRlpWriter()
writer.appendInt(i)
return writer.finish
macro encodeList*(args: varargs[untyped]): BytesRange =
var
listLen = args.len