ggstd/bufio/bufio.rs
1// Copyright 2023 The rust-ggstd authors. All rights reserved.
2// Copyright 2009 The Go Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6//! Package bufio implements buffered I/O. It wraps an std::io::Read or std::io::Write
7//! object, creating another object (Reader or Writer) that also implements
8//! the interface but provides buffering and some help for textual I/O.
9
10use crate::compat;
11use crate::errors;
12use crate::io as ggio;
13use std::io::Write;
14
15// import (
16// "bytes"
17// "errors"
18// "io"
19// "strings"
20// "unicode/utf8"
21// )
22
23pub(crate) const DEFAULT_BUF_SIZE: usize = 4096;
24
25// ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
26// ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
27static ERR_BUFFER_FULL: errors::ErrorStaticString = errors::new_static("bufio: buffer full");
28// static ERR_NEGATIVE_COUNT: errors::ErrorStaticString = errors::new_static("bufio: negative count");
29
30// buffered input.
31
32/// Reader implements buffering for an std::io::Read object.
33///
34/// Consider using native Rust std::io::BufReader.
35pub struct Reader<'a, Input: std::io::Read> {
36 buf: Vec<u8>,
37 rd: &'a mut Input, // reader provided by the client
38 r: usize, // buf read positions
39 w: usize, // buf write positions
40 err: Option<Box<dyn std::error::Error>>,
41 last_byte: isize, // last byte read for UnreadByte; -1 means invalid
42 last_rune_size: isize, // size of last rune read for UnreadRune; -1 means invalid
43}
44
45const MIN_READ_BUFFER_SIZE: usize = 16;
46pub(super) const MAX_CONSECUTIVE_EMPTY_READS: usize = 100;
47
48impl<'a, Input: std::io::Read> Reader<'a, Input> {
49 /// new creates a reader with the default size buffer
50 pub fn new(r: &'a mut Input) -> Self {
51 Self::new_size(r, DEFAULT_BUF_SIZE)
52 }
53
54 /// new_size returns a new Reader whose buffer has at least the specified
55 /// size.
56 pub fn new_size(r: &'a mut Input, size: usize) -> Self {
57 // Is it already a Reader?
58 // b, ok := rd.(*Reader)
59 // if ok && b.buf.len() >= size {
60 // return b
61 // }
62 let size = size.max(MIN_READ_BUFFER_SIZE);
63 Reader {
64 buf: vec![0; size],
65 rd: r,
66 r: 0,
67 w: 0,
68 err: None,
69 last_byte: -1,
70 last_rune_size: -1,
71 }
72 }
73
74 /// size returns the size of the underlying buffer in bytes.
75 pub fn size(&mut self) -> usize {
76 self.buf.len()
77 }
78
79 /// reset discards any buffered data, resets all state, and switches
80 /// the buffered reader to read from r.
81 pub fn reset(&mut self, r: &'a mut Input) {
82 self.buf.resize(DEFAULT_BUF_SIZE, 0);
83 self.rd = r;
84 self.r = 0;
85 self.w = 0;
86 self.last_byte = -1;
87 self.last_rune_size = -1;
88 }
89
90 // var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
91
92 /// fill reads a new chunk into the buffer.
93 fn fill(&mut self) {
94 // Slide existing data to beginning.
95 if self.r > 0 {
96 self.buf.copy_within(self.r..self.w, 0);
97 self.w -= self.r;
98 self.r = 0
99 }
100
101 if self.w >= self.buf.len() {
102 panic!("bufio: tried to fill full buffer");
103 }
104
105 // Read new data: try a limited number of times.
106 for _i in 0..MAX_CONSECUTIVE_EMPTY_READS {
107 // let (n, err) = self.rd.read(&mut self.buf[self.w..]);
108 let res = self.rd.read(&mut self.buf[self.w..]);
109 match res {
110 Err(err) => {
111 self.err = Some(Box::new(err));
112 return;
113 }
114 Ok(n) => {
115 self.w += n;
116 if n > 0 {
117 return;
118 }
119 }
120 }
121 }
122 self.err = Some(Box::new(ggio::err_no_progress()));
123 }
124
125 fn read_err(&mut self) -> Option<Box<dyn std::error::Error>> {
126 self.err.take()
127 }
128
129 /// peek returns the next n bytes without advancing the reader. The bytes stop
130 /// being valid at the next read call. If peek returns fewer than n bytes, it
131 /// also returns an error explaining why the read is short. The error is
132 /// ERR_BUFFER_FULL if n is larger than b's buffer size.
133 ///
134 /// Calling peek prevents a UnreadByte or UnreadRune call from succeeding
135 /// until the next read operation.
136 pub fn peek(&mut self, n: usize) -> (&[u8], Option<Box<dyn std::error::Error>>) {
137 self.last_byte = -1;
138 self.last_rune_size = -1;
139
140 while self.w - self.r < n && self.w - self.r < self.buf.len() && self.err.is_none() {
141 self.fill(); // self.w-self.r < self.buf.len() => buffer is not full
142 }
143
144 if n > self.buf.len() {
145 return (&self.buf[self.r..self.w], Some(Box::new(ERR_BUFFER_FULL)));
146 }
147
148 // 0 <= n <= self.buf.len()
149 let mut err = None;
150 let avail = self.w - self.r;
151 let mut n = n;
152 if avail < n {
153 // not enough data in buffer
154 n = avail;
155 err = self.read_err();
156 if err.is_none() {
157 err = Some(Box::new(ERR_BUFFER_FULL));
158 }
159 }
160 (&self.buf[self.r..self.r + n], err)
161 }
162
163 // // Discard skips the next n bytes, returning the number of bytes discarded.
164 // //
165 // // If Discard skips fewer than n bytes, it also returns an error.
166 // // If 0 <= n <= b.buffered(), Discard is guaranteed to succeed without
167 // // reading from the underlying std::io::Read.
168 // fn Discard(&mut self, n isize) (discarded isize, err error) {
169 // if n < 0 {
170 // return 0, ERR_NEGATIVE_COUNT
171 // }
172 // if n == 0 {
173 // return
174 // }
175
176 // b.lastByte = -1
177 // b.lastRuneSize = -1
178
179 // remain := n
180 // for {
181 // skip := b.buffered()
182 // if skip == 0 {
183 // b.fill()
184 // skip = b.buffered()
185 // }
186 // if skip > remain {
187 // skip = remain
188 // }
189 // b.r += skip
190 // remain -= skip
191 // if remain == 0 {
192 // return n, nil
193 // }
194 // if b.err.is_some() {
195 // return n - remain, b.read_err()
196 // }
197 // }
198 // }
199
200 // // Read reads data into p.
201 // // It returns the number of bytes read into p.
202 // // The bytes are taken from at most one Read on the underlying Reader,
203 // // hence n may be less than p.len().
204 // // To read exactly p.len() bytes, use io.ReadFull(b, p).
205 // // If the underlying Reader can return a non-zero count with io.EOF,
206 // // then this Read method can do so as well; see the [std::io::Read] docs.
207 // fn Read(&mut self, p [u8]) (n isize, err error) {
208 // n = p.len()
209 // if n == 0 {
210 // if b.buffered() > 0 {
211 // return 0, nil
212 // }
213 // return 0, b.read_err()
214 // }
215 // if b.r == b.w {
216 // if b.err.is_some() {
217 // return 0, b.read_err()
218 // }
219 // if p.len() >= b.buf.len() {
220 // // Large read, empty buffer.
221 // // Read directly into p to avoid copy.
222 // n, b.err = b.rd.Read(p)
223 // if n < 0 {
224 // panic(errNegativeRead)
225 // }
226 // if n > 0 {
227 // b.lastByte = isize(p[n-1])
228 // b.lastRuneSize = -1
229 // }
230 // return n, b.read_err()
231 // }
232 // // One read.
233 // // Do not use b.fill, which will loop.
234 // b.r = 0
235 // b.w = 0
236 // n, b.err = b.rd.Read(b.buf)
237 // if n < 0 {
238 // panic(errNegativeRead)
239 // }
240 // if n == 0 {
241 // return 0, b.read_err()
242 // }
243 // b.w += n
244 // }
245
246 // // copy as much as we can
247 // // Note: if the slice panics here, it is probably because
248 // // the underlying reader returned a bad count. See issue 49795.
249 // n = copy(p, b.buf[b.r:b.w])
250 // b.r += n
251 // b.lastByte = isize(b.buf[b.r-1])
252 // b.lastRuneSize = -1
253 // return n, nil
254 // }
255
256 // // ReadByte reads and returns a single byte.
257 // // If no byte is available, returns an error.
258 // fn ReadByte (&mut self) (byte, error) {
259 // b.lastRuneSize = -1
260 // for b.r == b.w {
261 // if b.err.is_some() {
262 // return 0, b.read_err()
263 // }
264 // b.fill() // buffer is empty
265 // }
266 // c := b.buf[b.r]
267 // b.r++
268 // b.lastByte = isize(c)
269 // return c, nil
270 // }
271
272 // // UnreadByte unreads the last byte. Only the most recently read byte can be unread.
273 // //
274 // // UnreadByte returns an error if the most recent method called on the
275 // // Reader was not a read operation. Notably, peek, Discard, and WriteTo are not
276 // // considered read operations.
277 // fn UnreadByte (&mut self) error {
278 // if b.lastByte < 0 || b.r == 0 && b.w > 0 {
279 // return ErrInvalidUnreadByte
280 // }
281 // // b.r > 0 || b.w == 0
282 // if b.r > 0 {
283 // b.r--
284 // } else {
285 // // b.r == 0 && b.w == 0
286 // b.w = 1
287 // }
288 // b.buf[b.r] = byte(b.lastByte)
289 // b.lastByte = -1
290 // b.lastRuneSize = -1
291 // return nil
292 // }
293
294 // // ReadRune reads a single UTF-8 encoded Unicode character and returns the
295 // // rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
296 // // and returns unicode:REPLACEMENT_CHAR (U+FFFD) with a size of 1.
297 // fn ReadRune (&mut self) (r rune, size isize, err error) {
298 // for b.r+utf8.UTFMAX > b.w && !utf8.full_rune(b.buf[b.r:b.w]) && b.err.is_none() && b.w-b.r < b.buf.len() {
299 // b.fill() // b.w-b.r < len(buf) => buffer is not full
300 // }
301 // b.lastRuneSize = -1
302 // if b.r == b.w {
303 // return 0, 0, b.read_err()
304 // }
305 // r, size = rune(b.buf[b.r]), 1
306 // if r >= utf8::RUNE_SELF {
307 // r, size = utf8.decode_rune(b.buf[b.r:b.w])
308 // }
309 // b.r += size
310 // b.lastByte = isize(b.buf[b.r-1])
311 // b.lastRuneSize = size
312 // return r, size, nil
313 // }
314
315 // // UnreadRune unreads the last rune. If the most recent method called on
316 // // the Reader was not a ReadRune, UnreadRune returns an error. (In this
317 // // regard it is stricter than UnreadByte, which will unread the last byte
318 // // from any read operation.)
319 // fn UnreadRune (&mut self) error {
320 // if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
321 // return ErrInvalidUnreadRune
322 // }
323 // b.r -= b.lastRuneSize
324 // b.lastByte = -1
325 // b.lastRuneSize = -1
326 // return nil
327 // }
328
329 /// buffered returns the number of bytes that can be read from the current buffer.
330 pub fn buffered(&mut self) -> usize {
331 self.w - self.r
332 }
333
334 // // ReadSlice reads until the first occurrence of delim in the input,
335 // // returning a slice pointing at the bytes in the buffer.
336 // // The bytes stop being valid at the next read.
337 // // If ReadSlice encounters an error before finding a delimiter,
338 // // it returns all the data in the buffer and the error itself (often io.EOF).
339 // // ReadSlice fails with error ERR_BUFFER_FULL if the buffer fills without a delim.
340 // // Because the data returned from ReadSlice will be overwritten
341 // // by the next I/O operation, most clients should use
342 // // ReadBytes or ReadString instead.
343 // // ReadSlice returns err.is_some() if and only if line does not end in delim.
344 // fn ReadSlice(&mut self, delim byte) (line [u8], err error) {
345 // s := 0 // search start index
346 // for {
347 // // Search buffer.
348 // if i := bytes.index_byte(b.buf[b.r+s:b.w], delim); i >= 0 {
349 // i += s
350 // line = b.buf[b.r : b.r+i+1]
351 // b.r += i + 1
352 // break
353 // }
354
355 // // Pending error?
356 // if b.err.is_some() {
357 // line = b.buf[b.r:b.w]
358 // b.r = b.w
359 // err = b.read_err()
360 // break
361 // }
362
363 // // Buffer full?
364 // if b.buffered() >= b.buf.len() {
365 // b.r = b.w
366 // line = b.buf
367 // err = ERR_BUFFER_FULL
368 // break
369 // }
370
371 // s = b.w - b.r // do not rescan area we scanned before
372
373 // b.fill() // buffer is not full
374 // }
375
376 // // Handle last byte, if any.
377 // if i := len(line) - 1; i >= 0 {
378 // b.lastByte = isize(line[i])
379 // b.lastRuneSize = -1
380 // }
381
382 // return
383 // }
384
385 // // ReadLine is a low-level line-reading primitive. Most callers should use
386 // // ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
387 // //
388 // // ReadLine tries to return a single line, not including the end-of-line bytes.
389 // // If the line was too long for the buffer then isPrefix is set and the
390 // // beginning of the line is returned. The rest of the line will be returned
391 // // from future calls. isPrefix will be false when returning the last fragment
392 // // of the line. The returned buffer is only valid until the next call to
393 // // ReadLine. ReadLine either returns a non-nil line or it returns an error,
394 // // never both.
395 // //
396 // // The text returned from ReadLine does not include the line end ("\r\n" or "\n").
397 // // No indication or error is given if the input ends without a final line end.
398 // // Calling UnreadByte after ReadLine will always unread the last byte read
399 // // (possibly a character belonging to the line end) even if that byte is not
400 // // part of the line returned by ReadLine.
401 // fn ReadLine (&mut self) (line [u8], isPrefix bool, err error) {
402 // line, err = b.ReadSlice('\n')
403 // if err == ERR_BUFFER_FULL {
404 // // Handle the case where "\r\n" straddles the buffer.
405 // if len(line) > 0 && line[len(line)-1] == '\r' {
406 // // Put the '\r' back on buf and drop it from line.
407 // // Let the next call to ReadLine check for "\r\n".
408 // if b.r == 0 {
409 // // should be unreachable
410 // panic("bufio: tried to rewind past start of buffer")
411 // }
412 // b.r--
413 // line = line[..len(line)-1]
414 // }
415 // return line, true, nil
416 // }
417
418 // if len(line) == 0 {
419 // if err.is_some() {
420 // line = nil
421 // }
422 // return
423 // }
424 // err = nil
425
426 // if line[len(line)-1] == '\n' {
427 // drop := 1
428 // if len(line) > 1 && line[len(line)-2] == '\r' {
429 // drop = 2
430 // }
431 // line = line[..len(line)-drop]
432 // }
433 // return
434 // }
435
436 // // collectFragments reads until the first occurrence of delim in the input. It
437 // // returns (slice of full buffers, remaining bytes before delim, total number
438 // // of bytes in the combined first two elements, error).
439 // // The complete result is equal to
440 // // `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a
441 // // length of `totalLen`. The result is structured in this way to allow callers
442 // // to minimize allocations and copies.
443 // fn collectFragments(&mut self, delim byte) (fullBuffers [][u8], finalFragment [u8], totalLen isize, err error) {
444 // var frag [u8]
445 // // Use ReadSlice to look for delim, accumulating full buffers.
446 // for {
447 // var e error
448 // frag, e = b.ReadSlice(delim)
449 // if e == nil { // got final fragment
450 // break
451 // }
452 // if e != ERR_BUFFER_FULL { // unexpected error
453 // err = e
454 // break
455 // }
456
457 // // Make a copy of the buffer.
458 // buf := bytes.Clone(frag)
459 // fullBuffers = append(fullBuffers, buf)
460 // totalLen += len(buf)
461 // }
462
463 // totalLen += len(frag)
464 // return fullBuffers, frag, totalLen, err
465 // }
466
467 // // ReadBytes reads until the first occurrence of delim in the input,
468 // // returning a slice containing the data up to and including the delimiter.
469 // // If ReadBytes encounters an error before finding a delimiter,
470 // // it returns the data read before the error and the error itself (often io.EOF).
471 // // ReadBytes returns err.is_some() if and only if the returned data does not end in
472 // // delim.
473 // // For simple uses, a Scanner may be more convenient.
474 // fn ReadBytes(&mut self, delim byte) ([u8], error) {
475 // full, frag, n, err := b.collectFragments(delim)
476 // // Allocate new buffer to hold the full pieces and the fragment.
477 // buf := make([u8], n)
478 // n = 0
479 // // Copy full pieces and fragment in.
480 // for i := range full {
481 // n += copy(buf[n..], full[i])
482 // }
483 // copy(buf[n..], frag)
484 // return buf, err
485 // }
486
487 // // ReadString reads until the first occurrence of delim in the input,
488 // // returning a string containing the data up to and including the delimiter.
489 // // If ReadString encounters an error before finding a delimiter,
490 // // it returns the data read before the error and the error itself (often io.EOF).
491 // // ReadString returns err.is_some() if and only if the returned data does not end in
492 // // delim.
493 // // For simple uses, a Scanner may be more convenient.
494 // fn ReadString(&mut self, delim byte) (string, error) {
495 // full, frag, n, err := b.collectFragments(delim)
496 // // Allocate new buffer to hold the full pieces and the fragment.
497 // var buf strings.Builder
498 // buf.Grow(n)
499 // // Copy full pieces and fragment in.
500 // for _, fb := range full {
501 // buf.Write(fb)
502 // }
503 // buf.Write(frag)
504 // return buf.String(), err
505 // }
506
507 // // WriteTo implements io.WriterTo.
508 // // This may make multiple calls to the Read method of the underlying Reader.
509 // // If the underlying reader supports the WriteTo method,
510 // // this calls the underlying WriteTo without buffering.
511 // fn WriteTo(&mut self, w std::io::Write) (n int64, err error) {
512 // b.lastByte = -1
513 // b.lastRuneSize = -1
514
515 // n, err = b.writeBuf(w)
516 // if err.is_some() {
517 // return
518 // }
519
520 // if r, ok := b.rd.(io.WriterTo); ok {
521 // m, err := r.WriteTo(w)
522 // n += m
523 // return n, err
524 // }
525
526 // if w, ok := w.(io.ReaderFrom); ok {
527 // m, err := w.ReadFrom(b.rd)
528 // n += m
529 // return n, err
530 // }
531
532 // if b.w-b.r < b.buf.len() {
533 // b.fill() // buffer not full
534 // }
535
536 // for b.r < b.w {
537 // // b.r < b.w => buffer is not empty
538 // m, err := b.writeBuf(w)
539 // n += m
540 // if err.is_some() {
541 // return n, err
542 // }
543 // b.fill() // buffer is empty
544 // }
545
546 // if b.err == io.EOF {
547 // b.err = nil
548 // }
549
550 // return n, b.read_err()
551 // }
552
553 // var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
554
555 // // writeBuf writes the Reader's buffer to the writer.
556 // fn writeBuf(&mut self, w std::io::Write) (int64, error) {
557 // n, err := w.write(b.buf[b.r:b.w])
558 // if n < 0 {
559 // panic(errNegativeWrite)
560 // }
561 // b.r += n
562 // return int64(n), err
563 // }
564}
565
566// buffered output
567
568/// Writer implements buffering for an std::io::Write object.
569/// If an error occurs writing to a Writer, no more data will be
570/// accepted and all subsequent writes, and flush, will return the error.
571/// After all data has been written, the client should call the
572/// flush method to guarantee all data has been forwarded to
573/// the underlying std::io::Write.
574///
575/// Consider using native Rust std::io::BufWriter.
576pub struct Writer<'a> {
577 err: Option<std::io::Error>,
578 buf: Vec<u8>,
579 n: usize,
580 wr: &'a mut dyn std::io::Write,
581}
582
583impl std::io::Write for Writer<'_> {
584 /// Write writes the contents of p into the buffer.
585 /// It returns the number of bytes written.
586 // If nn < p.len(), it also returns an error explaining
587 // why the write is short.
588 fn write(&mut self, p: &[u8]) -> std::io::Result<usize> {
589 if self.err.is_some() {
590 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
591 }
592 let mut p = p;
593 let mut nn = 0;
594 while p.len() > self.available() && self.err.is_none() {
595 let mut n = 0;
596 if self.buffered() == 0 {
597 // Large write, empty buffer.
598 // Write directly from p to avoid copy.
599 match self.wr.write(p) {
600 Ok(nw) => n = nw,
601 Err(err) => self.err = Some(err),
602 }
603 } else {
604 n = compat::copy(&mut self.buf[self.n..], p);
605 self.n += n;
606 _ = self.flush();
607 }
608 nn += n;
609 p = &p[n..];
610 }
611 if self.err.is_some() {
612 if nn > 0 {
613 return Ok(nn);
614 }
615 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
616 }
617 let n = compat::copy(&mut self.buf[self.n..], p);
618 self.n += n;
619 nn += n;
620 Ok(nn)
621 }
622
623 /// flush writes any buffered data to the underlying std::io::Write.
624 fn flush(&mut self) -> std::io::Result<()> {
625 if self.err.is_some() {
626 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
627 }
628 if self.n == 0 {
629 return Ok(());
630 }
631
632 match self.wr.write(&self.buf[0..self.n]) {
633 Err(err) => {
634 self.err = Some(err);
635 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
636 }
637 Ok(n) => {
638 if n > 0 && n < self.n {
639 compat::copy_within(&mut self.buf, n..self.n, 0);
640 }
641 self.n -= n;
642 }
643 }
644 if self.n > 0 {
645 self.err = Some(ggio::new_error_short_write());
646 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
647 }
648 Ok(())
649 }
650}
651
652impl<'a> Writer<'a> {
653 /// new returns a new Writer whose buffer has the default size.
654 pub fn new(w: &'a mut dyn std::io::Write) -> Self {
655 Self::new_size(w, DEFAULT_BUF_SIZE)
656 }
657
658 /// new_size returns a new Writer whose buffer has at least the specified
659 /// size.
660 pub fn new_size(w: &'a mut dyn std::io::Write, size: usize) -> Self {
661 // // Is it already a Writer?
662 // b, ok := w.(*Writer)
663 // if ok && b.buf.len() >= size {
664 // return b
665 // }
666 Self {
667 err: None,
668 buf: vec![0; if size == 0 { DEFAULT_BUF_SIZE } else { size }],
669 n: 0,
670 wr: w,
671 }
672 }
673
674 /// size returns the size of the underlying buffer in bytes.
675 pub fn size(&self) -> usize {
676 self.buf.len()
677 }
678
679 /// reset discards any unflushed buffered data, clears any error, and
680 /// resets b to write its output to w.
681 // Calling reset on the zero value of Writer initializes the internal buffer
682 // to the default size.
683 // Calling w.reset(w) (that is, resetting a Writer to itself) does nothing.
684 pub fn reset(&mut self, w: &'a mut dyn std::io::Write) {
685 // // If a Writer w is passed to new_writer, new_writer will return w.
686 // // Different layers of code may do that, and then later pass w
687 // // to reset. Avoid infinite recursion in that case.
688 // if b == w {
689 // return
690 // }
691 // if self.buf == nil {
692 // self.buf = make([u8], DEFAULT_BUF_SIZE)
693 // }
694 self.err = None;
695 self.n = 0;
696 self.wr = w;
697 }
698
699 // available returns how many bytes are unused in the buffer.
700 pub fn available(&self) -> usize {
701 self.buf.len() - self.n
702 }
703
704 // // AvailableBuffer returns an empty buffer with b.available() capacity.
705 // // This buffer is intended to be appended to and
706 // // passed to an immediately succeeding Write call.
707 // // The buffer is only valid until the next write operation on b.
708 // fn AvailableBuffer(&self) [u8] {
709 // return b.buf[b.n..][..0]
710 // }
711
712 // buffered returns the number of bytes that have been written into the current buffer.
713 fn buffered(&self) -> usize {
714 self.n
715 }
716
717 /// write_byte writes a single byte.
718 pub fn write_byte(&mut self, c: u8) -> std::io::Result<()> {
719 if self.err.is_some() {
720 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
721 }
722 if self.available() == 0 && self.flush().is_err() {
723 return Err(errors::copy_stdio_error(self.err.as_ref().unwrap()));
724 }
725 self.buf[self.n] = c;
726 self.n += 1;
727 Ok(())
728 }
729
730 // // WriteRune writes a single Unicode code point, returning
731 // // the number of bytes written and any error.
732 // fn WriteRune(&self, r rune) (size isize, err error) {
733 // // Compare as uint32 to correctly handle negative runes.
734 // if uint32(r) < utf8::RUNE_SELF {
735 // err = b.write_byte(byte(r))
736 // if err.is_some() {
737 // return 0, err
738 // }
739 // return 1, nil
740 // }
741 // if b.err.is_some() {
742 // return 0, b.err
743 // }
744 // n := b.available()
745 // if n < utf8.UTFMAX {
746 // if b.flush(); b.err.is_some() {
747 // return 0, b.err
748 // }
749 // n = b.available()
750 // if n < utf8.UTFMAX {
751 // // Can only happen if buffer is silly small.
752 // return b.write_string(string(r))
753 // }
754 // }
755 // size = utf8.encode_rune(b.buf[b.n..], r)
756 // b.n += size
757 // return size, nil
758 // }
759
760 /// write_string writes a string.
761 /// It returns the number of bytes written.
762 // // If the count is less than len(s), it also returns an error explaining
763 // // why the write is short.
764 pub fn write_string(&mut self, s: &str) -> std::io::Result<usize> {
765 self.write(s.as_bytes())
766
767 // var sw io.StringWriter
768 // tryStringWriter := true
769
770 // nn := 0
771 // for len(s) > b.available() && b.err.is_none() {
772 // var n isize
773 // if b.buffered() == 0 && sw == nil && tryStringWriter {
774 // // Check at most once whether b.wr is a StringWriter.
775 // sw, tryStringWriter = b.wr.(io.StringWriter)
776 // }
777 // if b.buffered() == 0 && tryStringWriter {
778 // // Large write, empty buffer, and the underlying writer supports
779 // // write_string: forward the write to the underlying StringWriter.
780 // // This avoids an extra copy.
781 // n, b.err = sw.write_string(s)
782 // } else {
783 // n = copy(b.buf[b.n..], s)
784 // b.n += n
785 // b.flush()
786 // }
787 // nn += n
788 // s = s[n..]
789 // }
790 // if b.err.is_some() {
791 // return nn, b.err
792 // }
793 // n := copy(b.buf[b.n..], s)
794 // b.n += n
795 // nn += n
796 // return nn, nil
797 }
798}
799
800// // ReadFrom implements io.ReaderFrom. If the underlying writer
801// // supports the ReadFrom method, this calls the underlying ReadFrom.
802// // If there is buffered data and an underlying ReadFrom, this fills
803// // the buffer and writes it before calling ReadFrom.
804// fn ReadFrom(&self, r std::io::Read) (n int64, err error) {
805// if b.err.is_some() {
806// return 0, b.err
807// }
808// readerFrom, readerFromOK := b.wr.(io.ReaderFrom)
809// var m isize
810// for {
811// if b.available() == 0 {
812// if err1 := b.flush(); err1 != nil {
813// return n, err1
814// }
815// }
816// if readerFromOK && b.buffered() == 0 {
817// nn, err := readerFrom.ReadFrom(r)
818// b.err = err
819// n += nn
820// return n, err
821// }
822// nr := 0
823// for nr < MAX_CONSECUTIVE_EMPTY_READS {
824// m, err = r.Read(b.buf[b.n..])
825// if m != 0 || err.is_some() {
826// break
827// }
828// nr++
829// }
830// if nr == MAX_CONSECUTIVE_EMPTY_READS {
831// return n, io.ErrNoProgress
832// }
833// b.n += m
834// n += int64(m)
835// if err.is_some() {
836// break
837// }
838// }
839// if err == io.EOF {
840// // If we filled the buffer exactly, flush preemptively.
841// if b.available() == 0 {
842// err = b.flush()
843// } else {
844// err = nil
845// }
846// }
847// return n, err
848// }
849
850// // buffered input and output
851
852// // ReadWriter stores pointers to a Reader and a Writer.
853// // It implements io.ReadWriter.
854// type ReadWriter struct {
855// *Reader
856// *Writer
857// }
858
859// // NewReadWriter allocates a new ReadWriter that dispatches to r and w.
860// fn NewReadWriter(r *Reader, w *Writer) *ReadWriter {
861// return &ReadWriter{r, w}
862// }