2 netstring -- netstring format serialization library
3 Copyright (C) 2015-2016 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, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
35 func NewReader(r io.Reader) *Reader {
37 reader: bufio.NewReader(r),
38 prefix: make([]byte, MaxPrefixSize),
42 // Parse incoming netstring prefix. It returns netstring's incoming
43 // data length. After using this method you can call either Read()
44 // or Discard() methods. User can check if incoming data length is
46 func (self *Reader) Iter() (size uint64, err error) {
48 for self.n < MaxPrefixSize {
49 self.prefix[self.n], self.err = self.reader.ReadByte()
53 if self.prefix[self.n] == ':' {
58 self.size, self.err = strconv.ParseUint(
59 string(self.prefix[:self.n]), 10, 64,
67 func (self *Reader) terminator() bool {
68 self.prefix[0], self.err = self.reader.ReadByte()
72 if self.prefix[0] != ',' {
73 self.err = ErrTerminator
79 // Receive the full netstring message. This method is called after
80 // Iter() and user must preallocate buf. If buf size is smaller than
81 // incoming data size, then function will return an error. Also it
82 // checks the final terminator character and will return an error if
84 func (self *Reader) Read(buf []byte) error {
88 if uint64(cap(buf)) < self.size {
91 _, self.err = io.ReadAtLeast(self.reader, buf, int(self.size))
95 if !self.terminator() {
101 // Discard (skip) netstring message. This method is called after Iter().
102 // It reads and ignores data from the reader and checks that terminator
103 // character is valid.
104 func (self *Reader) Discard() error {
108 if _, self.err = self.reader.Discard(int(self.size)); self.err != nil {
111 if !self.terminator() {