Decode from non-seekable streams

This commit is contained in:
Emery Hemingway 2024-05-06 13:27:59 +02:00
parent 3b9c164737
commit c40d2c6443
2 changed files with 24 additions and 15 deletions

View File

@ -1,6 +1,6 @@
# Package
version = "20240426"
version = "20240506"
author = "Emery Hemingway"
description = "data model and serialization format"
license = "Unlicense"

View File

@ -15,11 +15,12 @@ proc readVarint(s: Stream): uint =
c = uint s.readUint8
result = result or (c shl shift)
proc decodePreserves*(s: Stream): Value =
proc decodePreserves*(s: Stream): Value {.gcsafe.}
proc decodePreserves(s: Stream; tag: uint8): Value =
## Decode a Preserves value from a binary-encoded stream.
if s.atEnd: raise newException(IOError, "End of Preserves stream")
const endMarker = 0x84
let tag = s.readUint8()
case tag
of 0x80: result = Value(kind: pkBoolean, bool: false)
of 0x81: result = Value(kind: pkBoolean, bool: true)
@ -99,30 +100,38 @@ proc decodePreserves*(s: Stream): Value =
of 0xb4:
result = Value(kind: pkRecord)
var label = decodePreserves(s)
while s.peekUint8() != endMarker:
result.record.add decodePreserves(s)
var tag = s.readUint8()
while tag != endMarker:
result.record.add decodePreserves(s, tag)
tag = s.readUint8()
result.record.add(move label)
discard s.readUint8()
of 0xb5:
result = Value(kind: pkSequence)
while s.peekUint8() != endMarker:
result.sequence.add decodePreserves(s)
discard s.readUint8()
var tag = s.readUint8()
while tag != endMarker:
result.sequence.add decodePreserves(s, tag)
tag = s.readUint8()
of 0xb6:
result = Value(kind: pkSet)
while s.peekUint8() != endMarker:
incl(result, decodePreserves(s))
discard s.readUint8()
var tag = s.readUint8()
while tag != endMarker:
incl(result, decodePreserves(s, tag))
tag = s.readUint8()
of 0xb7:
result = Value(kind: pkDictionary)
while s.peekUint8() != endMarker:
result[decodePreserves(s)] = decodePreserves(s)
discard s.readUint8()
var tag = s.readUint8()
while tag != endMarker:
result[decodePreserves(s, tag)] = decodePreserves(s)
tag = s.readUint8()
of endMarker:
raise newException(ValueError, "invalid Preserves stream")
else:
raise newException(ValueError, "invalid Preserves tag byte 0x" & tag.toHex(2))
proc decodePreserves*(s: Stream): Value {.gcsafe.} =
## Decode a Preserves value from a binary-encoded stream.
s.decodePreserves s.readUint8()
proc decodePreserves*(s: string): Value =
## Decode a string of binary-encoded Preserves.
decodePreserves(s.newStringStream)