Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add io.readChars overload (simpler, less error prone) #16044

Merged
merged 4 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
- `os.FileInfo` (returned by `getFileInfo`) now contains `blockSize`,
determining preferred I/O block size for this file object.

- Added a simpler to use `io.readChars` overload.

- `repr` now doesn't insert trailing newline; previous behavior was very inconsistent,
see #16034. Use `-d:nimLegacyReprWithNewline` for previous behavior.

Expand Down Expand Up @@ -167,6 +169,7 @@ provided by the operating system.
dumping (on select signals) and notifying the parent process about the cause
of termination.


## Language changes

- `nimscript` now handles `except Exception as e`.
Expand Down
2 changes: 1 addition & 1 deletion lib/std/sha1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ proc secureHashFile*(filename: string): SecureHash =
var state = newSha1State()
var buffer = newString(BufferLength)
while true:
let length = readChars(f, buffer, 0, BufferLength)
let length = readChars(f, buffer)
if length == 0:
break
buffer.setLen(length)
Expand Down
12 changes: 8 additions & 4 deletions lib/system/io.nim
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,18 @@ proc readBytes*(f: File, a: var openArray[int8|uint8], start, len: Natural): int
## `len` (if not as many bytes are remaining), but not greater.
result = readBuffer(f, addr(a[start]), len)

proc readChars*(f: File, a: var openArray[char]): int {.tags: [ReadIOEffect], benign.} =
## reads up to `a.len` bytes into the buffer `a`. Returns
## the actual number of bytes that have been read which may be less than
## `a.len` (if not as many bytes are remaining), but not greater.
result = readBuffer(f, addr(a[0]), a.len)

proc readChars*(f: File, a: var openArray[char], start, len: Natural): int {.
tags: [ReadIOEffect], benign.} =
tags: [ReadIOEffect], benign, deprecated:
"use other `readChars` overload, possibly via: readChars(toOpenArray(buf, start, len-1))".} =
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
## the actual number of bytes that have been read which may be less than
## `len` (if not as many bytes are remaining), but not greater.
##
## **Warning:** The buffer `a` must be pre-allocated. This can be done
## using, for example, ``newString``.
if (start + len) > len(a):
raiseEIO("buffer overflow: (start+len) > length of openarray buffer")
result = readBuffer(f, addr(a[start]), len)
Expand Down
2 changes: 1 addition & 1 deletion lib/wrappers/openssl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ proc md5_File*(file: string): string {.raises: [IOError,Exception].} =
ctx: MD5_CTX

discard md5_Init(ctx)
while(let bytes = f.readChars(buf, 0, sz); bytes > 0):
while (let bytes = f.readChars(buf); bytes > 0):
discard md5_Update(ctx, buf[0].addr, cast[csize_t](bytes))

discard md5_Final(buf[0].addr, ctx)
Expand Down
37 changes: 37 additions & 0 deletions tests/stdlib/tio.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# xxx move to here other tests that belong here; io is a proper module

import std/os
from stdtest/specialpaths import buildDir

block: # readChars
let file = buildDir / "D20201118T205105.txt"
let s = "he\0l\0lo"
writeFile(file, s)
defer: removeFile(file)
let f = open(file)
defer: close(f)
let n = f.getFileInfo.blockSize
var buf = newString(n)
template fn =
let n2 = f.readChars(buf)
doAssert n2 == s.len
doAssert buf[0..<n2] == s
fn()
setFilePos(f, 0)
fn()

block:
setFilePos(f, 0)
var s2: string
let nSmall = 2
for ai in buf.mitems: ai = '\0'
var n2s: seq[int]
while true:
let n2 = f.readChars(toOpenArray(buf, 0, nSmall-1))
# xxx: maybe we could support: toOpenArray(buf, 0..nSmall)
n2s.add n2
s2.add buf[0..<n2]
if n2 == 0:
break
doAssert n2s == @[2,2,2,1,0]
doAssert s2 == s