memio - buffer.go
1 package memio
2
3 import (
4 "io"
5 "unicode/utf8"
6 )
7
8 // Buffer grants a byte slice very straightforward IO methods.
9 type Buffer []byte
10
11 // Read satisfies the io.Reader interface.
12 func (s *Buffer) Read(p []byte) (int, error) {
13 if len(p) == 0 {
14 return 0, nil
15 }
16
17 if len(*s) == 0 {
18 return 0, io.EOF
19 }
20
21 n := copy(p, *s)
22 *s = (*s)[n:]
23
24 return n, nil
25 }
26
27 // ReadAt satisfies the io.ReaderAt interface.
28 //
29 // Care should be taken when used in conjunction with any other Read* calls as
30 // they will alter the start point of the buffer.
31 func (s *Buffer) ReadAt(p []byte, off int64) (int, error) {
32 n := copy(p, (*s)[off:])
33 if n < len(p) {
34 return n, io.EOF
35 }
36
37 return n, nil
38 }
39
40 // WriteTo satisfies the io.WriterTo interface.
41 func (s *Buffer) WriteTo(w io.Writer) (int64, error) {
42 if len(*s) == 0 {
43 return 0, io.EOF
44 }
45
46 n, err := w.Write(*s)
47 *s = (*s)[n:]
48
49 return int64(n), err
50 }
51
52 // Write satisfies the io.Writer interface.
53 func (s *Buffer) Write(p []byte) (int, error) {
54 *s = append(*s, p...)
55 return len(p), nil
56 }
57
58 // WriteAt satisfies the io.WriteAt interface.
59 func (s *Buffer) WriteAt(p []byte, off int64) (int, error) {
60 l := int64(len(p)) + off
61 if int64(cap(*s)) < l {
62 t := make([]byte, len(*s), l)
63
64 copy(t, (*s)[:cap(*s)])
65
66 *s = t
67 }
68
69 return copy((*s)[off:cap(*s)], p), nil
70 }
71
72 // WriteString writes a string to the buffer without casting to a byte slice.
73 func (s *Buffer) WriteString(str string) (int, error) {
74 *s = append(*s, str...)
75
76 return len(str), nil
77 }
78
79 // ReadFrom satisfies the io.ReaderFrom interface.
80 func (s *Buffer) ReadFrom(r io.Reader) (int64, error) {
81 var n int64
82
83 for {
84 if len(*s) == cap(*s) {
85 *s = append(*s, 0)[:len(*s)]
86 }
87
88 m, err := r.Read((*s)[len(*s):cap(*s)])
89 *s = (*s)[:len(*s)+m]
90 n += int64(m)
91
92 if err != nil {
93 if err == io.EOF {
94 return n, nil
95 }
96
97 return n, err
98 }
99 }
100 }
101
102 // ReadByte satisfies the io.ByteReader interface.
103 func (s *Buffer) ReadByte() (byte, error) {
104 if len(*s) == 0 {
105 return 0, io.EOF
106 }
107
108 b := (*s)[0]
109 *s = (*s)[1:]
110
111 return b, nil
112 }
113
114 // ReadRune satisfies the io.RuneReader interface.
115 func (s *Buffer) ReadRune() (rune, int, error) {
116 if len(*s) == 0 {
117 return 0, 0, io.EOF
118 }
119
120 r, n := utf8.DecodeRune(*s)
121 *s = (*s)[n:]
122
123 return r, n, nil
124 }
125
126 // WriteByte satisfies the io.ByteWriter interface.
127 func (s *Buffer) WriteByte(b byte) error {
128 *s = append(*s, b)
129
130 return nil
131 }
132
133 // Peek reads the next n bytes without advancing the position.
134 func (s *Buffer) Peek(n int) ([]byte, error) {
135 if *s == nil {
136 return nil, ErrClosed
137 } else if n > len(*s) {
138 return *s, io.EOF
139 }
140
141 return (*s)[:n], nil
142 }
143
144 // Close satisfies the io.Closer interface.
145 func (s *Buffer) Close() error {
146 *s = nil
147
148 return nil
149 }
150