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