Add object encoding/decoding
This commit is contained in:
parent
2db4d48802
commit
aae968ac3b
2 changed files with 32 additions and 17 deletions
|
|
@ -38,13 +38,6 @@ type
|
|||
proc newProtoBuffer*(): ProtoBuffer =
|
||||
ProtoBuffer(outstream: OutputStream.init(), fieldNum: 1)
|
||||
|
||||
# Main interface
|
||||
proc encode*(): ProtoBuffer =
|
||||
discard
|
||||
|
||||
proc decode*[T](source: ProtoBuffer): T =
|
||||
discard
|
||||
|
||||
proc output*(proto: ProtoBuffer): seq[byte] {.inline.} =
|
||||
proto.outstream.getOutput
|
||||
|
||||
|
|
@ -59,6 +52,8 @@ template protoHeader*(fieldNum: int, wire: ProtoWireType): byte =
|
|||
((cast[uint](fieldNum) shl 3) or cast[uint](wire)).byte
|
||||
|
||||
template increaseBytesRead(amount = 1) =
|
||||
## Convenience template for increasing
|
||||
## all of the counts
|
||||
mixin isSome
|
||||
bytesRead += amount
|
||||
outOffset += amount
|
||||
|
|
@ -111,10 +106,14 @@ proc encodeField*(protobuf: var ProtoBuffer, value: SomeLengthDelimited) {.inlin
|
|||
proc put(stream: OutputStreamVar, value: object) {.inline.}
|
||||
|
||||
proc encodeField(stream: OutputStreamVar, fieldNum: int, value: object) {.inline.} =
|
||||
#TODO Encode generic objects
|
||||
stream.append protoHeader(fieldNum, LengthDelimited)
|
||||
|
||||
# This is currently needed in order to get the size
|
||||
# of the output before adding it to the stream.
|
||||
# Maybe there is a better way to do this
|
||||
let objStream = OutputStream.init()
|
||||
objStream.put(value)
|
||||
|
||||
let objOutput = objStream.getOutput()
|
||||
stream.put(len(objOutput).uint)
|
||||
stream.put(objOutput)
|
||||
|
|
@ -123,11 +122,17 @@ proc encodeField*(protobuf: var ProtoBuffer, value: object) {.inline.} =
|
|||
protobuf.outstream.encodeField(protobuf.fieldNum, value)
|
||||
inc protobuf.fieldNum
|
||||
|
||||
proc encode*(protobuf: var ProtoBuffer, value: object) {.inline.} =
|
||||
var fieldNum = 1
|
||||
for field, val in value.fieldPairs:
|
||||
protobuf.outstream.encodeField(fieldNum, val)
|
||||
inc fieldNum
|
||||
|
||||
proc put(stream: OutputStreamVar, value: object) {.inline.} =
|
||||
var fieldNum = 1
|
||||
for field, val in value.fieldPairs:
|
||||
stream.encodeField(fieldNum, val)
|
||||
fieldNum += 1
|
||||
inc fieldNum
|
||||
|
||||
proc getVarint[T: SomeVarint](
|
||||
bytes: var seq[byte],
|
||||
|
|
@ -320,7 +325,7 @@ proc decodeField*[T: object](
|
|||
let bytesToRead = some(decodedSize.int)
|
||||
for field, val in result.value.fieldPairs:
|
||||
setField(result.value, index, outOffset, outBytesProcessed, bytesToRead, bytes)
|
||||
index += 1
|
||||
inc index
|
||||
|
||||
proc decode*[T: object](
|
||||
bytes: var seq[byte],
|
||||
|
|
@ -332,4 +337,4 @@ proc decode*[T: object](
|
|||
var fieldNum = 1
|
||||
for field, val in result.fieldPairs:
|
||||
setField(result, fieldNum, offset, bytesRead, none(int), bytes)
|
||||
fieldNum += 1
|
||||
inc fieldNum
|
||||
|
|
@ -15,7 +15,7 @@ type
|
|||
i: Test1
|
||||
|
||||
suite "Test Varint Encoding":
|
||||
test "Can encode/decode enum":
|
||||
test "Can encode/decode enum field":
|
||||
var proto = newProtoBuffer()
|
||||
var bytesProcessed: int
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ suite "Test Varint Encoding":
|
|||
assert decodedME2.value == ME2
|
||||
assert decodedME2.index == 2
|
||||
|
||||
test "Can encode/decode negative number":
|
||||
test "Can encode/decode negative number field":
|
||||
var proto = newProtoBuffer()
|
||||
let num = -153452
|
||||
var bytesProcessed: int
|
||||
|
|
@ -50,7 +50,7 @@ suite "Test Varint Encoding":
|
|||
assert decoded.value == num
|
||||
assert decoded.index == 1
|
||||
|
||||
test "Can encode/decode unsigned number":
|
||||
test "Can encode/decode unsigned number field":
|
||||
var proto = newProtoBuffer()
|
||||
let num = 123151.uint
|
||||
var bytesProcessed: int
|
||||
|
|
@ -65,7 +65,7 @@ suite "Test Varint Encoding":
|
|||
assert decoded.value == num
|
||||
assert decoded.index == 1
|
||||
|
||||
test "Can encode/decode string":
|
||||
test "Can encode/decode string field":
|
||||
var proto = newProtoBuffer()
|
||||
let str = "hey this is a string"
|
||||
var bytesProcessed: int
|
||||
|
|
@ -80,7 +80,7 @@ suite "Test Varint Encoding":
|
|||
assert decoded.value == str
|
||||
assert decoded.index == 1
|
||||
|
||||
test "Can encode/decode object":
|
||||
test "Can encode/decode object field":
|
||||
var proto = newProtoBuffer()
|
||||
|
||||
let obj = Test3(g: 300, h: 200, i: Test1(a: 100))
|
||||
|
|
@ -91,4 +91,14 @@ suite "Test Varint Encoding":
|
|||
var output = proto.output
|
||||
let decoded = decodeField(output, Test3, offset, bytesProcessed)
|
||||
assert decoded.value == obj
|
||||
assert decoded.index == 1
|
||||
assert decoded.index == 1
|
||||
|
||||
test "Can encode/decode object":
|
||||
var proto = newProtoBuffer()
|
||||
|
||||
let obj = Test3(g: 300, h: 200, i: Test1(a: 100))
|
||||
|
||||
proto.encode(obj)
|
||||
var output = proto.output
|
||||
let decoded = output.decode(Test3)
|
||||
assert decoded == obj
|
||||
Loading…
Add table
Add a link
Reference in a new issue