func readline(reader *bufio.Reader, buffer *bytes.Buffer) (line string, size int, err error) { var ( segment []byte ) for { if segment, err = reader.ReadBytes('\n'); err != nil { if err != io.EOF { log.Errorf("read line failed: %s", err) } return } if _, err = buffer.Write(segment); err != nil { log.Errorf("write buffer failed: %s", err) return } if isPartialLine(segment) { time.Sleep(1 * time.Second) } else { size = buffer.Len() line = buffer.String() buffer.Reset() line = strings.TrimRight(line, "\r\n") return } } return }
func IsXM(reader *bufio.Reader) bool { header, e := reader.Peek(17) if e != nil { return false } return bytes.Equal(header[0:17], xmHeader) }
func nextLine(reader *bufio.Reader) []byte { line, _, err := reader.ReadLine() handleError(err) return line }
func readTrimmedLine(r *bufio.Reader) ([]byte, error) { if line, err := r.ReadBytes('\n'); err != nil { return nil, err } else { return bytes.TrimRight(line, "\r\n"), nil } }
func readError(r *bufio.Reader) (*Message, error) { b, err := r.ReadBytes(delimEnd) if err != nil { return nil, err } return &Message{Type: Err, val: b[1 : len(b)-2], raw: b}, nil }
func ReadTillEOL(reader *bufio.Reader, buf []byte) int { i := 0 for { ch, err := reader.ReadByte() if err != nil { return -1 } if i >= len(buf) { return i } if ch == '\r' { ch, err := reader.ReadByte() if err != nil { return -1 } if ch == '\n' { return i } else { buf[i] = '\r' buf[i+1] = ch i += 1 } } else { buf[i] = ch } i += 1 } return i }
// translate EscX to Meta+X func escapeKey(r rune, reader *bufio.Reader) rune { switch r { case 'b': r = MetaBackward case 'f': r = MetaForward case 'd': r = MetaDelete case CharTranspose: r = MetaTranspose case CharBackspace: r = MetaBackspace case 'O': d, _, _ := reader.ReadRune() switch d { case 'H': r = CharLineStart case 'F': r = CharLineEnd default: reader.UnreadRune() } case CharEsc: } return r }
func parseStatsSettingsResponse(r *bufio.Reader, stats *SettingsStats) error { pattern := "STAT %s %s\r\n" var ( key string value []byte ) for { line, err := r.ReadSlice('\n') if err != nil { return err } if bytes.Equal(line, resultEnd) { return nil } n, err := fmt.Sscanf(string(line), pattern, &key, &value) if err != nil || n != 2 { return fmt.Errorf("memcache: unexpected line in stats response: %q", line) } err = stats.Set(key, value) if err != nil && err != ErrInvalidStatsKey { return err } } panic("unreached") }
func parseStatsItemsResponse(r *bufio.Reader, slabMap map[int]*ItemStats) error { pattern := "STAT items:%d:%s %s\r\n" var ( slabIndex int key string value []byte ) for { line, err := r.ReadSlice('\n') if err != nil { return err } if bytes.Equal(line, resultEnd) { return nil } n, err := fmt.Sscanf(string(line), pattern, &slabIndex, &key, &value) if err != nil || n != 3 { return fmt.Errorf("memcache: unexpected line in stats items response: %q", line) } _, ok := slabMap[slabIndex] if !ok { slabMap[slabIndex] = new(ItemStats) } err = slabMap[slabIndex].Set(key, value) if err != nil && err != ErrInvalidStatsKey { return err } } panic("unreached") }
func readBulkData(conn *bufio.Reader, len int64) ([]byte, os.Error) { buff := make([]byte, len) _, e := io.ReadFull(conn, buff) if e != nil { return nil, NewErrorWithCause(SYSTEM_ERR, "Error while attempting read of bulkdata", e) } // fmt.Println ("Read ", n, " bytes. data: ", buff); crb, e1 := conn.ReadByte() if e1 != nil { return nil, os.NewError("Error while attempting read of bulkdata terminal CR:" + e1.String()) } if crb != CR_BYTE { return nil, os.NewError("<BUG> bulkdata terminal was not CR as expected") } lfb, e2 := conn.ReadByte() if e2 != nil { return nil, os.NewError("Error while attempting read of bulkdata terminal LF:" + e2.String()) } if lfb != LF_BYTE { return nil, os.NewError("<BUG> bulkdata terminal was not LF as expected.") } return buff, nil }
// parseGetResponse reads a GET response from r and calls cb for each // read and allocated Item func parseGetResponse(r *bufio.Reader, cb func(*Item)) error { for { line, err := r.ReadSlice('\n') if err != nil { return err } if bytes.Equal(line, resultEnd) { return nil } it := new(Item) size, err := scanGetResponseLine(line, it) if err != nil { return err } it.Value, err = ioutil.ReadAll(io.LimitReader(r, int64(size)+2)) if err != nil { return err } if !bytes.HasSuffix(it.Value, crlf) { return fmt.Errorf("memcache: corrupt get result read") } it.Value = it.Value[:size] cb(it) } panic("unreached") }
// parseGetResponse reads a GET response from r and calls cb for each // read and allocated Item func parseGetResponse(r *bufio.Reader, cb func(*Item)) error { for { line, err := r.ReadSlice('\n') if err != nil { return err } if bytes.Equal(line, resultEnd) { return nil } it := new(Item) var size int n, err := fmt.Sscanf(string(line), "VALUE %s %d %d %d\r\n", &it.Key, &it.Flags, &size, &it.casid) if err != nil { return err } if n != 4 { return fmt.Errorf("memcache: unexpected line in get response: %q", string(line)) } it.Value, err = ioutil.ReadAll(io.LimitReader(r, int64(size)+2)) if err != nil { return err } if !bytes.HasSuffix(it.Value, crlf) { return fmt.Errorf("memcache: corrupt get result read") } it.Value = it.Value[:size] cb(it) } panic("unreached") }
func readBulkString(r *bufio.Reader) (interface{}, error) { _, err := r.ReadByte() if err != nil { return EMPTY_STRING, err } countAsStr, err := ReadLine(r) if err != nil { return EMPTY_STRING, err } count, err := strconv.Atoi(countAsStr) if err != nil { return EMPTY_STRING, err } if count == -1 { return countAsStr, nil } line, err := ReadLine(r) if err != nil { return EMPTY_STRING, err } if len(line) != count { return EMPTY_STRING, errors.New("Expected " + countAsStr + " characters in string and got " + line) } return line, nil }
func readArray(r *bufio.Reader) (interface{}, error) { _, err := r.ReadByte() if err != nil { return EMPTY_STRING, err } countAsStr, err := ReadLine(r) if err != nil { return EMPTY_STRING, err } arrLen, err := strconv.Atoi(countAsStr) if err != nil { return EMPTY_STRING, err } l := list.New() for i := 0; i < arrLen; i++ { val, err := readType(r) if err != nil { return EMPTY_STRING, err } l.PushBack(val) } return l, nil }
func (c *ListCommand) Decode(r *bufio.Reader) error { started := false for { resp, err := r.ReadString('\n') if err != nil { return err } // Handle the start condition if !started { if resp != "START\n" { return fmt.Errorf("expect list start block") } started = true continue } // Check for the end if resp == "END\n" { c.done = true return nil } // Store the line c.lines = append(c.lines, resp) } return nil }
// reades errors like -ERR not working :D\r\n func readError(reader *bufio.Reader) (*Reply, error) { raw_response, err := reader.ReadBytes('\n') if err != nil { return nil, err } return nil, errors.New(string(raw_response[0 : len(raw_response)-2])) }
func (c *InfoCommand) Decode(r *bufio.Reader) error { started := false for { resp, err := r.ReadString('\n') if err != nil { return err } // Handle the start condition if !started { switch resp { case "Set does not exist\n": c.done = true c.notExist = true return nil case "START\n": started = true c.notExist = false continue default: return fmt.Errorf("invalid response: %s", resp) } } // Check for the end if resp == "END\n" { c.done = true return nil } // Store the line c.lines = append(c.lines, resp) } return nil }
// parses Simple string response like +OK\r\n func readSimpleString(reader *bufio.Reader) (*Reply, error) { raw_response, err := reader.ReadBytes('\n') if err != nil { return nil, err } return &Reply{Response: raw_response[0 : len(raw_response)-2], Rtype: RString}, nil }
// translate Esc[X func escapeExKey(r rune, reader *bufio.Reader) rune { switch r { case 'D': r = CharBackward case 'C': r = CharForward case 'A': r = CharPrev case 'B': r = CharNext case 'H': r = CharLineStart case 'F': r = CharLineEnd default: if r == '3' && reader != nil { d, _, _ := reader.ReadRune() if d == '~' { r = CharDelete } else { reader.UnreadRune() } } } return r }
func readInteger(reader *bufio.Reader) (*Reply, error) { raw_response, err := reader.ReadBytes('\n') if err != nil { return nil, err } return &Reply{Response: raw_response[0 : len(raw_response)-2], Rtype: RInt}, nil }
func (cmd *cmdSync) PSyncPipeCopy(c net.Conn, br *bufio.Reader, bw *bufio.Writer, offset int64, copyto io.Writer) (int64, error) { defer c.Close() var nread atomic2.Int64 go func() { defer c.Close() for { time.Sleep(time.Second * 5) if err := sendPSyncAck(bw, offset+nread.Get()); err != nil { return } } }() var p = make([]byte, 8192) for { n, err := br.Read(p) if err != nil { return nread.Get(), nil } if _, err := copyto.Write(p[:n]); err != nil { return nread.Get(), err } nread.Add(int64(n)) } }
func readBodyIdentity(r *bufio.Reader, maxBodySize int, dst []byte) ([]byte, error) { dst = dst[:cap(dst)] if len(dst) == 0 { dst = make([]byte, 1024) } offset := 0 for { nn, err := r.Read(dst[offset:]) if nn <= 0 { if err != nil { if err == io.EOF { return dst[:offset], nil } return dst[:offset], err } panic(fmt.Sprintf("BUG: bufio.Read() returned (%d, nil)", nn)) } offset += nn if maxBodySize > 0 && offset > maxBodySize { return dst[:offset], ErrBodyTooLarge } if len(dst) == offset { n := round2(2 * offset) if maxBodySize > 0 && n > maxBodySize { n = maxBodySize + 1 } b := make([]byte, n) copy(b, dst) dst = b } } }
func newMessageReader(bufr *bufio.Reader) (*messageReader, error) { if _, err := bufr.ReadBytes('"'); err != nil { return nil, err } msg, err := bufr.ReadBytes('"') if err != nil { return nil, err } for { b, err := bufr.Peek(1) if err != nil { return nil, err } if b[0] == ',' { bufr.ReadByte() break } if b[0] != ' ' { break } bufr.ReadByte() } return &messageReader{ reader: bufr, message: string(msg[:len(msg)-1]), firstRead: true, }, nil }
func appendBodyFixedSize(r *bufio.Reader, dst []byte, n int) ([]byte, error) { if n == 0 { return dst, nil } offset := len(dst) dstLen := offset + n if cap(dst) < dstLen { b := make([]byte, round2(dstLen)) copy(b, dst) dst = b } dst = dst[:dstLen] for { nn, err := r.Read(dst[offset:]) if nn <= 0 { if err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } return dst[:offset], err } panic(fmt.Sprintf("BUG: bufio.Read() returned (%d, nil)", nn)) } offset += nn if offset == dstLen { return dst, nil } } }
// reads a bulk reply (i.e $5\r\nhello) func readBulk(reader *bufio.Reader, head string) ([]byte, error) { var err error var data []byte if head == "" { head, err = reader.ReadString('\n') if err != nil { return nil, err } } switch head[0] { case ':': data = []byte(strings.TrimSpace(head[1:])) case '$': size, err := strconv.Atoi(strings.TrimSpace(head[1:])) if err != nil { return nil, err } if size == -1 { return nil, doesNotExist } lr := io.LimitReader(reader, int64(size)) data, err = ioutil.ReadAll(lr) if err == nil { // read end of line _, err = reader.ReadString('\n') } default: return nil, RedisError("Expecting Prefix '$' or ':'") } return data, err }
func mustPeekBuffered(r *bufio.Reader) []byte { buf, err := r.Peek(r.Buffered()) if len(buf) == 0 || err != nil { panic(fmt.Sprintf("bufio.Reader.Peek() returned unexpected data (%q, %v)", buf, err)) } return buf }
func getBoardAndPrincess(reader *bufio.Reader) (Board, Princess) { board := Board{} princess := Princess{} y := 0 for { line, isPrefix, err := reader.ReadLine() if err == io.EOF { break } handleError(err) handleLongLines(isPrefix) x := bytes.Index(line, []byte("p")) if x > -1 { // Found the princess! princess.X = x princess.Y = y } y++ board = append(board, line) } return board, princess }
func isEof(r *bufio.Reader) bool { _, err := r.Peek(1) if err == io.EOF { return true } return false }
func readHexInt(r *bufio.Reader) (int, error) { n := 0 i := 0 var k int for { c, err := r.ReadByte() if err != nil { if err == io.EOF && i > 0 { return n, nil } return -1, err } k = hexbyte2int(c) if k < 0 { if i == 0 { return -1, fmt.Errorf("cannot read hex num from empty string") } r.UnreadByte() return n, nil } if i >= maxHexIntChars { return -1, fmt.Errorf("cannot read hex num with more than %d digits", maxHexIntChars) } n = (n << 4) | k i++ } }
func readMultiBulk(br *bufio.Reader) ([][]byte, error) { count, err := readInt(br) switch { case err != nil: return nil, err case count < 0: return nil, PROTOCOL_ERROR } data := make([][]byte, 0, count) for count > 0 { f, err := br.ReadByte() var b []byte switch f { case '$': b, err = readBulk(br) if err != nil { return nil, err } case ':': // coerce an integer into mere bytes b, err = readLine(br) if err != nil { return nil, err } default: return nil, PROTOCOL_ERROR } data = append(data, b) count-- } return data, nil }