diff --git a/faststreams/outputs.nim b/faststreams/outputs.nim index d48fce8..00e48df 100644 --- a/faststreams/outputs.nim +++ b/faststreams/outputs.nim @@ -524,23 +524,22 @@ proc tryMovingToNextPage(c: var WriteCursor) = fsAssert false, "Attempt to write past the end of a cursor" template writeToNewSpanImpl(s: OutputStream, b: byte, awaiter, writeOp, drainOp: untyped) = - # Unsafe memory outputs don't use pages at all, so if our cursor - # reached here, this is a range violation defect: - fsAssert canExtendOutput(s) - - if s.vtable == nil or s.extCursorsCount > 0: + if s.buffers == nil: + fsAssert s.vtable != nil # This is an unsafe memory output and we've reached + # the end of the buffer which is range violation defect + fsAssert s.vtable.writeOp != nil + 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 # ready to flush due to outstanding delayed writes or this is # just a memory output stream. In both cases, we just need to # allocate more memory and continue writing: addPage(s) - elif s.buffers == nil: - awaiter s.vtable.writeOp(nil, unsafeAddr b, 1) + writeByte(s.span, b) else: trackWrittenToEnd(s.buffers) awaiter drainOp(s, nil, 0) - - writeByte(s.span, b) + writeByte(s.span, b) proc write*(c: var WriteCursor, b: byte) = if atEnd(c.span): @@ -638,6 +637,10 @@ proc write*(s: OutputStream, chars: openArray[char]) = proc write*(s: MaybeAsyncOutputStream, value: string) {.inline.} = 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 = type T = type(value) static: assert supportsCopyMem(T) diff --git a/tests/test_outputs.nim b/tests/test_outputs.nim index a2fa06a..4caebc3 100644 --- a/tests/test_outputs.nim +++ b/tests/test_outputs.nim @@ -9,6 +9,9 @@ proc bytes(s: string): seq[byte] = result = newSeqOfCap[byte](s.len) 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(b: seq[byte]): 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.} = nimSeq.add bytes(val) - memStream.write val smallPageSizeStream.write val largePageSizeStream.write val - fileStream.write val unbufferedFileStream.write val - streamWritingToExistingBuffer.write val template outputText(val: auto) = @@ -154,6 +154,15 @@ suite "output stream": 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": var x = 0x42'u8