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 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 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 readMessage(buf *streambuf.Buffer) (*message, error) { if !buf.Avail(2) { return nil, nil } version, _ := buf.ReadNetUint8At(0) if version != '2' { return nil, errors.New("version error") } code, _ := buf.ReadNetUint8At(1) switch code { case 'W': if !buf.Avail(6) { return nil, nil } size, _ := buf.ReadNetUint32At(2) buf.Advance(6) buf.Reset() return &message{code: code, size: size}, buf.Err() case 'C': if !buf.Avail(6) { return nil, nil } len, _ := buf.ReadNetUint32At(2) if !buf.Avail(int(len) + 6) { return nil, nil } buf.Advance(6) tmp, _ := buf.Collect(int(len)) buf.Reset() dataBuf := streambuf.New(nil) // decompress data decomp, err := zlib.NewReader(streambuf.NewFixed(tmp)) if err != nil { return nil, err } // dataBuf.ReadFrom(streambuf.NewFixed(tmp)) dataBuf.ReadFrom(decomp) decomp.Close() // unpack data dataBuf.Fix() var events []*message for dataBuf.Len() > 0 { version, _ := dataBuf.ReadNetUint8() if version != '2' { return nil, errors.New("version error 2") } code, _ := dataBuf.ReadNetUint8() if code != 'J' { return nil, errors.New("expected json data frame") } seq, _ := dataBuf.ReadNetUint32() payloadLen, _ := dataBuf.ReadNetUint32() jsonRaw, _ := dataBuf.Collect(int(payloadLen)) var doc interface{} err = json.Unmarshal(jsonRaw, &doc) if err != nil { return nil, err } events = append(events, &message{ code: code, seq: seq, doc: doc.(map[string]interface{}), }) } return &message{code: 'C', events: events}, nil default: return nil, errors.New("unknown code") } }
func readMessage(buf *streambuf.Buffer) (*message, error) { if !buf.Avail(2) { return nil, nil } version, _ := buf.ReadNetUint8At(0) if version != '1' { return nil, errors.New("version error") } code, _ := buf.ReadNetUint8At(1) switch code { case 'W': if !buf.Avail(6) { return nil, nil } size, _ := buf.ReadNetUint32At(2) buf.Advance(6) buf.Reset() return &message{code: code, size: size}, buf.Err() case 'C': if !buf.Avail(6) { return nil, nil } len, _ := buf.ReadNetUint32At(2) if !buf.Avail(int(len) + 6) { return nil, nil } buf.Advance(6) tmp, _ := buf.Collect(int(len)) buf.Reset() dataBuf := streambuf.New(nil) // decompress data decomp, err := zlib.NewReader(streambuf.NewFixed(tmp)) if err != nil { return nil, err } // dataBuf.ReadFrom(streambuf.NewFixed(tmp)) dataBuf.ReadFrom(decomp) decomp.Close() // unpack data dataBuf.Fix() var events []*message for dataBuf.Len() > 0 { version, _ := dataBuf.ReadNetUint8() if version != '1' { return nil, errors.New("version error 2") } code, _ := dataBuf.ReadNetUint8() if code != 'D' { return nil, errors.New("expected data frame") } seq, _ := dataBuf.ReadNetUint32() pairCount, _ := dataBuf.ReadNetUint32() kv := make(map[string]string) for i := 0; i < int(pairCount); i++ { keyLen, _ := dataBuf.ReadNetUint32() keyRaw, _ := dataBuf.Collect(int(keyLen)) valLen, _ := dataBuf.ReadNetUint32() valRaw, _ := dataBuf.Collect(int(valLen)) kv[string(keyRaw)] = string(valRaw) } events = append(events, &message{code: code, seq: seq, kv: kv}) } return &message{code: 'C', events: events}, nil default: return nil, errors.New("unknown code") } }