reader.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package strings
  5. import (
  6. "errors"
  7. "io"
  8. "unicode/utf8"
  9. )
  10. // A Reader implements the io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner,
  11. // io.RuneReader, io.RuneScanner, io.Seeker, and io.WriterTo interfaces by reading
  12. // from a string.
  13. // The zero value for Reader operates like a Reader of an empty string.
  14. type Reader struct {
  15. s string
  16. i int64 // current reading index
  17. prevRune int // index of previous rune; or < 0
  18. }
  19. // Len returns the number of bytes of the unread portion of the
  20. // string.
  21. func (r *Reader) Len() int {
  22. if r.i >= int64(len(r.s)) {
  23. return 0
  24. }
  25. return int(int64(len(r.s)) - r.i)
  26. }
  27. // Size returns the original length of the underlying string.
  28. // Size is the number of bytes available for reading via ReadAt.
  29. // The returned value is always the same and is not affected by calls
  30. // to any other method.
  31. func (r *Reader) Size() int64 { return int64(len(r.s)) }
  32. // Read implements the io.Reader interface.
  33. func (r *Reader) Read(b []byte) (n int, err error) {
  34. if r.i >= int64(len(r.s)) {
  35. return 0, io.EOF
  36. }
  37. r.prevRune = -1
  38. n = copy(b, r.s[r.i:])
  39. r.i += int64(n)
  40. return
  41. }
  42. // ReadAt implements the io.ReaderAt interface.
  43. func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
  44. // cannot modify state - see io.ReaderAt
  45. if off < 0 {
  46. return 0, errors.New("strings.Reader.ReadAt: negative offset")
  47. }
  48. if off >= int64(len(r.s)) {
  49. return 0, io.EOF
  50. }
  51. n = copy(b, r.s[off:])
  52. if n < len(b) {
  53. err = io.EOF
  54. }
  55. return
  56. }
  57. // ReadByte implements the io.ByteReader interface.
  58. func (r *Reader) ReadByte() (byte, error) {
  59. r.prevRune = -1
  60. if r.i >= int64(len(r.s)) {
  61. return 0, io.EOF
  62. }
  63. b := r.s[r.i]
  64. r.i++
  65. return b, nil
  66. }
  67. // UnreadByte implements the io.ByteScanner interface.
  68. func (r *Reader) UnreadByte() error {
  69. if r.i <= 0 {
  70. return errors.New("strings.Reader.UnreadByte: at beginning of string")
  71. }
  72. r.prevRune = -1
  73. r.i--
  74. return nil
  75. }
  76. // ReadRune implements the io.RuneReader interface.
  77. func (r *Reader) ReadRune() (ch rune, size int, err error) {
  78. if r.i >= int64(len(r.s)) {
  79. r.prevRune = -1
  80. return 0, 0, io.EOF
  81. }
  82. r.prevRune = int(r.i)
  83. if c := r.s[r.i]; c < utf8.RuneSelf {
  84. r.i++
  85. return rune(c), 1, nil
  86. }
  87. ch, size = utf8.DecodeRuneInString(r.s[r.i:])
  88. r.i += int64(size)
  89. return
  90. }
  91. // UnreadRune implements the io.RuneScanner interface.
  92. func (r *Reader) UnreadRune() error {
  93. if r.i <= 0 {
  94. return errors.New("strings.Reader.UnreadRune: at beginning of string")
  95. }
  96. if r.prevRune < 0 {
  97. return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
  98. }
  99. r.i = int64(r.prevRune)
  100. r.prevRune = -1
  101. return nil
  102. }
  103. // Seek implements the io.Seeker interface.
  104. func (r *Reader) Seek(offset int64, whence int) (int64, error) {
  105. r.prevRune = -1
  106. var abs int64
  107. switch whence {
  108. case io.SeekStart:
  109. abs = offset
  110. case io.SeekCurrent:
  111. abs = r.i + offset
  112. case io.SeekEnd:
  113. abs = int64(len(r.s)) + offset
  114. default:
  115. return 0, errors.New("strings.Reader.Seek: invalid whence")
  116. }
  117. if abs < 0 {
  118. return 0, errors.New("strings.Reader.Seek: negative position")
  119. }
  120. r.i = abs
  121. return abs, nil
  122. }
  123. // WriteTo implements the io.WriterTo interface.
  124. func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
  125. r.prevRune = -1
  126. if r.i >= int64(len(r.s)) {
  127. return 0, nil
  128. }
  129. s := r.s[r.i:]
  130. m, err := io.WriteString(w, s)
  131. if m > len(s) {
  132. panic("strings.Reader.WriteTo: invalid WriteString count")
  133. }
  134. r.i += int64(m)
  135. n = int64(m)
  136. if m != len(s) && err == nil {
  137. err = io.ErrShortWrite
  138. }
  139. return
  140. }
  141. // Reset resets the Reader to be reading from s.
  142. func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
  143. // NewReader returns a new Reader reading from s.
  144. // It is similar to bytes.NewBufferString but more efficient and read-only.
  145. func NewReader(s string) *Reader { return &Reader{s, 0, -1} }