☰

# std/streams

Theme:

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

This module provides a stream interface and two implementations thereof: the FileStream and the StringStream which implement the stream interface for Nim file objects (`File`) and strings.

Other modules may provide other implementations for this standard stream interface.

Warning: Due to the use of `pointer`, the `readData`, `peekData` and `writeData` interfaces are not available on the compile-time VM, and must be cast from a `ptr string` on the JS backend. However, `readDataStr` is available generally in place of `readData`.

# Basic usage

The basic flow of using this module is:

1. Open input stream
2. Read or write stream
3. Close stream

## StringStream example

    import std/streams

    var strm = newStringStream("""The first line
    the second line
    the third line""")

    var line = ""

    while strm.readLine(line):
      echo line

    # Output:
    # The first line
    # the second line
    # the third line

    strm.close()

## FileStream example

Write file stream example:

    import std/streams

    var strm = newFileStream("somefile.txt", fmWrite)
    var line = ""

    if not isNil(strm):
      strm.writeLine("The first line")
      strm.writeLine("the second line")
      strm.writeLine("the third line")
      strm.close()

    # Output (somefile.txt):
    # The first line
    # the second line
    # the third line

Read file stream example:

    import std/streams

    var strm = newFileStream("somefile.txt", fmRead)
    var line = ""

    if not isNil(strm):
      while strm.readLine(line):
        echo line
      strm.close()

    # Output:
    # The first line
    # the second line
    # the third line

# See also

- asyncstreams module
- io module for FileMode enum

# Imports

since, syncio

# Types

    FileStream = ref FileStreamObj

  A stream that encapsulates a `File`.

  Note: Not available for JS backend.

  Source Edit

    FileStreamObj = object of Stream

  A file stream object.

  Note: Not available for JS backend.

  Source Edit

    Stream = ref StreamObj

  All procedures of this module use this type. Procedures don't directly use StreamObj. Source Edit

    StreamObj = object of RootObj
      closeImpl*: proc (s: Stream) {.nimcall, ...raises: [IOError, OSError],
                                     tags: [WriteIOEffect], gcsafe.}
      atEndImpl*: proc (s: Stream): bool {.nimcall,
                                           ...raises: [Defect, IOError, OSError],
                                           tags: [], gcsafe.}
      setPositionImpl*: proc (s: Stream; pos: int) {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [], gcsafe.}
      getPositionImpl*: proc (s: Stream): int {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [], gcsafe.}
      readDataStrImpl*: proc (s: Stream; buffer: var string; slice: Slice[int]): int {.
          nimcall, ...raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
      readLineImpl*: proc (s: Stream; line: var string): bool {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
      readDataImpl*: proc (s: Stream; buffer: pointer; bufLen: int): int {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
      peekDataImpl*: proc (s: Stream; buffer: pointer; bufLen: int): int {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
      writeDataImpl*: proc (s: Stream; buffer: pointer; bufLen: int) {.nimcall,
          ...raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.}
      flushImpl*: proc (s: Stream) {.nimcall, ...raises: [Defect, IOError, OSError],
                                     tags: [WriteIOEffect], gcsafe.}

  Stream interface that supports writing or reading.

  Note:

  - That these fields here shouldn't be used directly. They are accessible so that a stream implementation can override them.
  Source Edit

    StringStream = ref StringStreamObj

  A stream that encapsulates a string. Source Edit

    StringStreamObj = object of StreamObj
      data*: string              ## A string data.
                                 ## This is updated when called `writeLine` etc.

  A string stream object. Source Edit

# Procs

    proc atEnd(s: Stream): bool {....raises: [IOError, OSError], tags: [], forbids: [].}

  Checks if more data can be read from `s`. Returns `true` if all data has been read.

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      var line = ""
      doAssert strm.atEnd() == false
      while strm.readLine(line):
        discard
      doAssert strm.atEnd() == true
      strm.close()

  Source Edit

    proc close(s: Stream) {....raises: [IOError, OSError], tags: [WriteIOEffect],
                            forbids: [].}

  Closes the stream `s`.

  See also:

  - flush proc

  Example:

      block:
        let strm = newStringStream("The first line\nthe second line\nthe third line")
        ## do something...
        strm.close()

      block:
        let strm = newFileStream("amissingfile.txt")
        # deferring works even if newFileStream fails
        defer: strm.close()
        if not isNil(strm):
          ## do something...

  Source Edit

    proc flush(s: Stream) {....raises: [IOError, OSError], tags: [WriteIOEffect],
                            forbids: [].}

  Flushes the buffers that the stream `s` might use.

  This procedure causes any unwritten data for that stream to be delivered to the host environment to be written to the file.

  See also:

  - close proc

  Example:

      from std/os import removeFile

      var strm = newFileStream("somefile.txt", fmWrite)

      doAssert "Before write:" & readFile("somefile.txt") == "Before write:"
      strm.write("hello")
      doAssert "After  write:" & readFile("somefile.txt") == "After  write:"

      strm.flush()
      doAssert "After  flush:" & readFile("somefile.txt") == "After  flush:hello"
      strm.write("HELLO")
      strm.flush()
      doAssert "After  flush:" & readFile("somefile.txt") == "After  flush:helloHELLO"

      strm.close()
      doAssert "After  close:" & readFile("somefile.txt") == "After  close:helloHELLO"
      removeFile("somefile.txt")

  Source Edit

    proc getPosition(s: Stream): int {....raises: [IOError, OSError], tags: [],
                                       forbids: [].}

  Retrieves the current position in the stream `s`.

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      doAssert strm.getPosition() == 0
      discard strm.readLine()
      doAssert strm.getPosition() == 15
      strm.close()

  Source Edit

    proc newFileStream(f: File): owned FileStream {....raises: [], tags: [],
        forbids: [].}

  Creates a new stream from the file `f`.

  Note: Not available for JS backend.

  See also:

  - newStringStream proc creates a new stream from string.
  - newFileStream proc is the same as using open proc on Examples.
  - openFileStream proc creates a file stream from the file name and the mode.

  Example:

      ## Input (somefile.txt):
      ## The first line
      ## the second line
      ## the third line
      var f: File
      if open(f, "somefile.txt", fmRead, -1):
        var strm = newFileStream(f)
        var line = ""
        while strm.readLine(line):
          echo line
        ## Output:
        ## The first line
        ## the second line
        ## the third line
        strm.close()

  Source Edit

    proc newFileStream(filename: string; mode: FileMode = fmRead; bufSize: int = -1): owned
        FileStream {....raises: [], tags: [], forbids: [].}

  Creates a new stream from the file named `filename` with the mode `mode`.

  If the file cannot be opened, `nil` is returned. See the io module for a list of available FileMode enums.

  Note:

  - This function returns nil in case of failure. To prevent unexpected behavior and ensure proper error handling, use openFileStream proc instead.
  - Not available for JS backend.

  See also:

  - newStringStream proc creates a new stream from string.
  - newFileStream proc creates a file stream from opened File.
  - openFileStream proc creates a file stream from the file name and the mode.

  Example:

      from std/os import removeFile
      var strm = newFileStream("somefile.txt", fmWrite)
      if not isNil(strm):
        strm.writeLine("The first line")
        strm.writeLine("the second line")
        strm.writeLine("the third line")
        strm.close()
        ## Output (somefile.txt)
        ## The first line
        ## the second line
        ## the third line
        removeFile("somefile.txt")

  Source Edit

    proc newStringStream(s: sink string = ""): owned StringStream {....raises: [],
        tags: [], forbids: [].}

  Creates a new stream from the string `s`.

  See also:

  - newFileStream proc creates a file stream from opened File.
  - newFileStream proc creates a file stream from the file name and the mode.
  - openFileStream proc creates a file stream from the file name and the mode.

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      doAssert strm.readLine() == "The first line"
      doAssert strm.readLine() == "the second line"
      doAssert strm.readLine() == "the third line"
      strm.close()

  Source Edit

    proc openFileStream(filename: string; mode: FileMode = fmRead; bufSize: int = -1): owned
        FileStream {....raises: [IOError], tags: [], forbids: [].}

  Creates a new stream from the file named `filename` with the mode `mode`. If the file cannot be opened, an IO exception is raised.

  Note: Not available for JS backend.

  See also:

  - newStringStream proc creates a new stream from string.
  - newFileStream proc creates a file stream from opened File.
  - newFileStream proc creates a file stream from the file name and the mode.

  Example:

      try:
        ## Input (somefile.txt):
        ## The first line
        ## the second line
        ## the third line
        var strm = openFileStream("somefile.txt")
        echo strm.readLine()
        ## Output:
        ## The first line
        strm.close()
      except:
        stderr.write getCurrentExceptionMsg()

  Source Edit

    proc peek[T](s: Stream; result: var T)

  Generic peek procedure. Peeks `result` from the stream `s`.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream("012")
      ## peekInt
      var i: int8
      strm.peek(i)
      doAssert i == 48
      ## peekData
      var buffer: array[2, char]
      strm.peek(buffer)
      doAssert buffer == ['0', '1']
      strm.close()

  Source Edit

    proc peekBool(s: Stream): bool {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Peeks a bool from the stream `s`.

  A bool is one byte long and it is `true` for every non-zero (`0000_0000`) value. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(true)
      strm.write(false)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekBool() == true
      ## not false
      doAssert strm.peekBool() == true
      doAssert strm.readBool() == true
      doAssert strm.peekBool() == false
      strm.close()

  Source Edit

    proc peekChar(s: Stream): char {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Peeks a char from the stream `s`. Raises `IOError` if an error occurred. Returns '\0' as an EOF marker.

  Example:

      var strm = newStringStream("12\n3")
      doAssert strm.peekChar() == '1'
      doAssert strm.peekChar() == '1'
      discard strm.readAll()
      doAssert strm.peekChar() == '\x00'
      strm.close()

  Source Edit

    proc peekData(s: Stream; buffer: pointer; bufLen: int): int {.
        ...raises: [IOError, OSError], tags: [ReadIOEffect], forbids: [].}

  Low level proc that reads data into an untyped `buffer` of `bufLen` size without moving stream position.

  JS note: `buffer` is treated as a `ptr string` and written to between `0..<bufLen`.

  Example:

      var strm = newStringStream("abcde")
      var buffer: array[6, char]
      doAssert strm.peekData(addr(buffer), 1024) == 5
      doAssert buffer == ['a', 'b', 'c', 'd', 'e', '\x00']
      doAssert strm.atEnd() == false
      strm.close()

  Source Edit

    proc peekFloat32(s: Stream): float32 {....raises: [IOError, OSError],
                                           tags: [ReadIOEffect], forbids: [].}

  Peeks a float32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'f32)
      strm.write(2'f32)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekFloat32() == 1'f32
      ## not 2'f32
      doAssert strm.peekFloat32() == 1'f32
      doAssert strm.readFloat32() == 1'f32
      doAssert strm.peekFloat32() == 2'f32
      strm.close()

  Source Edit

    proc peekFloat64(s: Stream): float64 {....raises: [IOError, OSError],
                                           tags: [ReadIOEffect], forbids: [].}

  Peeks a float64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'f64)
      strm.write(2'f64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekFloat64() == 1'f64
      ## not 2'f64
      doAssert strm.peekFloat64() == 1'f64
      doAssert strm.readFloat64() == 1'f64
      doAssert strm.peekFloat64() == 2'f64
      strm.close()

  Source Edit

    proc peekInt8(s: Stream): int8 {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Peeks an int8 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i8)
      strm.write(2'i8)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekInt8() == 1'i8
      ## not 2'i8
      doAssert strm.peekInt8() == 1'i8
      doAssert strm.readInt8() == 1'i8
      doAssert strm.peekInt8() == 2'i8
      strm.close()

  Source Edit

    proc peekInt16(s: Stream): int16 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Peeks an int16 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i16)
      strm.write(2'i16)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekInt16() == 1'i16
      ## not 2'i16
      doAssert strm.peekInt16() == 1'i16
      doAssert strm.readInt16() == 1'i16
      doAssert strm.peekInt16() == 2'i16
      strm.close()

  Source Edit

    proc peekInt32(s: Stream): int32 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Peeks an int32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i32)
      strm.write(2'i32)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekInt32() == 1'i32
      ## not 2'i32
      doAssert strm.peekInt32() == 1'i32
      doAssert strm.readInt32() == 1'i32
      doAssert strm.peekInt32() == 2'i32
      strm.close()

  Source Edit

    proc peekInt64(s: Stream): int64 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Peeks an int64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i64)
      strm.write(2'i64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekInt64() == 1'i64
      ## not 2'i64
      doAssert strm.peekInt64() == 1'i64
      doAssert strm.readInt64() == 1'i64
      doAssert strm.peekInt64() == 2'i64
      strm.close()

  Source Edit

    proc peekLine(s: Stream): string {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Peeks a line from a stream `s`. Raises `IOError` if an error occurred.

  Note: This is not very efficient.

  See also:

  - readLine(Stream) proc
  - readLine(Stream, string) proc
  - peekLine(Stream, string) proc

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      doAssert strm.peekLine() == "The first line"
      ## not "the second line"
      doAssert strm.peekLine() == "The first line"
      doAssert strm.readLine() == "The first line"
      doAssert strm.peekLine() == "the second line"
      strm.close()

  Source Edit

    proc peekLine(s: Stream; line: var string): bool {....raises: [IOError, OSError],
        tags: [ReadIOEffect], forbids: [].}

  Peeks a line of text from the stream `s` into `line`. `line` must not be `nil`! May throw an IO exception.

  A line of text may be delimited by `CR`, `LF` or `CRLF`. The newline character(s) are not part of the returned string. Returns `false` if the end of the file has been reached, `true` otherwise. If `false` is returned `line` contains no new data.

  See also:

  - readLine(Stream) proc
  - readLine(Stream, string) proc
  - peekLine(Stream) proc

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      var line = ""
      doAssert strm.peekLine(line) == true
      doAssert line == "The first line"
      doAssert strm.peekLine(line) == true
      ## not "the second line"
      doAssert line == "The first line"
      doAssert strm.readLine(line) == true
      doAssert line == "The first line"
      doAssert strm.peekLine(line) == true
      doAssert line == "the second line"
      strm.close()

  Source Edit

    proc peekStr(s: Stream; length: int): string {....raises: [IOError, OSError],
        tags: [ReadIOEffect], forbids: [].}

  Peeks a string of length `length` from the stream `s`. Raises `IOError` if an error occurred.

  Example:

      var strm = newStringStream("abcde")
      doAssert strm.peekStr(2) == "ab"
      ## not "cd
      doAssert strm.peekStr(2) == "ab"
      doAssert strm.readStr(2) == "ab"
      doAssert strm.peekStr(2) == "cd"
      strm.close()

  Source Edit

    proc peekStr(s: Stream; length: int; str: var string) {.
        ...raises: [IOError, OSError], tags: [ReadIOEffect], forbids: [].}

  Peeks a string of length `length` from the stream `s`. Raises `IOError` if an error occurred. Source Edit

    proc peekUint8(s: Stream): uint8 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Peeks an uint8 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u8)
      strm.write(2'u8)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekUint8() == 1'u8
      ## not 2'u8
      doAssert strm.peekUint8() == 1'u8
      doAssert strm.readUint8() == 1'u8
      doAssert strm.peekUint8() == 2'u8
      strm.close()

  Source Edit

    proc peekUint16(s: Stream): uint16 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Peeks an uint16 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u16)
      strm.write(2'u16)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekUint16() == 1'u16
      ## not 2'u16
      doAssert strm.peekUint16() == 1'u16
      doAssert strm.readUint16() == 1'u16
      doAssert strm.peekUint16() == 2'u16
      strm.close()

  Source Edit

    proc peekUint32(s: Stream): uint32 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Peeks an uint32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u32)
      strm.write(2'u32)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekUint32() == 1'u32
      ## not 2'u32
      doAssert strm.peekUint32() == 1'u32
      doAssert strm.readUint32() == 1'u32
      doAssert strm.peekUint32() == 2'u32
      strm.close()

  Source Edit

    proc peekUint64(s: Stream): uint64 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Peeks an uint64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use peekStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u64)
      strm.write(2'u64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.peekUint64() == 1'u64
      ## not 2'u64
      doAssert strm.peekUint64() == 1'u64
      doAssert strm.readUint64() == 1'u64
      doAssert strm.peekUint64() == 2'u64
      strm.close()

  Source Edit

    proc read[T](s: Stream; result: var T)

  Generic read procedure. Reads `result` from the stream `s`.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream("012")
      ## readInt
      var i: int8
      strm.read(i)
      doAssert i == 48
      ## readData
      var buffer: array[2, char]
      strm.read(buffer)
      doAssert buffer == ['1', '2']
      strm.close()

  Source Edit

    proc readAll(s: Stream): string {....raises: [IOError, OSError],
                                      tags: [ReadIOEffect], forbids: [].}

  Reads all available data.

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      doAssert strm.readAll() == "The first line\nthe second line\nthe third line"
      doAssert strm.atEnd() == true
      strm.close()

  Source Edit

    proc readBool(s: Stream): bool {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Reads a bool from the stream `s`.

  A bool is one byte long and it is `true` for every non-zero (`0000_0000`) value. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(true)
      strm.write(false)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readBool() == true
      doAssert strm.readBool() == false
      doAssertRaises(IOError): discard strm.readBool()
      strm.close()

  Source Edit

    proc readChar(s: Stream): char {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Reads a char from the stream `s`.

  Raises `IOError` if an error occurred. Returns '\0' as an EOF marker.

  Example:

      var strm = newStringStream("12\n3")
      doAssert strm.readChar() == '1'
      doAssert strm.readChar() == '2'
      doAssert strm.readChar() == '\n'
      doAssert strm.readChar() == '3'
      doAssert strm.readChar() == '\x00'
      strm.close()

  Source Edit

    proc readData(s: Stream; buffer: pointer; bufLen: int): int {.
        ...raises: [IOError, OSError], tags: [ReadIOEffect], forbids: [].}

  Low level proc that reads data into an untyped `buffer` of `bufLen` size.

  JS note: `buffer` is treated as a `ptr string` and written to between `0..<bufLen`.

  Example:

      var strm = newStringStream("abcde")
      var buffer: array[6, char]
      doAssert strm.readData(addr(buffer), 1024) == 5
      doAssert buffer == ['a', 'b', 'c', 'd', 'e', '\x00']
      doAssert strm.atEnd() == true
      strm.close()

  Source Edit

    proc readDataStr(s: Stream; buffer: var string; slice: Slice[int]): int {.
        ...raises: [IOError, OSError], tags: [ReadIOEffect], forbids: [].}

  Low level proc that reads data into a string `buffer` at `slice`.

  Example:

      var strm = newStringStream("abcde")
      var buffer = "12345"
      doAssert strm.readDataStr(buffer, 0..3) == 4
      doAssert buffer == "abcd5"
      strm.close()

  Source Edit

    proc readFloat32(s: Stream): float32 {....raises: [IOError, OSError],
                                           tags: [ReadIOEffect], forbids: [].}

  Reads a float32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'f32)
      strm.write(2'f32)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readFloat32() == 1'f32
      doAssert strm.readFloat32() == 2'f32
      doAssertRaises(IOError): discard strm.readFloat32()
      strm.close()

  Source Edit

    proc readFloat64(s: Stream): float64 {....raises: [IOError, OSError],
                                           tags: [ReadIOEffect], forbids: [].}

  Reads a float64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'f64)
      strm.write(2'f64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readFloat64() == 1'f64
      doAssert strm.readFloat64() == 2'f64
      doAssertRaises(IOError): discard strm.readFloat64()
      strm.close()

  Source Edit

    proc readInt8(s: Stream): int8 {....raises: [IOError, OSError],
                                     tags: [ReadIOEffect], forbids: [].}

  Reads an int8 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i8)
      strm.write(2'i8)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readInt8() == 1'i8
      doAssert strm.readInt8() == 2'i8
      doAssertRaises(IOError): discard strm.readInt8()
      strm.close()

  Source Edit

    proc readInt16(s: Stream): int16 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Reads an int16 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i16)
      strm.write(2'i16)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readInt16() == 1'i16
      doAssert strm.readInt16() == 2'i16
      doAssertRaises(IOError): discard strm.readInt16()
      strm.close()

  Source Edit

    proc readInt32(s: Stream): int32 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Reads an int32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i32)
      strm.write(2'i32)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readInt32() == 1'i32
      doAssert strm.readInt32() == 2'i32
      doAssertRaises(IOError): discard strm.readInt32()
      strm.close()

  Source Edit

    proc readInt64(s: Stream): int64 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Reads an int64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'i64)
      strm.write(2'i64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readInt64() == 1'i64
      doAssert strm.readInt64() == 2'i64
      doAssertRaises(IOError): discard strm.readInt64()
      strm.close()

  Source Edit

    proc readLine(s: Stream): string {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Reads a line from a stream `s`. Raises `IOError` if an error occurred.

  Note: This is not very efficient.

  See also:

  - readLine(Stream, string) proc
  - peekLine(Stream) proc
  - peekLine(Stream, string) proc

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      doAssert strm.readLine() == "The first line"
      doAssert strm.readLine() == "the second line"
      doAssert strm.readLine() == "the third line"
      doAssertRaises(IOError): discard strm.readLine()
      strm.close()

  Source Edit

    proc readLine(s: Stream; line: var string): bool {....raises: [IOError, OSError],
        tags: [ReadIOEffect], forbids: [].}

  Reads a line of text from the stream `s` into `line`. `line` must not be `nil`! May throw an IO exception.

  A line of text may be delimited by `LF` or `CRLF`. The newline character(s) are not part of the returned string. Returns `false` if the end of the file has been reached, `true` otherwise. If `false` is returned `line` contains no new data.

  See also:

  - readLine(Stream) proc
  - peekLine(Stream) proc
  - peekLine(Stream, string) proc

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      var line = ""
      doAssert strm.readLine(line) == true
      doAssert line == "The first line"
      doAssert strm.readLine(line) == true
      doAssert line == "the second line"
      doAssert strm.readLine(line) == true
      doAssert line == "the third line"
      doAssert strm.readLine(line) == false
      doAssert line == ""
      strm.close()

  Source Edit

    proc readStr(s: Stream; length: int): string {....raises: [IOError, OSError],
        tags: [ReadIOEffect], forbids: [].}

  Reads a string of length `length` from the stream `s`. Raises `IOError` if an error occurred.

  Example:

      var strm = newStringStream("abcde")
      doAssert strm.readStr(2) == "ab"
      doAssert strm.readStr(2) == "cd"
      doAssert strm.readStr(2) == "e"
      doAssert strm.readStr(2) == ""
      strm.close()

  Source Edit

    proc readStr(s: Stream; length: int; str: var string) {.
        ...raises: [IOError, OSError], tags: [ReadIOEffect], forbids: [].}

  Reads a string of length `length` from the stream `s`. Raises `IOError` if an error occurred. Source Edit

    proc readUint8(s: Stream): uint8 {....raises: [IOError, OSError],
                                       tags: [ReadIOEffect], forbids: [].}

  Reads an uint8 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u8)
      strm.write(2'u8)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readUint8() == 1'u8
      doAssert strm.readUint8() == 2'u8
      doAssertRaises(IOError): discard strm.readUint8()
      strm.close()

  Source Edit

    proc readUint16(s: Stream): uint16 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Reads an uint16 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u16)
      strm.write(2'u16)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readUint16() == 1'u16
      doAssert strm.readUint16() == 2'u16
      doAssertRaises(IOError): discard strm.readUint16()
      strm.close()

  Source Edit

    proc readUint32(s: Stream): uint32 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Reads an uint32 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u32)
      strm.write(2'u32)
      strm.flush()
      strm.setPosition(0)

      ## get data
      doAssert strm.readUint32() == 1'u32
      doAssert strm.readUint32() == 2'u32
      doAssertRaises(IOError): discard strm.readUint32()
      strm.close()

  Source Edit

    proc readUint64(s: Stream): uint64 {....raises: [IOError, OSError],
                                         tags: [ReadIOEffect], forbids: [].}

  Reads an uint64 from the stream `s`. Raises `IOError` if an error occurred.

  Note: Not available for JS backend. Use readStr for now.

  Example:

      var strm = newStringStream()
      ## setup for reading data
      strm.write(1'u64)
      strm.write(2'u64)
      strm.flush()
      strm.setPosition(0)
      ## get data
      doAssert strm.readUint64() == 1'u64
      doAssert strm.readUint64() == 2'u64
      doAssertRaises(IOError): discard strm.readUint64()
      strm.close()

  Source Edit

    proc setPosition(s: Stream; pos: int) {....raises: [IOError, OSError], tags: [],
                                            forbids: [].}

  Sets the position `pos` of the stream `s`.

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      strm.setPosition(4)
      doAssert strm.readLine() == "first line"
      strm.setPosition(0)
      doAssert strm.readLine() == "The first line"
      strm.close()

  Source Edit

    proc write(s: Stream; args: varargs[string, `$`]) {....raises: [IOError, OSError],
        tags: [WriteIOEffect], forbids: [].}

  Writes one or more strings to the the stream. No length fields or terminating zeros are written.

  Example:

      var strm = newStringStream("")
      strm.write(1, 2, 3, 4)
      strm.setPosition(0)
      doAssert strm.readLine() == "1234"
      strm.close()

  Source Edit

    proc write(s: Stream; x: string) {....raises: [IOError, OSError],
                                       tags: [WriteIOEffect], forbids: [].}

  Writes the string `x` to the stream `s`. No length field or terminating zero is written.

  Example:

      var strm = newStringStream("")
      strm.write("THE FIRST LINE")
      strm.setPosition(0)
      doAssert strm.readLine() == "THE FIRST LINE"
      strm.close()

  Source Edit

    proc write[T](s: Stream; x: T)

  Generic write procedure. Writes `x` to the stream `s`. Implementation:

  Note: Not available for JS backend. Use write(Stream, string) for now.

      s.writeData(s, unsafeAddr(x), sizeof(x))

  Example:

      var strm = newStringStream("")
      strm.write("abcde")
      strm.setPosition(0)
      doAssert strm.readAll() == "abcde"
      strm.close()

  Source Edit

    proc writeData(s: Stream; buffer: pointer; bufLen: int) {.
        ...raises: [IOError, OSError], tags: [WriteIOEffect], forbids: [].}

  Low level proc that writes an untyped `buffer` of `bufLen` size to the stream `s`.

  JS note: `buffer` is treated as a `ptr string` and read between `0..<bufLen`.

  Example:

      ## writeData
      var strm = newStringStream("")
      var buffer = ['a', 'b', 'c', 'd', 'e']
      strm.writeData(addr(buffer), sizeof(buffer))
      doAssert strm.atEnd() == true
      ## readData
      strm.setPosition(0)
      var buffer2: array[6, char]
      doAssert strm.readData(addr(buffer2), sizeof(buffer2)) == 5
      doAssert buffer2 == ['a', 'b', 'c', 'd', 'e', '\x00']
      strm.close()

  Source Edit

    proc writeLine(s: Stream; args: varargs[string, `$`]) {.
        ...raises: [IOError, OSError], tags: [WriteIOEffect], forbids: [].}

  Writes one or more strings to the the stream `s` followed by a new line. No length field or terminating zero is written.

  Example:

      var strm = newStringStream("")
      strm.writeLine(1, 2)
      strm.writeLine(3, 4)
      strm.setPosition(0)
      doAssert strm.readAll() == "12\n34\n"
      strm.close()

  Source Edit

# Iterators

    iterator lines(s: Stream): string {....raises: [IOError, OSError],
                                        tags: [ReadIOEffect], forbids: [].}

  Iterates over every line in the stream. The iteration is based on `readLine`.

  See also:

  - readLine(Stream) proc
  - readLine(Stream, string) proc

  Example:

      var strm = newStringStream("The first line\nthe second line\nthe third line")
      var lines: seq[string]
      for line in strm.lines():
        lines.add line
      doAssert lines == @["The first line", "the second line", "the third line"]
      strm.close()

  Source Edit

# Exports

FileMode