mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-07-24 08:43:16 +00:00
47 lines
1.7 KiB
Nim
47 lines
1.7 KiB
Nim
## `cbor_serialization` wrapper adapting its exception API to `Result[T, string]` for the FFI layer.
|
|
## `.ffi.` payloads (plain `object` and `ref T`) cross as value copies; raw `pointer`/`ptr T` are
|
|
## rejected at macro-expansion time (see `rejectRawPtrType`).
|
|
|
|
import system/ansi_c
|
|
import cbor_serialization, cbor_serialization/std/options, results
|
|
|
|
export cbor_serialization, options, results
|
|
|
|
const CborNullByte*: byte = 0xf6'u8
|
|
## CBOR `null` — wire sentinel for empty OK payloads.
|
|
|
|
proc cborEncode*[T](x: T): seq[byte] =
|
|
return Cbor.encode(x)
|
|
|
|
proc cborEncodeShared*[T](x: T): tuple[data: ptr UncheckedArray[byte], len: int] =
|
|
## Encodes `x` into a caller-owned `c_malloc` buffer (free via `cborFreeShared`).
|
|
## Empty payloads return `(nil, 0)` without allocating.
|
|
let bytes = Cbor.encode(x)
|
|
if bytes.len == 0:
|
|
return (nil, 0)
|
|
let buf = cast[ptr UncheckedArray[byte]](c_malloc(csize_t(bytes.len)))
|
|
copyMem(buf, unsafeAddr bytes[0], bytes.len)
|
|
return (buf, bytes.len)
|
|
|
|
proc cborFreeShared*(data: var ptr UncheckedArray[byte]) =
|
|
## Frees a `cborEncodeShared` buffer and nils the pointer. Nil-safe.
|
|
if not data.isNil():
|
|
c_free(data)
|
|
data = nil
|
|
|
|
proc cborDecode*[T](data: openArray[byte], _: typedesc[T]): Result[T, string] =
|
|
## Decode `data` into a `T`, mapping any exception to `Result.err`.
|
|
try:
|
|
let v = Cbor.decode(data, T)
|
|
return ok(v)
|
|
except CatchableError as exc:
|
|
return err(exc.msg)
|
|
|
|
proc cborDecodePtr*[T](
|
|
data: ptr UncheckedArray[byte], dataLen: int, _: typedesc[T]
|
|
): Result[T, string] =
|
|
## Convenience for ptr+len buffers.
|
|
if dataLen <= 0:
|
|
return cborDecode(default(seq[byte]), T)
|
|
cborDecode(toOpenArray(data, 0, dataLen - 1), T)
|