package rest_websocket import ( "io" "git.ali33.ru/fcg-xvii/go-tools/json" "git.ali33.ru/fcg-xvii/rest" ) // конверторы // Int64ToBytes упаковывает int64 в срез байтов заданной длины func Int64ToBytes(num int64, byteCount int) []byte { bytes := make([]byte, byteCount) for i := 0; i < byteCount; i++ { shift := uint((byteCount - 1 - i) * 8) bytes[i] = byte(num >> shift) } return bytes } // BytesToInt64 конвертирует срез байтов в int64 func BytesToInt64(bytes []byte) int64 { var num int64 for _, b := range bytes { num = (num << 8) | int64(b) } return num } func ioError(field string, err error) rest.IErrorArgs { return rest.NewError( "ErrIO", json.Map{ "field": field, "error": err.Error(), }, ) } // чтение func ReadBuf(r io.Reader, size int, field string) ([]byte, rest.IErrorArgs) { buf := make([]byte, size) if _, err := r.Read(buf); err != nil { return nil, ioError(field, err) } return buf, nil } func ReadBufSize(r io.Reader, lenSize int, field string) ([]byte, rest.IErrorArgs) { var size int64 if err := ReadInt64(r, lenSize, field+"_size", &size); err != nil { return nil, err } buf, err := ReadBuf(r, int(size), field) return buf, err } func ReadInt64(r io.Reader, size int, field string, result *int64) rest.IErrorArgs { buf := make([]byte, size) if _, err := r.Read(buf); err != nil { return ioError(field, err) } *result = BytesToInt64(buf) return nil } func ReadString(r io.Reader, lenSize int, field string, result *string) rest.IErrorArgs { strBuf, err := ReadBufSize(r, lenSize, field) if err != nil { return err } *result = string(strBuf) return nil } func ReadByte(r io.Reader, field string, result *byte) rest.IErrorArgs { buf, err := ReadBuf(r, 1, field) if err != nil { return err } *result = buf[0] return nil } // запись func WriteBuf(w io.Writer, buf []byte, field string) rest.IErrorArgs { if _, err := w.Write(buf); err != nil { return ioError(field, err) } return nil } func WriteInt64(w io.Writer, val int64, size int, field string) rest.IErrorArgs { buf := Int64ToBytes(val, size) return WriteBuf(w, buf, field) } func WriteString(w io.Writer, val, field string, lenSize int) rest.IErrorArgs { // длина if err := WriteInt64(w, int64(len(val)), lenSize, field+"_size"); err != nil { return err } // строка if len(val) == 0 { return nil } return WriteBuf(w, []byte(val), field) } func WriteByte(w io.Writer, val byte, field string) rest.IErrorArgs { return WriteBuf(w, []byte{val}, field) } func WriteBufSize(w io.Writer, val []byte, lenSize int, field string) rest.IErrorArgs { // длина if err := WriteInt64(w, int64(len(val)), lenSize, field+"_size"); err != nil { return err } // буфер return WriteBuf(w, val, field) }