aboutsummaryrefslogtreecommitdiff
path: root/src/protobuf/protobuf.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/protobuf/protobuf.nim')
-rw-r--r--src/protobuf/protobuf.nim517
1 files changed, 0 insertions, 517 deletions
diff --git a/src/protobuf/protobuf.nim b/src/protobuf/protobuf.nim
deleted file mode 100644
index d15bfc7..0000000
--- a/src/protobuf/protobuf.nim
+++ /dev/null
@@ -1,517 +0,0 @@
-import endians
-import intsets
-import macros
-import streams
-import strutils
-
-export streams
-
-const
- MaximumVarintBytes = 10
- WireTypeBits = 3
- WireTypeMask = (1 shl WireTypeBits) - 1
-
-type
- ProtobufStreamObj* = object of StreamObj
- stream: Stream
-
- ProtobufStream* = ref ProtobufStreamObj
-
- Tag* = distinct uint32
-
- ParseError* = object of Exception
-
- InvalidFieldNumberError* = object of ParseError
-
- UnexpectedWireTypeError* = object of ParseError
-
- bytes* = distinct string
-
- WireType* {.pure.} = enum
- Varint = 0
- Fixed64 = 1
- LengthDelimited = 2
- StartGroup = 3
- EndGroup = 4
- Fixed32 = 5
-
- FieldType* {.pure.} = enum
- Double = 1
- Float
- Int64
- UInt64
- Int32
- Fixed64
- Fixed32
- Bool
- String
- Group
- Message
- Bytes
- UInt32
- Enum
- SFixed32
- SFixed64
- SInt32
- SInt64
-
-proc wiretype*(ft: FieldType): WireType =
- case ft
- of FieldType.Double: result = WireType.Fixed64
- of FieldType.Float: result = WireType.Fixed32
- of FieldType.Int64: result = WireType.Varint
- of FieldType.UInt64: result = WireType.Varint
- of FieldType.Int32: result = WireType.Varint
- of FieldType.Fixed64: result = WireType.Fixed64
- of FieldType.Fixed32: result = WireType.Fixed32
- of FieldType.Bool: result = WireType.Varint
- of FieldType.String: result = WireType.LengthDelimited
- of FieldType.Group: result = WireType.LengthDelimited # ???
- of FieldType.Message: result = WireType.LengthDelimited
- of FieldType.Bytes: result = WireType.LengthDelimited
- of FieldType.UInt32: result = WireType.Varint
- of FieldType.Enum: result = WireType.Varint
- of FieldType.SFixed32: result = WireType.Fixed32
- of FieldType.SFixed64: result = WireType.Fixed64
- of FieldType.SInt32: result = WireType.Varint
- of FieldType.SInt64: result = WireType.Varint
-
-proc isNumeric*(wiretype: WireType): bool =
- case wiretype
- of WireType.Varint: result = true
- of WireType.Fixed64: result = true
- of WireType.Fixed32: result = true
- else: result = false
-
-proc isNumeric*(ft: FieldType): bool =
- result = isNumeric(wiretype(ft))
-
-proc pbClose(s: Stream) =
- close(ProtobufStream(s).stream)
- ProtobufStream(s).stream = nil
-
-proc pbAtEnd(s: Stream): bool =
- result = atEnd(ProtobufStream(s).stream)
-
-proc pbSetPosition(s: Stream, pos: int) =
- setPosition(ProtobufStream(s).stream, pos)
-
-proc pbGetPosition(s: Stream): int =
- result = getPosition(ProtobufStream(s).stream)
-
-proc pbReadData(s: Stream, buffer: pointer, bufLen: int): int =
- result = readData(ProtobufStream(s).stream, buffer, bufLen)
-
-proc pbPeekData(s: Stream, buffer: pointer, bufLen: int): int =
- result = peekData(ProtobufStream(s).stream, buffer, bufLen)
-
-proc pbWriteData(s: Stream, buffer: pointer, bufLen: int) =
- writeData(ProtobufStream(s).stream, buffer, bufLen)
-
-proc pbFlush(s: Stream) =
- flush(ProtobufStream(s).stream)
-
-proc newProtobufStream*(stream: Stream): ProtobufStream =
- new(result)
-
- result.closeImpl = pbClose
- result.atEndImpl = pbAtEnd
- result.setPositionImpl = pbSetPosition
- result.getPositionImpl = pbGetPosition
- result.readDataImpl = pbReadData
- result.peekDataImpl = pbPeekData
- result.writeDataImpl = pbWriteData
- result.flushImpl = pbFlush
-
- result.stream = stream
-
-proc readByte(stream: ProtobufStream): byte =
- result = readInt8(stream).byte
-
-proc writeByte(stream: ProtobufStream, b: byte) =
- var x: byte
- shallowCopy(x, b)
- writeData(stream, addr(x), sizeof(x))
-
-proc readVarint*(stream: ProtobufStream): uint64 =
- var
- count = 0
-
- result = 0
-
- while true:
- if count == MaximumVarintBytes:
- raise newException(Exception, "invalid varint (<= 10 bytes)")
-
- let b = readByte(stream)
-
- result = result or ((b.uint64 and 0x7f) shl (7 * count))
-
- inc(count)
-
- if (b and 0x80) == 0:
- break
-
-proc writeVarint*(stream: ProtobufStream, n: uint64) =
- var value = n
- while value >= 0x80'u64:
- writeByte(stream, (value or 0x80).byte)
- value = value shr 7
- writeByte(stream, value.byte)
-
-proc zigzagEncode*(n: int32): uint32 =
- {.emit:["result = ((NU32)n << 1) ^ (NU32)(n >> 31);"].}
-
-proc zigzagDecode*(n: uint32): int32 =
- {.emit:["result = (NI32) ((n >> 1) ^ (~(n & 1) + 1));"].}
-
-proc zigzagEncode*(n: int64): uint64 =
- {.emit:["result = ((NU64)n << 1) ^ (NU64)(n >> 63);"].}
-
-proc zigzagDecode*(n: uint64): int64 =
- {.emit:["result = (NI64) ((n >> 1) ^ (~(n & 1) + 1));"].}
-
-template makeTag*(fieldNumber: int, wireType: WireType): Tag =
- ((fieldNumber shl 3).uint32 or wireType.uint32).Tag
-
-template getTagWireType*(tag: Tag): WireType =
- (tag.uint32 and WireTypeMask).WireType
-
-template getTagFieldNumber*(tag: Tag): int =
- (tag.uint32 shr 3).int
-
-proc writeTag*(stream: ProtobufStream, tag: Tag) =
- writeVarint(stream, tag.uint32)
-
-proc writeTag*(stream: ProtobufStream, fieldNumber: int, wireType: WireType) =
- writeTag(stream, makeTag(fieldNumber, wireType))
-
-proc readTag*(stream: ProtobufStream): Tag =
- result = readVarint(stream).Tag
-
-proc writeInt32*(stream: ProtobufStream, n: int32) =
- writeVarint(stream, n.uint64)
-
-proc writeInt32*(stream: ProtobufStream, n: int32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeInt32(stream, n)
-
-proc readInt32*(stream: ProtobufStream): int32 =
- result = readVarint(stream).int32
-
-proc writeSInt32*(stream: ProtobufStream, n: int32) =
- writeVarint(stream, zigzagEncode(n))
-
-proc writeSInt32*(stream: ProtobufStream, n: int32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, zigzagEncode(n))
-
-proc readSInt32*(stream: ProtobufStream): int32 =
- result = zigzagDecode(readVarint(stream).uint32)
-
-proc writeUInt32*(stream: ProtobufStream, n: uint32) =
- writeVarint(stream, n)
-
-proc writeUInt32*(stream: ProtobufStream, n: uint32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, n)
-
-proc readUInt32*(stream: ProtobufStream): uint32 =
- result = readVarint(stream).uint32
-
-proc writeInt64*(stream: ProtobufStream, n: int64) =
- writeVarint(stream, n.uint64)
-
-proc writeInt64*(stream: ProtobufStream, n: int64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, n.uint64)
-
-proc readInt64*(stream: ProtobufStream): int64 =
- result = readVarint(stream).int64
-
-proc writeSInt64*(stream: ProtobufStream, n: int64) =
- writeVarint(stream, zigzagEncode(n))
-
-proc writeSInt64*(stream: ProtobufStream, n: int64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, zigzagEncode(n))
-
-proc readSInt64*(stream: ProtobufStream): int64 =
- result = zigzagDecode(readVarint(stream))
-
-proc writeUInt64*(stream: ProtobufStream, n: uint64) =
- writeVarint(stream, n)
-
-proc writeUInt64*(stream: ProtobufStream, n: uint64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, n)
-
-proc readUInt64*(stream: ProtobufStream): uint64 =
- result = readVarint(stream)
-
-proc writeBool*(stream: ProtobufStream, value: bool) =
- writeVarint(stream, value.uint32)
-
-proc writeBool*(stream: ProtobufStream, n: bool, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Varint)
- writeVarint(stream, n.uint32)
-
-proc readBool*(stream: ProtobufStream): bool =
- result = readVarint(stream).bool
-
-proc writeFixed64*(stream: ProtobufStream, value: uint64) =
- var
- input = value
- output: uint64
-
- littleEndian64(addr(output), addr(input))
-
- write(stream, output)
-
-proc writeFixed64*(stream: ProtobufStream, n: uint64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed64)
- writeFixed64(stream, n)
-
-proc readFixed64*(stream: ProtobufStream): uint64 =
- var tmp: uint64
- if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
- raise newException(IOError, "cannot read from stream")
- littleEndian64(addr(result), addr(tmp))
-
-proc writeSFixed64*(stream: ProtobufStream, value: int64) =
- writeFixed64(stream, cast[uint64](value))
-
-proc writeSFixed64*(stream: ProtobufStream, value: int64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed64)
- writeSFixed64(stream, value)
-
-proc readSFixed64*(stream: ProtobufStream): int64 =
- result = cast[int64](readFixed64(stream))
-
-proc writeDouble*(stream: ProtobufStream, value: float64) =
- var
- input = value
- output: float64
-
- littleEndian64(addr(output), addr(input))
-
- write(stream, output)
-
-proc writeDouble*(stream: ProtobufStream, value: float64, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed64)
- writeDouble(stream, value)
-
-proc readDouble*(stream: ProtobufStream): float64 =
- var tmp: uint64
- if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
- raise newException(IOError, "cannot read from stream")
- littleEndian64(addr(result), addr(tmp))
-
-proc writeFixed32*(stream: ProtobufStream, value: uint32) =
- var
- input = value
- output: uint32
-
- littleEndian32(addr(output), addr(input))
-
- write(stream, output)
-
-proc writeFixed32*(stream: ProtobufStream, value: uint32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed32)
- writeFixed32(stream, value)
-
-proc readFixed32*(stream: ProtobufStream): uint32 =
- var tmp: uint32
- if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
- raise newException(IOError, "cannot read from stream")
- littleEndian32(addr(result), addr(tmp))
-
-proc writeSFixed32*(stream: ProtobufStream, value: int32) =
- writeFixed32(stream, cast[uint32](value))
-
-proc writeSFixed32*(stream: ProtobufStream, value: int32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed32)
- writeSFixed32(stream, value)
-
-proc readSFixed32*(stream: ProtobufStream): int32 =
- result = cast[int32](readFixed32(stream))
-
-proc writeFloat*(stream: ProtobufStream, value: float32) =
- var
- input = value
- output: float32
-
- littleEndian32(addr(output), addr(input))
-
- write(stream, output)
-
-proc writeFloat*(stream: ProtobufStream, value: float32, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.Fixed32)
- writeFloat(stream, value)
-
-proc readFloat*(stream: ProtobufStream): float32 =
- var tmp: float32
- if readData(stream, addr(tmp), sizeof(tmp)) != sizeof(tmp):
- raise newException(IOError, "cannot read from stream")
- littleEndian32(addr(result), addr(tmp))
-
-proc writeString*(stream: ProtobufStream, s: string) =
- writeUInt64(stream, len(s).uint64)
- write(stream, s)
-
-proc writeString*(stream: ProtobufStream, s: string, fieldNumber: int) =
- writeTag(stream, fieldNumber, WireType.LengthDelimited)
- writeString(stream, s)
-
-proc writeBytes*(stream: ProtobufStream, s: bytes) =
- writeString(stream, string(s))
-
-proc writeBytes*(stream: ProtobufStream, s: bytes, fieldNumber: int) =
- writeString(stream, string(s), fieldNumber)
-
-proc safeReadStr*(stream: Stream, size: int): string =
- result = newString(size)
- if readData(stream, addr(result[0]), size) != size:
- raise newException(IOError, "cannot read from stream")
-
-proc readString*(stream: ProtobufStream): string =
- let size = int(readUInt64(stream))
- result = safeReadStr(stream, size)
-
-proc readBytes*(stream: ProtobufStream): bytes =
- bytes(readString(stream))
-
-proc readEnum*[T](stream: ProtobufStream): T =
- result = T(readUInt32(stream))
-
-proc writeEnum*[T](stream: ProtobufStream, value: T) =
- writeUInt32(stream, uint32(value))
-
-proc sizeOfVarint[T](value: T): uint64 =
- var tmp = uint64(value)
- while tmp >= 0x80'u64:
- tmp = tmp shr 7
- inc(result)
- inc(result)
-
-proc packedFieldSize*[T](values: seq[T], fieldtype: FieldType): uint64 =
- case fieldtype
- of FieldType.Fixed64, FieldType.SFixed64, FieldType.Double:
- result = uint64(len(values)) * 8
- of FieldType.Fixed32, FieldType.SFixed32, FieldType.Float:
- result = uint64(len(values)) * 4
- of FieldType.Int64, FieldType.UInt64, FieldType.Int32, FieldType.Bool,
- FieldType.UInt32, FieldType.Enum:
- for value in values:
- result += sizeOfVarint(value)
- of FieldType.SInt32:
- for value in values:
- result += sizeOfVarint(zigzagEncode(int32(value)))
- of FieldType.SInt64:
- for value in values:
- result += sizeOfVarint(zigzagEncode(int64(value)))
- else:
- raise newException(Exception, "invalid fieldtype")
-
-proc sizeOfString*(s: string): uint64 =
- result = sizeOfVarint(len(s).uint64) + len(s).uint64
-
-proc sizeOfBytes*(s: bytes): uint64 =
- result = sizeOfString(string(s))
-
-proc sizeOfDouble*(value: float64): uint64 =
- result = 8
-
-proc sizeOfFloat*(value: float32): uint64 =
- result = 4
-
-proc sizeOfInt64*(value: int64): uint64 =
- result = sizeOfVarint(value)
-
-proc sizeOfUInt64*(value: uint64): uint64 =
- result = sizeOfVarint(value)
-
-proc sizeOfInt32*(value: int32): uint64 =
- result = sizeOfVarint(value)
-
-proc sizeOfFixed64*(value: uint64): uint64 =
- result = 8
-
-proc sizeOfFixed32*(value: uint32): uint64 =
- result = 4
-
-proc sizeOfBool*(value: bool): uint64 =
- result = sizeOfVarint(value)
-
-proc sizeOfUInt32*(value: uint32): uint64 =
- result = sizeOfVarint(value)
-
-proc sizeOfSFixed32*(value: int32): uint64 =
- result = 4
-
-proc sizeOfSFixed64*(value: int64): uint64 =
- result = 8
-
-proc sizeOfSInt32*(value: int32): uint64 =
- result = sizeOfVarint(zigzagEncode(value))
-
-proc sizeOfSInt64*(value: int64): uint64 =
- result = sizeOfVarint(zigzagEncode(value))
-
-proc sizeOfEnum*[T](value: T): uint64 =
- result = sizeOfUInt32(value.uint32)
-
-proc sizeOfLengthDelimited*(size: uint64): uint64 =
- result = size + sizeOfVarint(size)
-
-proc sizeOfTag*(fieldNumber: int, wiretype: WireType): uint64 =
- result = sizeOfUInt32(uint32(makeTag(fieldNumber, wiretype)))
-
-proc skipField*(stream: ProtobufStream, wiretype: WireType) =
- case wiretype
- of WireType.Varint:
- discard readVarint(stream)
- of WireType.Fixed64:
- discard readFixed64(stream)
- of WireType.Fixed32:
- discard readFixed32(stream)
- of WireType.LengthDelimited:
- let size = readVarint(stream)
- discard safeReadStr(stream, int(size))
- else:
- raise newException(Exception, "unsupported wiretype: " & $wiretype)
-
-proc expectWireType*(actual: WireType, expected: varargs[WireType]) =
- for exp in expected:
- if actual == exp:
- return
- let message = "Got wiretype " & $actual & " but expected: " &
- join(expected, ", ")
- raise newException(UnexpectedWireTypeError, message)
-
-macro writeMessage*(stream: ProtobufStream, message: typed, fieldNumber: int): typed =
- ## Write a message to a stream with tag and length.
- let t = getTypeInst(message)
- result = newStmtList(
- newCall(
- ident("writeTag"),
- stream,
- fieldNumber,
- newDotExpr(ident("WireType"), ident("LengthDelimited"))
- ),
- newCall(
- ident("writeVarint"),
- stream,
- newCall(ident("sizeOf" & $t), message)
- ),
- newCall(
- ident("write" & $t),
- stream,
- message
- )
- )
-
-proc excl*(s: var IntSet, values: openArray[int]) =
- ## Exclude multiple values from an IntSet.
- for value in values:
- excl(s, value)