mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-09 02:20:07 +08:00
first commit
This commit is contained in:
118
util/bits/bits.go
Normal file
118
util/bits/bits.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package bits
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
R io.Reader
|
||||
n int
|
||||
bits uint64
|
||||
}
|
||||
|
||||
func (self *Reader) ReadBits64(n int) (bits uint64, err error) {
|
||||
if self.n < n {
|
||||
var b [8]byte
|
||||
var got int
|
||||
want := (n - self.n + 7) / 8
|
||||
if got, err = self.R.Read(b[:want]); err != nil {
|
||||
return
|
||||
}
|
||||
if got < want {
|
||||
err = io.EOF
|
||||
return
|
||||
}
|
||||
for i := 0; i < got; i++ {
|
||||
self.bits <<= 8
|
||||
self.bits |= uint64(b[i])
|
||||
}
|
||||
self.n += got * 8
|
||||
}
|
||||
bits = self.bits >> uint(self.n-n)
|
||||
self.bits ^= bits << uint(self.n-n)
|
||||
self.n -= n
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Reader) ReadBits(n int) (bits uint, err error) {
|
||||
var bits64 uint64
|
||||
if bits64, err = self.ReadBits64(n); err != nil {
|
||||
return
|
||||
}
|
||||
bits = uint(bits64)
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Reader) Read(p []byte) (n int, err error) {
|
||||
for n < len(p) {
|
||||
want := 8
|
||||
if len(p)-n < want {
|
||||
want = len(p) - n
|
||||
}
|
||||
var bits uint64
|
||||
if bits, err = self.ReadBits64(want * 8); err != nil {
|
||||
break
|
||||
}
|
||||
for i := 0; i < want; i++ {
|
||||
p[n+i] = byte(bits >> uint((want-i-1)*8))
|
||||
}
|
||||
n += want
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Writer struct {
|
||||
W io.Writer
|
||||
n int
|
||||
bits uint64
|
||||
}
|
||||
|
||||
func (self *Writer) WriteBits64(bits uint64, n int) (err error) {
|
||||
if self.n+n > 64 {
|
||||
move := uint(64 - self.n)
|
||||
mask := bits >> move
|
||||
self.bits = (self.bits << move) | mask
|
||||
self.n = 64
|
||||
if err = self.FlushBits(); err != nil {
|
||||
return
|
||||
}
|
||||
n -= int(move)
|
||||
bits ^= (mask << move)
|
||||
}
|
||||
self.bits = (self.bits << uint(n)) | bits
|
||||
self.n += n
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Writer) WriteBits(bits uint, n int) (err error) {
|
||||
return self.WriteBits64(uint64(bits), n)
|
||||
}
|
||||
|
||||
func (self *Writer) Write(p []byte) (n int, err error) {
|
||||
for n < len(p) {
|
||||
if err = self.WriteBits64(uint64(p[n]), 8); err != nil {
|
||||
return
|
||||
}
|
||||
n++
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Writer) FlushBits() (err error) {
|
||||
if self.n > 0 {
|
||||
var b [8]byte
|
||||
bits := self.bits
|
||||
if self.n%8 != 0 {
|
||||
bits <<= uint(8 - (self.n % 8))
|
||||
}
|
||||
want := (self.n + 7) / 8
|
||||
for i := 0; i < want; i++ {
|
||||
b[i] = byte(bits >> uint((want-i-1)*8))
|
||||
}
|
||||
if _, err = self.W.Write(b[:want]); err != nil {
|
||||
return
|
||||
}
|
||||
self.n = 0
|
||||
}
|
||||
return
|
||||
}
|
51
util/bits/bits_test.go
Normal file
51
util/bits/bits_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package bits
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBits(t *testing.T) {
|
||||
rdata := []byte{0xf3, 0xb3, 0x45, 0x60}
|
||||
rbuf := bytes.NewReader(rdata[:])
|
||||
r := &Reader{R: rbuf}
|
||||
var u32 uint
|
||||
if u32, _ = r.ReadBits(4); u32 != 0xf {
|
||||
t.FailNow()
|
||||
}
|
||||
if u32, _ = r.ReadBits(4); u32 != 0x3 {
|
||||
t.FailNow()
|
||||
}
|
||||
if u32, _ = r.ReadBits(2); u32 != 0x2 {
|
||||
t.FailNow()
|
||||
}
|
||||
if u32, _ = r.ReadBits(2); u32 != 0x3 {
|
||||
t.FailNow()
|
||||
}
|
||||
b := make([]byte, 2)
|
||||
if r.Read(b); b[0] != 0x34 || b[1] != 0x56 {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
wbuf := &bytes.Buffer{}
|
||||
w := &Writer{W: wbuf}
|
||||
w.WriteBits(0xf, 4)
|
||||
w.WriteBits(0x3, 4)
|
||||
w.WriteBits(0x2, 2)
|
||||
w.WriteBits(0x3, 2)
|
||||
n, _ := w.Write([]byte{0x34, 0x56})
|
||||
if n != 2 {
|
||||
t.FailNow()
|
||||
}
|
||||
w.FlushBits()
|
||||
wdata := wbuf.Bytes()
|
||||
if wdata[0] != 0xf3 || wdata[1] != 0xb3 || wdata[2] != 0x45 || wdata[3] != 0x60 {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
b = make([]byte, 8)
|
||||
PutUInt64BE(b, 0x11223344, 32)
|
||||
if b[0] != 0x11 || b[1] != 0x22 || b[2] != 0x33 || b[3] != 0x44 {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
22
util/bits/bufio/bufio.go
Normal file
22
util/bits/bufio/bufio.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package bufio
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
buf [][]byte
|
||||
R io.ReadSeeker
|
||||
}
|
||||
|
||||
func NewReaderSize(r io.ReadSeeker, size int) *Reader {
|
||||
buf := make([]byte, size*2)
|
||||
return &Reader{
|
||||
R: r,
|
||||
buf: [][]byte{buf[0:size], buf[size:]},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Reader) ReadAt(b []byte, off int64) (n int, err error) {
|
||||
return
|
||||
}
|
65
util/bits/golomb_reader.go
Normal file
65
util/bits/golomb_reader.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package bits
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type GolombBitReader struct {
|
||||
R io.Reader
|
||||
buf [1]byte
|
||||
left byte
|
||||
}
|
||||
|
||||
func (self *GolombBitReader) ReadBit() (res uint, err error) {
|
||||
if self.left == 0 {
|
||||
if _, err = self.R.Read(self.buf[:]); err != nil {
|
||||
return
|
||||
}
|
||||
self.left = 8
|
||||
}
|
||||
self.left--
|
||||
res = uint(self.buf[0]>>self.left) & 1
|
||||
return
|
||||
}
|
||||
|
||||
func (self *GolombBitReader) ReadBits(n int) (res uint, err error) {
|
||||
for i := 0; i < n; i++ {
|
||||
var bit uint
|
||||
if bit, err = self.ReadBit(); err != nil {
|
||||
return
|
||||
}
|
||||
res |= bit << uint(n-i-1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *GolombBitReader) ReadExponentialGolombCode() (res uint, err error) {
|
||||
i := 0
|
||||
for {
|
||||
var bit uint
|
||||
if bit, err = self.ReadBit(); err != nil {
|
||||
return
|
||||
}
|
||||
if !(bit == 0 && i < 32) {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
if res, err = self.ReadBits(i); err != nil {
|
||||
return
|
||||
}
|
||||
res += (1 << uint(i)) - 1
|
||||
return
|
||||
}
|
||||
|
||||
func (self *GolombBitReader) ReadSE() (res uint, err error) {
|
||||
if res, err = self.ReadExponentialGolombCode(); err != nil {
|
||||
return
|
||||
}
|
||||
if res&0x01 != 0 {
|
||||
res = (res + 1) / 2
|
||||
} else {
|
||||
res = -res / 2
|
||||
}
|
||||
return
|
||||
}
|
3
util/bits/pio/pio.go
Normal file
3
util/bits/pio/pio.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package pio
|
||||
|
||||
var RecommendBufioSize = 1024 * 64
|
121
util/bits/pio/reader.go
Normal file
121
util/bits/pio/reader.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package pio
|
||||
|
||||
func U8(b []byte) (i uint8) {
|
||||
return b[0]
|
||||
}
|
||||
|
||||
func U16BE(b []byte) (i uint16) {
|
||||
i = uint16(b[0])
|
||||
i <<= 8
|
||||
i |= uint16(b[1])
|
||||
return
|
||||
}
|
||||
|
||||
func I16BE(b []byte) (i int16) {
|
||||
i = int16(b[0])
|
||||
i <<= 8
|
||||
i |= int16(b[1])
|
||||
return
|
||||
}
|
||||
|
||||
func I24BE(b []byte) (i int32) {
|
||||
i = int32(int8(b[0]))
|
||||
i <<= 8
|
||||
i |= int32(b[1])
|
||||
i <<= 8
|
||||
i |= int32(b[2])
|
||||
return
|
||||
}
|
||||
|
||||
func U24BE(b []byte) (i uint32) {
|
||||
i = uint32(b[0])
|
||||
i <<= 8
|
||||
i |= uint32(b[1])
|
||||
i <<= 8
|
||||
i |= uint32(b[2])
|
||||
return
|
||||
}
|
||||
|
||||
func I32BE(b []byte) (i int32) {
|
||||
i = int32(int8(b[0]))
|
||||
i <<= 8
|
||||
i |= int32(b[1])
|
||||
i <<= 8
|
||||
i |= int32(b[2])
|
||||
i <<= 8
|
||||
i |= int32(b[3])
|
||||
return
|
||||
}
|
||||
|
||||
func U32LE(b []byte) (i uint32) {
|
||||
i = uint32(b[3])
|
||||
i <<= 8
|
||||
i |= uint32(b[2])
|
||||
i <<= 8
|
||||
i |= uint32(b[1])
|
||||
i <<= 8
|
||||
i |= uint32(b[0])
|
||||
return
|
||||
}
|
||||
|
||||
func U32BE(b []byte) (i uint32) {
|
||||
i = uint32(b[0])
|
||||
i <<= 8
|
||||
i |= uint32(b[1])
|
||||
i <<= 8
|
||||
i |= uint32(b[2])
|
||||
i <<= 8
|
||||
i |= uint32(b[3])
|
||||
return
|
||||
}
|
||||
|
||||
func U40BE(b []byte) (i uint64) {
|
||||
i = uint64(b[0])
|
||||
i <<= 8
|
||||
i |= uint64(b[1])
|
||||
i <<= 8
|
||||
i |= uint64(b[2])
|
||||
i <<= 8
|
||||
i |= uint64(b[3])
|
||||
i <<= 8
|
||||
i |= uint64(b[4])
|
||||
return
|
||||
}
|
||||
|
||||
func U64BE(b []byte) (i uint64) {
|
||||
i = uint64(b[0])
|
||||
i <<= 8
|
||||
i |= uint64(b[1])
|
||||
i <<= 8
|
||||
i |= uint64(b[2])
|
||||
i <<= 8
|
||||
i |= uint64(b[3])
|
||||
i <<= 8
|
||||
i |= uint64(b[4])
|
||||
i <<= 8
|
||||
i |= uint64(b[5])
|
||||
i <<= 8
|
||||
i |= uint64(b[6])
|
||||
i <<= 8
|
||||
i |= uint64(b[7])
|
||||
return
|
||||
}
|
||||
|
||||
func I64BE(b []byte) (i int64) {
|
||||
i = int64(int8(b[0]))
|
||||
i <<= 8
|
||||
i |= int64(b[1])
|
||||
i <<= 8
|
||||
i |= int64(b[2])
|
||||
i <<= 8
|
||||
i |= int64(b[3])
|
||||
i <<= 8
|
||||
i |= int64(b[4])
|
||||
i <<= 8
|
||||
i |= int64(b[5])
|
||||
i <<= 8
|
||||
i |= int64(b[6])
|
||||
i <<= 8
|
||||
i |= int64(b[7])
|
||||
return
|
||||
}
|
68
util/bits/pio/vec.go
Normal file
68
util/bits/pio/vec.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package pio
|
||||
|
||||
func VecLen(vec [][]byte) (n int) {
|
||||
for _, b := range vec {
|
||||
n += len(b)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func VecSliceTo(in [][]byte, out [][]byte, s int, e int) (n int) {
|
||||
if s < 0 {
|
||||
s = 0
|
||||
}
|
||||
|
||||
if e >= 0 && e < s {
|
||||
panic("pio: VecSlice start > end")
|
||||
}
|
||||
|
||||
i := 0
|
||||
off := 0
|
||||
for s > 0 && i < len(in) {
|
||||
left := len(in[i])
|
||||
read := s
|
||||
if left < read {
|
||||
read = left
|
||||
}
|
||||
left -= read
|
||||
off += read
|
||||
s -= read
|
||||
e -= read
|
||||
if left == 0 {
|
||||
i++
|
||||
off = 0
|
||||
}
|
||||
}
|
||||
if s > 0 {
|
||||
panic("pio: VecSlice start out of range")
|
||||
}
|
||||
|
||||
for e != 0 && i < len(in) {
|
||||
left := len(in[i]) - off
|
||||
read := left
|
||||
if e > 0 && e < read {
|
||||
read = e
|
||||
}
|
||||
out[n] = in[i][off : off+read]
|
||||
n++
|
||||
left -= read
|
||||
e -= read
|
||||
off += read
|
||||
if left == 0 {
|
||||
i++
|
||||
off = 0
|
||||
}
|
||||
}
|
||||
if e > 0 {
|
||||
panic("pio: VecSlice end out of range")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func VecSlice(in [][]byte, s int, e int) (out [][]byte) {
|
||||
out = make([][]byte, len(in))
|
||||
n := VecSliceTo(in, out, s, e)
|
||||
out = out[:n]
|
||||
return
|
||||
}
|
21
util/bits/pio/vec_test.go
Normal file
21
util/bits/pio/vec_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package pio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func ExampleVec() {
|
||||
vec := [][]byte{[]byte{1, 2, 3}, []byte{4, 5, 6, 7, 8, 9}, []byte{10, 11, 12, 13}}
|
||||
println(VecLen(vec))
|
||||
|
||||
vec = VecSlice(vec, 1, -1)
|
||||
fmt.Println(vec)
|
||||
|
||||
vec = VecSlice(vec, 2, -1)
|
||||
fmt.Println(vec)
|
||||
|
||||
vec = VecSlice(vec, 8, 8)
|
||||
fmt.Println(vec)
|
||||
|
||||
// Output:
|
||||
}
|
87
util/bits/pio/writer.go
Normal file
87
util/bits/pio/writer.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package pio
|
||||
|
||||
func PutU8(b []byte, v uint8) {
|
||||
b[0] = v
|
||||
}
|
||||
|
||||
func PutI16BE(b []byte, v int16) {
|
||||
b[0] = byte(v >> 8)
|
||||
b[1] = byte(v)
|
||||
}
|
||||
|
||||
func PutU16BE(b []byte, v uint16) {
|
||||
b[0] = byte(v >> 8)
|
||||
b[1] = byte(v)
|
||||
}
|
||||
|
||||
func PutI24BE(b []byte, v int32) {
|
||||
b[0] = byte(v >> 16)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v)
|
||||
}
|
||||
|
||||
func PutU24BE(b []byte, v uint32) {
|
||||
b[0] = byte(v >> 16)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v)
|
||||
}
|
||||
|
||||
func PutI32BE(b []byte, v int32) {
|
||||
b[0] = byte(v >> 24)
|
||||
b[1] = byte(v >> 16)
|
||||
b[2] = byte(v >> 8)
|
||||
b[3] = byte(v)
|
||||
}
|
||||
|
||||
func PutU32BE(b []byte, v uint32) {
|
||||
b[0] = byte(v >> 24)
|
||||
b[1] = byte(v >> 16)
|
||||
b[2] = byte(v >> 8)
|
||||
b[3] = byte(v)
|
||||
}
|
||||
|
||||
func PutU32LE(b []byte, v uint32) {
|
||||
b[3] = byte(v >> 24)
|
||||
b[2] = byte(v >> 16)
|
||||
b[1] = byte(v >> 8)
|
||||
b[0] = byte(v)
|
||||
}
|
||||
|
||||
func PutU40BE(b []byte, v uint64) {
|
||||
b[0] = byte(v >> 32)
|
||||
b[1] = byte(v >> 24)
|
||||
b[2] = byte(v >> 16)
|
||||
b[3] = byte(v >> 8)
|
||||
b[4] = byte(v)
|
||||
}
|
||||
|
||||
func PutU48BE(b []byte, v uint64) {
|
||||
b[0] = byte(v >> 40)
|
||||
b[1] = byte(v >> 32)
|
||||
b[2] = byte(v >> 24)
|
||||
b[3] = byte(v >> 16)
|
||||
b[4] = byte(v >> 8)
|
||||
b[5] = byte(v)
|
||||
}
|
||||
|
||||
func PutU64BE(b []byte, v uint64) {
|
||||
b[0] = byte(v >> 56)
|
||||
b[1] = byte(v >> 48)
|
||||
b[2] = byte(v >> 40)
|
||||
b[3] = byte(v >> 32)
|
||||
b[4] = byte(v >> 24)
|
||||
b[5] = byte(v >> 16)
|
||||
b[6] = byte(v >> 8)
|
||||
b[7] = byte(v)
|
||||
}
|
||||
|
||||
func PutI64BE(b []byte, v int64) {
|
||||
b[0] = byte(v >> 56)
|
||||
b[1] = byte(v >> 48)
|
||||
b[2] = byte(v >> 40)
|
||||
b[3] = byte(v >> 32)
|
||||
b[4] = byte(v >> 24)
|
||||
b[5] = byte(v >> 16)
|
||||
b[6] = byte(v >> 8)
|
||||
b[7] = byte(v)
|
||||
}
|
Reference in New Issue
Block a user