90 lines
2.6 KiB
Nim
Raw Normal View History

2023-08-28 19:41:37 -07:00
import std/hashes
2023-09-12 20:09:55 -07:00
import ./sharedptr
2023-08-28 19:41:37 -07:00
export hashes
2023-09-12 20:09:55 -07:00
export sharedptr
2023-08-24 15:19:52 -07:00
type
2023-08-25 15:08:19 -07:00
DataBufferHolder* = object
2023-08-24 15:19:52 -07:00
buf: ptr UncheckedArray[byte]
size: int
2023-08-24 15:51:25 -07:00
2023-08-25 15:14:53 -07:00
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.
##
2023-08-24 15:51:25 -07:00
KeyBuffer* = DataBuffer
ValueBuffer* = DataBuffer
2023-08-24 16:29:25 -07:00
StringBuffer* = DataBuffer
2023-08-24 17:33:32 -07:00
CatchableErrorBuffer* = object
msg: StringBuffer
2023-08-24 15:19:52 -07:00
2023-08-29 14:58:33 -07:00
2023-08-25 15:08:19 -07:00
proc `=destroy`*(x: var DataBufferHolder) =
2023-08-24 15:19:52 -07:00
## copy pointer implementation
2023-08-25 15:08:19 -07:00
if x.buf != nil:
2023-08-28 21:32:28 -07:00
# when isMainModule or true:
2023-09-05 17:15:48 -07:00
# echo "buffer: FREE: ", repr x.buf.pointer
2023-08-25 15:08:19 -07:00
deallocShared(x.buf)
2023-08-24 15:19:52 -07:00
2023-08-25 15:08:19 -07:00
proc len*(a: DataBuffer): int = a[].size
2023-08-24 15:25:15 -07:00
2023-09-12 20:09:55 -07:00
proc isNil*(a: DataBuffer): bool = sharedptr.isNil(a)
2023-08-28 19:22:16 -07:00
2023-08-28 19:41:37 -07:00
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()
2023-08-24 15:19:52 -07:00
proc new*(tp: typedesc[DataBuffer], size: int = 0): DataBuffer =
2023-08-25 15:14:53 -07:00
## allocate new buffer with given size
2023-08-25 15:08:19 -07:00
newSharedPtr(DataBufferHolder(
buf: cast[typeof(result[].buf)](allocShared0(size)),
2023-08-24 15:19:52 -07:00
size: size,
2023-08-25 15:08:19 -07:00
))
2023-08-24 15:19:52 -07:00
proc new*[T: byte | char](tp: typedesc[DataBuffer], data: openArray[T]): DataBuffer =
## allocate new buffer and copies indata from openArray
##
result = DataBuffer.new(data.len)
if data.len() > 0:
2023-08-25 15:08:19 -07:00
copyMem(result[].buf, unsafeAddr data[0], data.len)
2023-08-24 16:29:25 -07:00
proc toSeq*[T: byte | char](a: DataBuffer, tp: typedesc[T]): seq[T] =
2023-08-25 15:14:53 -07:00
## convert buffer to a seq type using copy and either a byte or char
2023-08-24 16:29:25 -07:00
result = newSeq[T](a.len)
2023-08-25 15:08:19 -07:00
copyMem(addr result[0], unsafeAddr a[].buf[0], a.len)
2023-08-24 16:29:25 -07:00
2023-08-24 17:33:32 -07:00
proc toString*(data: DataBuffer): string =
2023-08-25 15:14:53 -07:00
## convert buffer to string type using copy
2023-08-29 17:00:11 -07:00
if data.isNil: return ""
2023-08-24 16:29:25 -07:00
result = newString(data.len())
if data.len() > 0:
2023-08-25 15:08:19 -07:00
copyMem(addr result[0], unsafeAddr data[].buf[0], data.len)
2023-08-24 17:33:32 -07:00
2023-08-25 15:14:53 -07:00
proc toCatchable*(err: CatchableErrorBuffer): ref CatchableError =
## convert back to a ref CatchableError
result = (ref CatchableError)(msg: err.msg.toString())
2023-08-24 17:33:32 -07:00
proc toBuffer*(err: ref Exception): CatchableErrorBuffer =
2023-08-25 15:14:53 -07:00
## convert exception to an object with StringBuffer
2023-08-24 17:33:32 -07:00
return CatchableErrorBuffer(
msg: StringBuffer.new(err.msg)
)
2023-08-28 18:37:14 -07:00
2023-09-05 17:08:40 -07:00
import ../key
2023-08-28 19:22:16 -07:00
import stew/results
2023-08-28 18:37:14 -07:00
proc new*(tp: typedesc[KeyBuffer], key: Key): KeyBuffer =
KeyBuffer.new(key.id())
2023-08-28 19:22:16 -07:00
proc toKey*(kb: KeyBuffer): Result[Key, ref CatchableError] =
Key.init(kb.toString())