package bin import ( "fmt" "io" ) func PutVarInt32(w io.Writer, num int) (int, error) { if num > 2147483647 { return 0, fmt.Errorf("num %d overflows int32", num) } arr := make([]byte, 5) for i := 0; i < 4; i++ { arr[i] = byte(num & 127) num >>= 7 if num == 0 { arr[i] |= 128 return w.Write(arr[:i+1]) } } // в последнем 9м байте все биты значащие arr[5] = byte(num) return w.Write(arr) } func VarInt32(src io.ByteReader) (num int, err error) { var ( b byte off uint ) for ; off < 28; off += 7 { b, err = src.ReadByte() if err != nil { return } if b < 128 { num |= int(b) << off } else { num |= int(b&127) << off return } } b, err = src.ReadByte() if err != nil { return } // в последнем 9м байте все биты значащие num |= int(b&7) << 28 return } func PutVarUint(arr []byte, num uint64) int { for i := 0; i < 8; i++ { arr[i] = byte(num & 127) num >>= 7 if num == 0 { arr[i] |= 128 return i + 1 } } // в последнем 9м байте все биты значащие arr[8] = byte(num) return 9 } func VarUint(src io.ByteReader) (num uint64, err error) { var ( b byte off uint ) for ; off < 56; off += 7 { b, err = src.ReadByte() if err != nil { return } if b < 128 { num |= uint64(b) << off } else { num |= uint64(b&127) << off return } } b, err = src.ReadByte() if err != nil { return } // в последнем 9м байте все биты значащие num |= uint64(b) << 56 return } /* func PackVarUint32(num int) (err error) { idx := 0 for num > 127 { s.vint[idx] = byte(num & 127) num >>= 7 idx++ } // Даже в последнем байте отсекаем старший бит (знак) s.vint[idx] = byte(num&127) | 128 _, err = s.dst.Write(s.vint[:idx+1]) return } */