## BaraDB binary wire protocol — shared between client and server. import std/endians const ProtocolMagic* = 0x42415241'u32 type FieldKind* = enum fkNull = 0x00 fkBool = 0x01 fkInt8 = 0x02 fkInt16 = 0x03 fkInt32 = 0x04 fkInt64 = 0x05 fkFloat32 = 0x06 fkFloat64 = 0x07 fkString = 0x08 fkBytes = 0x09 fkArray = 0x0A fkObject = 0x0B fkVector = 0x0C fkJson = 0x0D MsgKind* = enum mkClientHandshake = 0x01 mkQuery = 0x02 mkQueryParams = 0x03 mkExecute = 0x04 mkBatch = 0x05 mkTransaction = 0x06 mkClose = 0x07 mkPing = 0x08 mkAuth = 0x09 mkServerHandshake = 0x80 mkReady = 0x81 mkData = 0x82 mkComplete = 0x83 mkError = 0x84 mkAuthChallenge = 0x85 mkAuthOk = 0x86 mkSchemaChange = 0x87 mkPong = 0x88 mkTransactionState = 0x89 ResultFormat* = enum rfBinary = 0x00 rfJson = 0x01 rfText = 0x02 WireValue* = object case kind*: FieldKind of fkNull: discard of fkBool: boolVal*: bool of fkInt8: int8Val*: int8 of fkInt16: int16Val*: int16 of fkInt32: int32Val*: int32 of fkInt64: int64Val*: int64 of fkFloat32: float32Val*: float32 of fkFloat64: float64Val*: float64 of fkString: strVal*: string of fkBytes: bytesVal*: seq[byte] of fkArray: arrayVal*: seq[WireValue] of fkObject: objVal*: seq[(string, WireValue)] of fkVector: vecVal*: seq[float32] of fkJson: jsonVal*: string proc writeUint32*(buf: var seq[byte], val: uint32) = var bytes: array[4, byte] bigEndian32(addr bytes, unsafeAddr val) buf.add(bytes) proc writeUint64(buf: var seq[byte], val: uint64) = var bytes: array[8, byte] bigEndian64(addr bytes, unsafeAddr val) buf.add(bytes) proc writeString*(buf: var seq[byte], s: string) = buf.writeUint32(uint32(s.len)) for ch in s: buf.add(byte(ch)) proc readUint32*(buf: openArray[byte], pos: var int): uint32 = var bytes: array[4, byte] for i in 0..3: bytes[i] = buf[pos + i] bigEndian32(addr result, unsafeAddr bytes) pos += 4 proc readUint64*(buf: openArray[byte], pos: var int): uint64 = var bytes: array[8, byte] for i in 0..7: bytes[i] = buf[pos + i] bigEndian64(addr result, unsafeAddr bytes) pos += 8 proc readString*(buf: openArray[byte], pos: var int): string = let len = int(readUint32(buf, pos)) result = newString(len) for i in 0..