# # # Nim's Runtime Library # (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## 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. ## ## Examples: ## ## .. code-block:: Nim ## ## import streams ## var ## ss = newStringStream("""The first line ## the second line ## the third line""") ## line = "" ## while ss.readLine(line): ## echo line ## ss.close() ## ## var fs = newFileStream("somefile.txt", fmRead) ## if not isNil(fs): ## while fs.readLine(line): ## echo line ## fs.close() include "system/inclrtl" proc newEIO(msg: string): ref IOError = new(result) result.msg = msg type Stream* = ref StreamObj StreamObj* = object of RootObj ## 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. closeImpl*: proc (s: Stream) {.nimcall, tags: [], gcsafe.} atEndImpl*: proc (s: Stream): bool {.nimcall, tags: [], gcsafe.} setPositionImpl*: proc (s: Stream, pos: int) {.nimcall, tags: [], gcsafe.} getPositionImpl*: proc (s: Stream): int {.nimcall, tags: [], gcsafe.} readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} peekDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int) {.nimcall, tags: [WriteIOEffect], gcsafe.} flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.} proc flush*(s: Stream) = ## flushes the buffers that the stream `s` might use. if not isNil(s.flushImpl): s.flushImpl(s) proc close*(s: Stream) = ## closes the stream `s`. if not isNil(s.closeImpl): s.closeImpl(s) proc close*(s, unused: Stream) {.deprecated.} = ## closes the stream `s`. s.closeImpl(s) proc atEnd*(s: Stream): bool = ## checks if more data can be read from `f`. Returns true if all data has ## been read. result = s.atEndImpl(s) proc setPosition*(s: Stream, pos: int) = ## sets the position `pos` of the stream `s`. s.setPositionImpl(s, pos) proc getPosition*(s: Stream): int = ## retrieves the current position in the stream `s`. result = s.getPositionImpl(s) proc readData*(s: Stream, buffer: pointer, bufLen: int): int = ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) proc readAll*(s: Stream): string = ## Reads all available data. const bufferSize = 1000 result = newString(bufferSize) var r = 0 while true: let readBytes = readData(s, addr(result[r]), bufferSize) if readBytes < bufferSize: setLen(result, r+readBytes) break inc r, bufferSize setLen(result, r+bufferSize) proc peekData*(s: Stream, buffer: pointer, bufLen: int): int = ##
import ./mintsets
block: # bug https://github.com/nim-lang/Nim/pull/15564#issuecomment-729878104
# related to bug #11167
test1()
test2()