Add support for writing cstrings

This commit is contained in:
Zahary Karadjov 2021-11-04 11:54:55 +02:00
commit 1b561a9e71
2 changed files with 24 additions and 12 deletions

View file

@ -524,22 +524,21 @@ proc tryMovingToNextPage(c: var WriteCursor) =
fsAssert false, "Attempt to write past the end of a cursor" fsAssert false, "Attempt to write past the end of a cursor"
template writeToNewSpanImpl(s: OutputStream, b: byte, awaiter, writeOp, drainOp: untyped) = template writeToNewSpanImpl(s: OutputStream, b: byte, awaiter, writeOp, drainOp: untyped) =
# Unsafe memory outputs don't use pages at all, so if our cursor if s.buffers == nil:
# reached here, this is a range violation defect: fsAssert s.vtable != nil # This is an unsafe memory output and we've reached
fsAssert canExtendOutput(s) # the end of the buffer which is range violation defect
fsAssert s.vtable.writeOp != nil
if s.vtable == nil or s.extCursorsCount > 0: awaiter s.vtable.writeOp(s, unsafeAddr b, 1)
elif s.vtable == nil or s.extCursorsCount > 0:
# This is the main cursor of a stream, but we are either not # This is the main cursor of a stream, but we are either not
# ready to flush due to outstanding delayed writes or this is # ready to flush due to outstanding delayed writes or this is
# just a memory output stream. In both cases, we just need to # just a memory output stream. In both cases, we just need to
# allocate more memory and continue writing: # allocate more memory and continue writing:
addPage(s) addPage(s)
elif s.buffers == nil: writeByte(s.span, b)
awaiter s.vtable.writeOp(nil, unsafeAddr b, 1)
else: else:
trackWrittenToEnd(s.buffers) trackWrittenToEnd(s.buffers)
awaiter drainOp(s, nil, 0) awaiter drainOp(s, nil, 0)
writeByte(s.span, b) writeByte(s.span, b)
proc write*(c: var WriteCursor, b: byte) = proc write*(c: var WriteCursor, b: byte) =
@ -638,6 +637,10 @@ proc write*(s: OutputStream, chars: openArray[char]) =
proc write*(s: MaybeAsyncOutputStream, value: string) {.inline.} = proc write*(s: MaybeAsyncOutputStream, value: string) {.inline.} =
write s, value.toOpenArrayByte(0, value.len - 1) write s, value.toOpenArrayByte(0, value.len - 1)
proc write*(s: OutputStream, value: cstring) =
for c in value:
write s, c
template memCopyToBytes(value: auto): untyped = template memCopyToBytes(value: auto): untyped =
type T = type(value) type T = type(value)
static: assert supportsCopyMem(T) static: assert supportsCopyMem(T)

View file

@ -9,6 +9,9 @@ proc bytes(s: string): seq[byte] =
result = newSeqOfCap[byte](s.len) result = newSeqOfCap[byte](s.len)
for c in s: result.add byte(c) for c in s: result.add byte(c)
proc bytes(s: cstring): seq[byte] =
for c in s: result.add byte(c)
template bytes(c: char): byte = byte(c) template bytes(c: char): byte = byte(c)
template bytes(b: seq[byte]): seq[byte] = b template bytes(b: seq[byte]): seq[byte] = b
template bytes[N, T](b: array[N, T]): seq[byte] = @b template bytes[N, T](b: array[N, T]): seq[byte] = @b
@ -58,14 +61,11 @@ suite "output stream":
template output(val: auto) {.dirty.} = template output(val: auto) {.dirty.} =
nimSeq.add bytes(val) nimSeq.add bytes(val)
memStream.write val memStream.write val
smallPageSizeStream.write val smallPageSizeStream.write val
largePageSizeStream.write val largePageSizeStream.write val
fileStream.write val fileStream.write val
unbufferedFileStream.write val unbufferedFileStream.write val
streamWritingToExistingBuffer.write val streamWritingToExistingBuffer.write val
template outputText(val: auto) = template outputText(val: auto) =
@ -154,6 +154,15 @@ suite "output stream":
checkOutputsMatch() checkOutputsMatch()
test "cstrings":
for i in 1 .. 100:
output cstring("cstring sent by output ")
output cstring("")
outputText cstring("cstring sent by outputText ")
outputText cstring("")
checkOutputsMatch()
test "memcpy": test "memcpy":
var x = 0x42'u8 var x = 0x42'u8