2 netstring -- netstring format serialization library
3 Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
34 func NewReader(r io.Reader) *Reader {
36 reader: bufio.NewReader(r),
37 prefix: make([]byte, MaxPrefixSize),
41 // Parse incoming netstring prefix. It returns netstring's incoming
42 // data length. After using this method you can call either Read()
43 // or Discard() methods. User can check if incoming data length is
45 func (self *Reader) Iter() (size uint64, err error) {
47 for self.n < MaxPrefixSize {
48 self.prefix[self.n], self.err = self.reader.ReadByte()
52 if self.prefix[self.n] == ':' {
57 self.size, self.err = strconv.ParseUint(
58 string(self.prefix[:self.n]), 10, 64,
66 func (self *Reader) terminator() bool {
67 self.prefix[0], self.err = self.reader.ReadByte()
71 if self.prefix[0] != ',' {
72 self.err = ErrTerminator
78 // Receive the full netstring message. This method is called after
79 // Iter() and user must preallocate buf. If buf size is smaller than
80 // incoming data size, then function will return an error. Also it
81 // checks the final terminator character and will return an error if
83 func (self *Reader) Read(buf []byte) error {
87 if uint64(cap(buf)) < self.size {
90 _, self.err = io.ReadAtLeast(self.reader, buf, int(self.size))
94 if !self.terminator() {
100 // Discard (skip) netstring message. This method is called after Iter().
101 // It reads and ignores data from the reader and checks that terminator
102 // character is valid.
103 func (self *Reader) Discard() error {
107 if _, self.err = self.reader.Discard(int(self.size)); self.err != nil {
110 if !self.terminator() {