MCPcopy
hub / github.com/redis/go-redis / ReadStringInto

Method ReadStringInto

internal/proto/reader.go:560–612  ·  view source on GitHub ↗

ReadStringInto reads a string-typed reply directly into buf, avoiding the per-call allocation that ReadString incurs. It returns the number of bytes written to buf. Supported reply types: - $ \r\n \r\n bulk string (the GET path; payload is read straight into buf via bufio.Reader — for pa

(buf []byte)

Source from the content-addressed store, hash-verified

558// / float responses the payload lives in the (already-consumed) header
559// line, so no drain is needed.
560func (r *Reader) ReadStringInto(buf []byte) (int, error) {
561 line, err := r.ReadLine()
562 if err != nil {
563 return 0, err
564 }
565
566 switch line[0] {
567 case RespStatus:
568 // Simple string — data is in the line itself.
569 s := line[1:]
570 if len(s) > len(buf) {
571 return 0, fmt.Errorf("redis: buffer too small: need %d bytes, have %d", len(s), len(buf))
572 }
573 return copy(buf, s), nil
574
575 case RespString:
576 n, err := replyLen(line)
577 if err != nil {
578 return 0, err
579 }
580 if n > len(buf) {
581 // Drain the payload + trailing \r\n so the next read on this
582 // connection sees the start of the next reply rather than the
583 // tail of this one. Otherwise the unread bytes corrupt the
584 // stream and the bad connection gets handed back to the pool.
585 if _, derr := r.rd.Discard(n + 2); derr != nil {
586 return 0, derr
587 }
588 return 0, fmt.Errorf("redis: buffer too small: need %d bytes, have %d", n, len(buf))
589 }
590 // Read data directly into the user's buffer through the bufio.Reader.
591 // bufio.Reader.Read first drains its internal buffer, then for
592 // remaining data larger than its buffer size reads directly from the
593 // underlying reader (socket) — effectively zero-copy.
594 if _, err := io.ReadFull(r.rd, buf[:n]); err != nil {
595 return 0, err
596 }
597 // Discard trailing \r\n.
598 if _, err := r.rd.Discard(2); err != nil {
599 return 0, err
600 }
601 return n, nil
602
603 case RespInt, RespFloat:
604 s := line[1:]
605 if len(s) > len(buf) {
606 return 0, fmt.Errorf("redis: buffer too small: need %d bytes, have %d", len(s), len(buf))
607 }
608 return copy(buf, s), nil
609 }
610
611 return 0, fmt.Errorf("redis: can't parse reply=%.100q reading string into buffer", line)
612}
613
614func (r *Reader) ReadString() (string, error) {
615 line, err := r.ReadLine()

Calls 3

ReadLineMethod · 0.95
replyLenFunction · 0.85
DiscardMethod · 0.65