func (e *Encoder) EncodeObject(db uint32, key []byte, expireat uint64, obj interface{}) error { o, ok := obj.(objectEncoder) if !ok { return errors.New("unsupported object type") } if e.db == -1 || uint32(e.db) != db { e.db = int64(db) if err := e.enc.EncodeDatabase(int(db)); err != nil { return errors.Trace(err) } } if expireat != 0 { if err := e.enc.EncodeExpiry(expireat); err != nil { return errors.Trace(err) } } if err := o.encodeType(e.enc); err != nil { return err } if err := e.enc.EncodeString(key); err != nil { return errors.Trace(err) } if err := o.encodeValue(e.enc); err != nil { return err } return nil }
func (d *decoder) decodeRequest() (Resp, error) { t, err := d.decodeType() if err != nil { return nil, err } switch t { default: if !isLetter(byte(t)) { return nil, errors.Trace(ErrBadRespType) } // may be it's telnet text format d.r.UnreadByte() t, err := d.decodeText() if err != nil { return nil, err } items := strings.Fields(t) resp := &Array{} for _, item := range items { resp.AppendBulkBytes([]byte(item)) } return resp, nil case TypeString, TypeError, TypeInt, TypeBulkBytes: return nil, errors.Trace(ErrBadRespType) case TypePing: return NewPing(), nil case TypeArray: resp := &Array{} resp.Value, err = d.decodeArray() return resp, err } }
func (e *encoder) encodeResp(r Resp) error { switch x := r.(type) { default: return errors.Trace(ErrBadRespType) case *String: if err := e.encodeType(TypeString); err != nil { return err } return e.encodeText(x.Value) case *Error: if err := e.encodeType(TypeError); err != nil { return err } return e.encodeText(x.Value) case *Int: if err := e.encodeType(TypeInt); err != nil { return err } return e.encodeInt(x.Value) case *BulkBytes: if err := e.encodeType(TypeBulkBytes); err != nil { return err } return e.encodeBulkBytes(x.Value) case *Array: if err := e.encodeType(TypeArray); err != nil { return err } return e.encodeArray(x.Value) case Ping: return errors.Trace(e.w.WriteByte('\n')) } }
func (e *encoder) encodeText(s string) error { if _, err := e.w.WriteString(s); err != nil { return errors.Trace(err) } if _, err := e.w.WriteString("\r\n"); err != nil { return errors.Trace(err) } return nil }
func (d *decoder) decodeText() (string, error) { b, err := d.r.ReadBytes('\n') if err != nil { return "", errors.Trace(err) } if n := len(b) - 2; n < 0 || b[n] != '\r' { return "", errors.Trace(ErrBadRespEnd) } else { return string(b[:n]), nil } }
func (o Set) encodeValue(enc *rdb.Encoder) error { if err := enc.EncodeLength(uint32(len(o))); err != nil { return errors.Trace(err) } for _, e := range o { if err := enc.EncodeString(e); err != nil { return errors.Trace(err) } } return nil }
func (e *encoder) encodeBulkBytes(b []byte) error { if b == nil { return e.encodeInt(-1) } else { if err := e.encodeInt(int64(len(b))); err != nil { return err } if _, err := e.w.Write(b); err != nil { return errors.Trace(err) } if _, err := e.w.WriteString("\r\n"); err != nil { return errors.Trace(err) } return nil } }
func DecodeDump(p []byte) (interface{}, error) { d := &decoder{} if err := rdb.DecodeDump(p, 0, nil, 0, d); err != nil { return nil, errors.Trace(err) } return d.obj, d.err }
func (d *decoder) decodeResp() (Resp, error) { t, err := d.decodeType() if err != nil { return nil, err } switch t { default: return nil, errors.Trace(ErrBadRespType) case TypeString: resp := &String{} resp.Value, err = d.decodeText() return resp, err case TypeError: resp := &Error{} resp.Value, err = d.decodeText() return resp, err case TypeInt: resp := &Int{} resp.Value, err = d.decodeInt() return resp, err case TypeBulkBytes: resp := &BulkBytes{} resp.Value, err = d.decodeBulkBytes() return resp, err case TypeArray: resp := &Array{} resp.Value, err = d.decodeArray() return resp, err case TypePing: return NewPing(), nil } }
func (d *decoder) decodeType() (RespType, error) { if b, err := d.r.ReadByte(); err != nil { return 0, errors.Trace(err) } else { return RespType(b), nil } }
func OpenFile(fileName string, exclusive bool) (*os.File, error) { flag := os.O_CREATE | os.O_RDWR | os.O_TRUNC if exclusive { flag |= os.O_EXCL } f, err := os.OpenFile(fileName, flag, 0600) return f, errors.Trace(err) }
func Parse(s string) (int64, error) { if !BytesizeRegexp.MatchString(s) { return 0, errors.Trace(ErrBadBytesize) } subs := BytesizeRegexp.FindStringSubmatch(s) if len(subs) != 3 { return 0, errors.Trace(ErrBadBytesize) } size := int64(0) switch strings.ToUpper(string(subs[2])) { case "B", "": size = 1 case "KB", "K": size = KB case "MB", "M": size = MB case "GB", "G": size = GB case "TB", "T": size = TB case "PB", "P": size = PB default: return 0, errors.Trace(ErrBadBytesizeUnit) } text := subs[1] if digitsRegexp.MatchString(text) { n, err := strconv.ParseInt(text, 10, 64) if err != nil { return 0, errors.Trace(ErrBadBytesize) } size *= n } else { n, err := strconv.ParseFloat(text, 64) if err != nil { return 0, errors.Trace(ErrBadBytesize) } size = int64(float64(size) * n) } return size, nil }
func (w *simpleWriter) Write(b []byte) (int, error) { if w.err != nil { return 0, w.err } n, err := w.w.Write(b) if err != nil { w.err = errors.Trace(err) } return n, w.err }
func (d *decoder) decodeBulkBytes() ([]byte, error) { n, err := d.decodeInt() if err != nil { return nil, err } if n < -1 { return nil, errors.Trace(ErrBadRespBytesLen) } else if n == -1 { return nil, nil } b := make([]byte, n+2) if _, err := ioutils.ReadFull(d.r, b); err != nil { return nil, errors.Trace(err) } if b[n] != '\r' || b[n+1] != '\n' { return nil, errors.Trace(ErrBadRespEnd) } return b[:n], nil }
func (r *simpleReader) Read(b []byte) (int, error) { if r.err != nil { return 0, r.err } n, err := r.r.Read(b) if err != nil { r.err = errors.Trace(err) } return n, r.err }
func (d *decoder) decodeInt() (int64, error) { b, err := d.decodeText() if err != nil { return 0, err } if n, err := strconv.ParseInt(string(b), 10, 64); err != nil { return 0, errors.Trace(err) } else { return n, nil } }
func (p *pipe) WClose(err error) error { if err == nil { err = errors.Trace(io.EOF) } p.mu.Lock() defer p.mu.Unlock() if p.werr == nil { p.werr = err } p.rwait.Signal() p.wwait.Signal() return p.store.wclose() }
func (l *Loader) Header() error { header := make([]byte, 9) if err := l.readFull(header); err != nil { return err } if !bytes.Equal(header[:5], []byte("REDIS")) { return errors.New("verify magic string, invalid file format") } if version, err := strconv.ParseInt(string(header[5:]), 10, 64); err != nil { return errors.Trace(err) } else if version <= 0 || version > Version { return errors.Errorf("verify version, invalid RDB version number %d", version) } return nil }
func EncodeDump(obj interface{}) ([]byte, error) { o, ok := obj.(objectEncoder) if !ok { return nil, errors.New("unsupported object type") } var b bytes.Buffer enc := rdb.NewEncoder(&b) if err := o.encodeType(enc); err != nil { return nil, err } if err := o.encodeValue(enc); err != nil { return nil, err } if err := enc.EncodeDumpFooter(); err != nil { return nil, errors.Trace(err) } return b.Bytes(), nil }
func (d *decoder) decodeArray() ([]Resp, error) { n, err := d.decodeInt() if err != nil { return nil, err } if n < -1 { return nil, errors.Trace(ErrBadRespArrayLen) } else if n == -1 { return nil, nil } a := make([]Resp, n) for i := 0; i < len(a); i++ { if a[i], err = d.decodeResp(); err != nil { return nil, err } } return a, nil }
func (r *rdbReader) readFloat() (float64, error) { u, err := r.readUint8() if err != nil { return 0, err } switch u { case 253: return math.NaN(), nil case 254: return math.Inf(0), nil case 255: return math.Inf(-1), nil default: if b, err := r.readBytes(int(u)); err != nil { return 0, err } else { v, err := strconv.ParseFloat(string(b), 64) return v, errors.Trace(err) } } }
func (p *pipe) Read(b []byte) (int, error) { p.rl.Lock() defer p.rl.Unlock() p.mu.Lock() defer p.mu.Unlock() for { if p.rerr != nil { return 0, errors.Trace(io.ErrClosedPipe) } n, err := p.store.read(b) if err != nil || n != 0 { p.wwait.Signal() return n, err } if p.werr != nil || len(b) == 0 { return 0, p.werr } p.rwait.Wait() } }
func (o String) encodeValue(enc *rdb.Encoder) error { if err := enc.EncodeString([]byte(o)); err != nil { return errors.Trace(err) } return nil }
func (o Set) encodeType(enc *rdb.Encoder) error { t := rdb.ValueType(rdbTypeSet) return errors.Trace(enc.EncodeType(t)) }
func OpenTempFile(dir, prefix string) (*os.File, error) { f, err := ioutil.TempFile(dir, prefix) return f, errors.Trace(err) }
func (e *encoder) encodeType(t RespType) error { return errors.Trace(e.w.WriteByte(byte(t))) }
func (r *rdbReader) Read(p []byte) (int, error) { n, err := r.raw.Read(p) r.nread += int64(n) return n, errors.Trace(err) }
func (e *Encoder) EncodeFooter() error { return errors.Trace(e.enc.EncodeFooter()) }
func OpenFile(path string) (*os.File, error) { f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666) return f, errors.Trace(err) }