first commit
This commit is contained in:
		
							
								
								
									
										118
									
								
								utils/bits/bits.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								utils/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
									
								
								utils/bits/bits_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								utils/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() | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										23
									
								
								utils/bits/bufio/bufio.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								utils/bits/bufio/bufio.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| 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
									
								
								utils/bits/golomb_reader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								utils/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 | ||||
| } | ||||
							
								
								
									
										5
									
								
								utils/bits/pio/pio.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								utils/bits/pio/pio.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
|  | ||||
| package pio | ||||
|  | ||||
| var RecommendBufioSize = 1024*64 | ||||
|  | ||||
							
								
								
									
										91
									
								
								utils/bits/pio/reader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								utils/bits/pio/reader.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
|  | ||||
| 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 | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										69
									
								
								utils/bits/pio/vec.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								utils/bits/pio/vec.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| 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 | ||||
| } | ||||
|  | ||||
							
								
								
									
										22
									
								
								utils/bits/pio/vec_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								utils/bits/pio/vec_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| 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: | ||||
| } | ||||
							
								
								
									
										89
									
								
								utils/bits/pio/writer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								utils/bits/pio/writer.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
|  | ||||
| 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
	 Andrey Semochkin
					Andrey Semochkin