redis/internal/proto/write_buffer.go

141 lines
2.7 KiB
Go
Raw Normal View History

2016-07-02 15:52:10 +03:00
package proto
import (
"encoding"
"fmt"
"strconv"
)
type WriteBuffer struct {
rb *BufioReader
buf []byte
}
2016-07-02 15:52:10 +03:00
func NewWriteBuffer(rb *BufioReader) *WriteBuffer {
2016-07-02 15:52:10 +03:00
return &WriteBuffer{
rb: rb,
2016-07-02 15:52:10 +03:00
}
}
func (w *WriteBuffer) Len() int {
return len(w.buf)
}
func (w *WriteBuffer) Bytes() []byte {
return w.buf
}
func (w *WriteBuffer) AllocBuffer() {
w.rb = nil
w.buf = make([]byte, defaultBufSize)
}
func (w *WriteBuffer) Reset() {
if w.rb != nil {
w.buf = w.rb.Buffer()[:0]
} else {
w.buf = w.buf[:0]
}
}
func (w *WriteBuffer) Flush() []byte {
b := w.buf
if w.rb != nil {
w.rb.ResetBuffer(w.buf[:cap(w.buf)])
w.buf = nil
}
return b
}
2016-07-02 15:52:10 +03:00
func (w *WriteBuffer) Append(args []interface{}) error {
w.buf = append(w.buf, ArrayReply)
w.buf = strconv.AppendUint(w.buf, uint64(len(args)), 10)
w.buf = append(w.buf, '\r', '\n')
2016-07-02 15:52:10 +03:00
for _, arg := range args {
if err := w.append(arg); err != nil {
return err
}
}
return nil
}
func (w *WriteBuffer) append(val interface{}) error {
switch v := val.(type) {
case nil:
w.AppendString("")
case string:
w.AppendString(v)
case []byte:
w.AppendBytes(v)
case int:
w.AppendString(formatInt(int64(v)))
case int8:
w.AppendString(formatInt(int64(v)))
case int16:
w.AppendString(formatInt(int64(v)))
case int32:
w.AppendString(formatInt(int64(v)))
case int64:
w.AppendString(formatInt(v))
case uint:
w.AppendString(formatUint(uint64(v)))
case uint8:
w.AppendString(formatUint(uint64(v)))
case uint16:
w.AppendString(formatUint(uint64(v)))
case uint32:
w.AppendString(formatUint(uint64(v)))
case uint64:
w.AppendString(formatUint(v))
case float32:
w.AppendString(formatFloat(float64(v)))
case float64:
w.AppendString(formatFloat(v))
case bool:
if v {
w.AppendString("1")
} else {
w.AppendString("0")
}
2018-03-08 15:00:21 +03:00
case encoding.BinaryMarshaler:
b, err := v.MarshalBinary()
if err != nil {
return err
2016-07-02 15:52:10 +03:00
}
2018-03-08 15:00:21 +03:00
w.AppendBytes(b)
default:
return fmt.Errorf(
"redis: can't marshal %T (consider implementing encoding.BinaryMarshaler)", val)
2016-07-02 15:52:10 +03:00
}
return nil
}
func (w *WriteBuffer) AppendString(s string) {
w.buf = append(w.buf, StringReply)
w.buf = strconv.AppendUint(w.buf, uint64(len(s)), 10)
w.buf = append(w.buf, '\r', '\n')
w.buf = append(w.buf, s...)
w.buf = append(w.buf, '\r', '\n')
2016-07-02 15:52:10 +03:00
}
func (w *WriteBuffer) AppendBytes(p []byte) {
w.buf = append(w.buf, StringReply)
w.buf = strconv.AppendUint(w.buf, uint64(len(p)), 10)
w.buf = append(w.buf, '\r', '\n')
w.buf = append(w.buf, p...)
w.buf = append(w.buf, '\r', '\n')
2016-07-02 15:52:10 +03:00
}
2018-07-22 09:27:36 +03:00
func formatInt(n int64) string {
return strconv.FormatInt(n, 10)
}
func formatUint(u uint64) string {
return strconv.FormatUint(u, 10)
}
func formatFloat(f float64) string {
return strconv.FormatFloat(f, 'f', -1, 64)
}