Skip to content

Commit 7705507

Browse files
committed
std/io: reimplement EOF handling
1 parent f58c0c8 commit 7705507

22 files changed

Lines changed: 415 additions & 395 deletions

std/bufio/bufio.jule

Lines changed: 72 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ const (
4848
// Any mutation is undefined.
4949
let mut ErrInvalidUnreadByte = errors::New("bufio: invalid use of UnreadByte")
5050
let mut ErrInvalidUnreadRune = errors::New("bufio: invalid use of UnreadRune")
51-
let mut ErrBufferFull = errors::New("bufio: buffer full")
5251
let mut ErrNegativeCount = errors::New("bufio: negative count")
5352

5453
// Buffered input.
@@ -129,7 +128,7 @@ impl Reader {
129128
}
130129

131130
// Reads a new chunk into the buffer.
132-
async fn fill(mut *self): (eof: bool) {
131+
async fn fill(mut *self) {
133132
// Slide existing data to beginning.
134133
if self.r > 0 {
135134
copy(self.buf, self.buf[self.r:self.w])
@@ -146,21 +145,17 @@ impl Reader {
146145
for i > 0; i-- {
147146
n := self.rd.Read(self.buf[self.w:]).await else {
148147
self.err = error
149-
ret false
150-
}
151-
if n == io::EOF {
152-
ret true
148+
ret
153149
}
154150
if n < 0 {
155151
panic("bufio: reader returned negative count from Read")
156152
}
157153
self.w += n
158154
if n > 0 {
159-
ret false
155+
ret
160156
}
161157
}
162158
self.err = io::ErrNoProgress
163-
ret false
164159
}
165160

166161
fn readErr(mut *self): any {
@@ -187,10 +182,7 @@ impl Reader {
187182
self.lastRuneSize = -1
188183

189184
for self.w-self.r < n && self.w-self.r < len(self.buf) && self.err == nil {
190-
eof = self.fill().await // self.w-self.r < len(self.buf) => buffer is not full
191-
if eof {
192-
break
193-
}
185+
self.fill().await // self.w-self.r < len(self.buf) => buffer is not full
194186
}
195187

196188
if n > len(self.buf) {
@@ -234,10 +226,9 @@ impl Reader {
234226

235227
mut remain := n
236228
for {
237-
mut eof := false
238229
mut skip := self.Buffered()
239230
if skip == 0 {
240-
eof = self.fill().await
231+
self.fill().await
241232
skip = self.Buffered()
242233
}
243234
if skip > remain {
@@ -248,10 +239,11 @@ impl Reader {
248239
if remain == 0 {
249240
ret n
250241
}
251-
if eof {
252-
ret n - remain
253-
}
254242
if self.err != nil {
243+
discarded = n - remain
244+
if discarded > 0 {
245+
ret discarded
246+
}
255247
unsafe throw self.readErr()
256248
}
257249
}
@@ -282,9 +274,9 @@ impl Reader {
282274
if len(p) >= len(self.buf) {
283275
// Large read, empty buffer.
284276
// Read directly into p to avoid copy.
285-
n = self.rd.Read(p).await?
286-
if n == io::EOF {
287-
ret n
277+
n = self.rd.Read(p).await else {
278+
self.err = error
279+
unsafe throw self.readErr()
288280
}
289281
if n < 0 {
290282
panic("bufio: reader returned negative count from Read")
@@ -299,9 +291,9 @@ impl Reader {
299291
// Do not use self.fill, which will loop.
300292
self.r = 0
301293
self.w = 0
302-
n = self.rd.Read(self.buf).await?
303-
if n == io::EOF {
304-
ret io::EOF
294+
n = self.rd.Read(self.buf).await else {
295+
self.err = error
296+
unsafe throw self.readErr()
305297
}
306298
if n < 0 {
307299
panic("bufio: reader returned negative count from Read")
@@ -323,15 +315,11 @@ impl Reader {
323315
// If no byte is available, returns an error.
324316
async fn ReadByte(mut *self)!: (byte, int) {
325317
self.lastRuneSize = -1
326-
mut eof := false
327318
for self.r == self.w {
328-
if eof {
329-
ret 0, io::EOF
330-
}
331319
if self.err != nil {
332320
unsafe throw self.readErr()
333321
}
334-
eof = self.fill().await // buffer is empty
322+
self.fill().await // buffer is empty
335323
}
336324
c := self.buf[self.r]
337325
self.r++
@@ -365,17 +353,11 @@ impl Reader {
365353
// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
366354
async fn ReadRune(mut *self)!: (r: rune, size: int) {
367355
for self.r+utf8::UTFMax > self.w && !utf8::FullRune(self.buf[self.r:self.w]) && self.err == nil && self.w-self.r < len(self.buf) {
368-
eof := self.fill().await // self.w-self.r < len(buf) => buffer is not full
369-
if eof {
370-
break
371-
}
356+
self.fill().await // self.w-self.r < len(buf) => buffer is not full
372357
}
373358
self.lastRuneSize = -1
374359
if self.r == self.w {
375-
if self.err != nil {
376-
unsafe throw self.readErr()
377-
}
378-
ret 0, io::EOF
360+
unsafe throw self.readErr()
379361
}
380362
r, size = rune(self.buf[self.r]), 1
381363
if r >= utf8::RuneSelf {
@@ -415,7 +397,8 @@ impl Reader {
415397
// Throws error if and only if line does not end in delim because of an error.
416398
// If it encounters EOF before finding a delimiter,
417399
// it returns all the data in the buffer.
418-
async fn ReadSlice(mut *self, delim: byte)!: (line: []byte, full: bool, eof: bool) {
400+
// If there is no data in the buffer, throws io::EOF.
401+
async fn ReadSlice(mut *self, delim: byte)!: (line: []byte, full: bool) {
419402
mut s := 0 // search start index
420403
for {
421404
// Search buffer.
@@ -429,17 +412,15 @@ impl Reader {
429412

430413
// Pending error?
431414
if self.err != nil {
415+
if self.err == io::EOF && self.r != self.w {
416+
line = self.buf[self.r:self.w]
417+
self.r = self.w
418+
break
419+
}
432420
self.r = self.w
433421
unsafe throw self.readErr()
434422
}
435423

436-
// EOF?
437-
if eof {
438-
line = self.buf[self.r:self.w]
439-
self.r = self.w
440-
ret
441-
}
442-
443424
// Buffer full?
444425
if self.Buffered() >= len(self.buf) {
445426
self.r = self.w
@@ -450,7 +431,7 @@ impl Reader {
450431

451432
s = self.w - self.r // do not rescan area we scanned before
452433

453-
eof = self.fill().await // buffer is not full
434+
self.fill().await // buffer is not full
454435
}
455436

456437
// Handle last byte, if any.
@@ -478,8 +459,8 @@ impl Reader {
478459
// Calling [Reader.UnreadByte] after ReadLine will always unread the last byte read
479460
// (possibly a character belonging to the line end) even if that byte is not
480461
// part of the line returned by ReadLine.
481-
async fn ReadLine(mut *self)!: (line: []byte, isPrefix: bool, eof: bool) {
482-
line, full, eof := self.ReadSlice('\n').await?
462+
async fn ReadLine(mut *self)!: (line: []byte, isPrefix: bool) {
463+
line, full := self.ReadSlice('\n').await?
483464
if full {
484465
// Handle the case where "\r\n" straddles the buffer.
485466
if len(line) > 0 && line[len(line)-1] == '\r' {
@@ -492,7 +473,7 @@ impl Reader {
492473
self.r--
493474
line = line[:len(line)-1]
494475
}
495-
ret line, true, eof
476+
ret line, true
496477
}
497478

498479
if len(line) == 0 {
@@ -516,58 +497,58 @@ impl Reader {
516497
// `bytes::Join(append(fullBuffers, finalFragment), nil)`, which has a
517498
// length of `totalLen`. The result is structured in this way to allow callers
518499
// to minimize allocations and copies.
519-
async fn collectFragments(mut *self, delim: byte)!: (fullBuffers: [][]byte, finalFragment: []byte, totalLen: int, eof: bool) {
520-
let mut frag: []byte
500+
async fn collectFragments(mut *self, delim: byte)!: (fullBuffers: [][]byte, finalFragment: []byte, totalLen: int) {
521501
// Use ReadSlice to look for delim, accumulating full buffers.
502+
let mut full: bool
522503
for {
523-
(frag), full, (eof) := self.ReadSlice(delim).await? // unexpected error, if any
524-
if !full || eof { // got final fragment
525-
break
504+
finalFragment, full = self.ReadSlice(delim).await?
505+
if !full && self.err == nil { // got final fragment
506+
totalLen += len(finalFragment)
507+
ret
526508
}
527509
// Make a copy of the buffer.
528-
mut buf := bytes::Clone(frag)
510+
mut buf := bytes::Clone(finalFragment)
529511
fullBuffers = append(fullBuffers, buf)
530512
totalLen += len(buf)
531513
}
532-
533-
totalLen += len(frag)
534-
ret fullBuffers, frag, totalLen, eof
535514
}
536515

537516
// Reads until the first occurrence of delim in the input,
538517
// returning a slice containing the data up to and including the delimiter.
539518
// If it encounters an error before finding a delimiter, forwards it.
540519
// Throws error if and only if line does not end in delim because of an error.
541-
// Returns zero-length slice for EOF. If it encounters EOF before finding a delimiter,
520+
// If it encounters EOF before finding a delimiter,
542521
// it returns all the data in the buffer.
522+
// If there is no data in the buffer, throws io::EOF.
543523
// For simple uses, a Scanner may be more convenient.
544-
async fn ReadBytes(mut *self, delim: byte)!: (buf: []byte, eof: bool) {
545-
full, frag, mut n, eof := self.collectFragments(delim).await?
546-
if n == 0 && eof {
547-
ret
548-
}
524+
async fn ReadBytes(mut *self, delim: byte)!: (buf: []byte) {
525+
full, frag, mut n := self.collectFragments(delim).await?
549526
// Allocate new buffer to hold the full pieces and the fragment.
550527
buf = make([]byte, n)
528+
if n == 0 {
529+
ret
530+
}
551531
n = 0
552532
// Copy full pieces and fragment in.
553533
for i in full {
554534
n += copy(buf[n:], full[i])
555535
}
556536
copy(buf[n:], frag)
557-
ret buf, eof
537+
ret buf
558538
}
559539

560540
// Reads until the first occurrence of delim in the input,
561541
// returning a string containing the data up to and including the delimiter.
562542
// If it encounters an error before finding a delimiter, forwards it.
563543
// Throws error if and only if line does not end in delim because of an error.
564-
// Returns empty string for EOF. If it encounters EOF before finding a delimiter,
544+
// If it encounters EOF before finding a delimiter,
565545
// it returns all the data in the buffer.
546+
// If there is no data in the buffer, throws io::EOF.
566547
// For simple uses, a Scanner may be more convenient.
567-
async fn ReadStr(mut *self, delim: byte)!: (str, eof: bool) {
568-
full, frag, n, eof := self.collectFragments(delim).await?
569-
if n == 0 && eof {
570-
ret
548+
async fn ReadStr(mut *self, delim: byte)!: str {
549+
full, frag, n := self.collectFragments(delim).await?
550+
if n == 0 {
551+
ret ""
571552
}
572553
// Allocate new buffer to hold the full pieces and the fragment.
573554
let mut buf: strings::Builder
@@ -577,7 +558,7 @@ impl Reader {
577558
buf.Write(fb)?
578559
}
579560
buf.Write(frag)?
580-
ret buf.Str(), eof
561+
ret buf.Str()
581562
}
582563

583564
// Implements io::WriterTo.
@@ -594,18 +575,19 @@ impl Reader {
594575
self.fill().await // buffer not full
595576
}
596577

597-
mut eof := false
598578
for self.r < self.w {
599579
// self.r < self.w => buffer is not empty
600-
m := self.writeBuf(w).await?
601-
n += m
602-
if eof {
603-
break
580+
m := self.writeBuf(w).await else {
581+
if n > 0 {
582+
ret n
583+
}
584+
throw error
604585
}
605-
eof = self.fill().await // buffer is empty
586+
n += m
587+
self.fill().await // buffer is empty
606588
}
607589

608-
if self.err != nil {
590+
if self.err != nil && self.err != io::EOF {
609591
unsafe throw self.readErr()
610592
}
611593

@@ -823,17 +805,25 @@ impl Writer {
823805
unsafe throw self.err
824806
}
825807
let mut m: int
826-
Loop:
827808
for {
828809
if self.Available() == 0 {
829810
self.Flush().await?
830811
}
831812
mut nr := 0
832813
for nr < maxConsecutiveEmptyReads {
833-
m = r.Read(self.buf[self.n:]).await?
834-
if m == io::EOF {
835-
break Loop
836-
} else if m != 0 {
814+
m = r.Read(self.buf[self.n:]).await else {
815+
if error == io::EOF {
816+
// If we filled the buffer exactly, flush preemptively.
817+
if self.Available() == 0 {
818+
self.Flush().await?
819+
}
820+
if n > 0 {
821+
ret n
822+
}
823+
}
824+
throw error
825+
}
826+
if m != 0 {
837827
break
838828
}
839829
nr++
@@ -844,12 +834,6 @@ impl Writer {
844834
self.n += m
845835
n += i64(m)
846836
}
847-
if m == io::EOF {
848-
// If we filled the buffer exactly, flush preemptively.
849-
if self.Available() == 0 {
850-
self.Flush().await?
851-
}
852-
}
853837
ret n
854838
}
855839
}

0 commit comments

Comments
 (0)