Jaremy Creechley 7f921901d7
verifying types
2023-09-13 14:13:06 -07:00

94 lines
2.7 KiB
Nim

import std/hashes
import ./sharedptr
export hashes
export sharedptr
type
DataBufferHolder* = object
buf: ptr UncheckedArray[byte]
size: int
DataBuffer* = SharedPtr[DataBufferHolder] ##\
## A fixed length data buffer using a SharedPtr.
## It is thread safe even with `refc` since
## it doesn't use string or seq types internally.
##
KeyBuffer* = DataBuffer
ValueBuffer* = DataBuffer
StringBuffer* = DataBuffer
CatchableErrorBuffer* = object
msg: StringBuffer
proc `=destroy`*(x: var DataBufferHolder) =
## copy pointer implementation
if x.buf != nil:
# when isMainModule or true:
echoed "databuffer: FREE: ", repr x.buf.pointer
deallocShared(x.buf)
proc len*(a: DataBuffer): int = a[].size
proc hash*(a: DataBuffer): Hash =
a[].buf.toOpenArray(0, a[].size-1).hash()
proc `==`*(a, b: DataBuffer): bool =
if a.isNil and b.isNil: return true
elif a.isNil or b.isNil: return false
elif a[].size != b[].size: return false
elif a[].buf == b[].buf: return true
else: a.hash() == b.hash()
proc new*[D: DataBuffer](tp: typedesc[D], size: int = 0): D =
## allocate new buffer with given size
result = newSharedPtr(DataBufferHolder(
buf: cast[typeof(result[].buf)](allocShared0(size)),
size: size,
))
echoed "DataBuffer:new: ", result.unsafeRawPtr().repr,
" tp ", $(typeof(D)),
" @ ", result[].buf.pointer.repr,
" -> ", result.toString().repr
proc new*[T: byte | char; D: DataBuffer](tp: typedesc[D], data: openArray[T]): D =
## allocate new buffer and copies indata from openArray
##
result = D.new(data.len)
if data.len() > 0:
copyMem(result[].buf, unsafeAddr data[0], data.len)
proc toSeq*[T: byte | char](a: DataBuffer, tp: typedesc[T]): seq[T] =
## convert buffer to a seq type using copy and either a byte or char
result = newSeq[T](a.len)
copyMem(addr result[0], unsafeAddr a[].buf[0], a.len)
proc toString*(data: DataBuffer): string =
## convert buffer to string type using copy
if data.isNil: return "nil"
result = newString(data.len())
if data.len() > 0:
copyMem(addr result[0], unsafeAddr data[].buf[0], data.len)
proc toCatchable*(err: CatchableErrorBuffer): ref CatchableError =
## convert back to a ref CatchableError
result = (ref CatchableError)(msg: err.msg.toString())
proc toBuffer*(err: ref Exception): CatchableErrorBuffer =
## convert exception to an object with StringBuffer
return CatchableErrorBuffer(
msg: StringBuffer.new(err.msg)
)
import ../key
import stew/results
proc new*(tp: typedesc[KeyBuffer], key: Key): KeyBuffer =
result = KeyBuffer.new(key.id())
echoed "KeyBuffer:new: ", $result
proc toKey*(kb: KeyBuffer): Key =
let res = Key.init(kb.toString())
res.expect("should always be valid")