func (p *parser) parseArray(depth int, buf *streambuf.Buffer) (string, bool, bool, bool) { line, err := buf.UntilCRLF() if err != nil { debug("End of line not found, waiting for more data") return "", false, false, false } debug("line %s: %d", line, buf.BufferConsumed()) if len(line) == 3 && line[1] == '-' && line[2] == '1' { return "nil", false, true, true } if len(line) == 2 && line[1] == '0' { return "[]", false, true, true } count, err := strconv.ParseInt(string(line[1:]), 10, 64) if err != nil { logp.Err("Failed to read number of bulk messages: %s", err) return "", false, false, false } if count < 0 { return "nil", false, true, true } content := make([]string, 0, count) // read sub elements iserror := false for i := 0; i < int(count); i++ { var value string var ok, complete bool value, iserror, ok, complete := p.dispatch(depth+1, buf) if !ok || !complete { debug("Array incomplete") return "", iserror, ok, complete } content = append(content, value) } if depth == 0 && isRedisCommand(content[0]) { // we've got a request p.message.IsRequest = true p.message.Method = content[0] p.message.Path = content[1] } var value string if depth == 0 && p.message.IsRequest { value = strings.Join(content, " ") } else { value = "[" + strings.Join(content, ", ") + "]" } return value, iserror, true, true }
func parseVersionNumber(parser *parser, buf *streambuf.Buffer) parseResult { msg := parser.message if msg.IsRequest { return parser.contWith(buf, parseStateDataBinary) } // size already checked bytes, _ := buf.Collect(int(msg.bytes)) msg.str = memcacheString{bytes} return parser.yield(buf.BufferConsumed()) }
func (parser *parser) parse(buf *streambuf.Buffer) (bool, bool) { snapshot := buf.Snapshot() content, iserror, ok, complete := parser.dispatch(0, buf) if !ok || !complete { // on error or incomplete message drop all parsing progress, due to // parse not being statefull among multiple calls // => parser needs to restart parsing all content buf.Restore(snapshot) return ok, complete } parser.message.IsError = iserror parser.message.Size = buf.BufferConsumed() parser.message.Message = content return true, true }
func parseStatResponse(parser *parser, buf *streambuf.Buffer) parseResult { msg := parser.message if msg.IsRequest { return parser.contWith(buf, parseStateDataBinary) } bytes, _ := buf.Collect(int(msg.bytes)) if len(msg.keys) == 0 { return parser.failing(ErrExpectedKeys) } msg.stats = append(msg.stats, memcacheStat{ msg.keys[0], memcacheString{bytes}, }) return parser.yield(buf.BufferConsumed()) }
func parseDataBinary(parser *parser, buf *streambuf.Buffer) parseResult { msg := parser.message data, err := buf.Collect(int(msg.bytes - msg.bytesLost)) if err != nil { if err == streambuf.ErrNoMoreBytes { return parser.needMore() } return parser.failing(err) } debug("found data message") if msg.bytesLost > 0 { msg.count_values++ } else { parser.appendMessageData(data) } return parser.yield(buf.BufferConsumed() + int(msg.bytesLost)) }
func parseData(parser *parser, buf *streambuf.Buffer) parseResult { msg := parser.message debug("parse message data (%v)", msg.bytes) data, err := buf.CollectWithSuffix( int(msg.bytes-msg.bytesLost), []byte("\r\n"), ) if err != nil { if err == streambuf.ErrNoMoreBytes { return parser.needMore() } return parser.failing(err) } debug("found message data") if msg.bytesLost > 0 { msg.count_values++ } else { parser.appendMessageData(data) } return parser.yield(buf.BufferConsumed() + int(msg.bytesLost)) }
func parseBinaryCounterResponse( parser *parser, buf *streambuf.Buffer, ) parseResult { msg := parser.message if msg.IsRequest { return parser.contWith(buf, parseStateDataBinary) } // size already checked bytes, _ := buf.Collect(int(msg.bytes)) tmp := streambuf.NewFixed(bytes) err := withBinaryUint64(parser, tmp, func(msg *message, value uint64) { msg.value = value }) if err != nil { return parser.failing(err) } buf.Advance(8) return parser.yield(buf.BufferConsumed()) }
func (p *parser) yieldNoData(buf *streambuf.Buffer) parseResult { return p.yield(buf.BufferConsumed()) }