| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 | package gnetimport (	"encoding/binary"	"fmt"	"math")var (	bitMasksBig    = []byte{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}	bitMasksLittle = []byte{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01})type BitSplit struct {	p    []uint8	size uint64}func (b *BitSplit) Size() uint64 {	return b.size}func (b *BitSplit) All() []int {	a := make([]int, len(b.p))	for i := 0; i < len(b.p); i++ {		a[i] = int(b.p[i])	}	return a}func (b *BitSplit) Is0(i uint64) bool {	if i >= b.size {		return false	}	return b.p[i] == 0}func (b *BitSplit) Is1(i uint64) bool {	if i >= b.size {		return false	}	return b.p[i] == 1}func (b *BitSplit) String() string {	return fmt.Sprintf("%v", b.p)}func binarySplit(p []byte, bitMasks []byte, reverse bool) *BitSplit {	bs := new(BitSplit)	bs.p = make([]uint8, 0, len(p)*8) // *8 是因为每个字节占 8 位	for _, b := range p {		for _, bm := range bitMasks {			v := 0			if b&bm > 0 {				v = 1			}			if reverse {				bs.p = append([]byte{uint8(v)}, bs.p...)			} else {				bs.p = append(bs.p, uint8(v))			}		}	}	bs.size = uint64(len(bs.p))	return bs}type bigEndian struct{}func (bigEndian) String() string { return "BigEndian" }func (bigEndian) GoString() string { return "gnet.BigEndian" }func (bigEndian) PutUint16(b []byte, v uint16) {	binary.BigEndian.PutUint16(b, v)}func (bigEndian) PutUint32(b []byte, v uint32) {	binary.BigEndian.PutUint32(b, v)}func (bigEndian) PutUint64(b []byte, v uint64) {	binary.BigEndian.PutUint64(b, v)}func (b bigEndian) BitSplit(p []byte) *BitSplit {	return binarySplit(p, bitMasksBig, false)}func (b bigEndian) BigMerge(p [8]byte) uint8 {	for _, n := range p {		if n != 0 && n != 1 {			panic("number must be 0 or 1")		}	}	var result uint8	for i := len(p) - 1; i >= 0; i-- {		result |= p[i] << (7 - i)	}	return result}func (b bigEndian) Int16(p []byte) int16 {	return int16(NegativeCovert(int64(b.Uint16(p))))}func (b bigEndian) Int32(p []byte) int32 {	return int32(NegativeCovert(int64(b.Uint32(p))))}func (b bigEndian) Int64(p []byte) int64 {	return NegativeCovert(int64(b.Uint32(p)))}func (b bigEndian) Uint16(p []byte) uint16 {	if len(p) != 2 {		return 0	}	return binary.BigEndian.Uint16(p)}func (b bigEndian) Uint32(p []byte) uint32 {	if len(p) != 4 {		return 0	}	return binary.BigEndian.Uint32(p)}func (b bigEndian) Uint64(p []byte) uint64 {	if len(p) != 8 {		return 0	}	return binary.BigEndian.Uint64(p)}func (b bigEndian) Float32(p []byte) float32 {	if len(p) != 4 {		return 0	}	return math.Float32frombits(b.Uint32(p))}func (b bigEndian) Float64(p []byte) float64 {	if len(p) != 8 {		return 0	}	return math.Float64frombits(b.Uint64(p))}type littleEndian struct{}func (littleEndian) String() string { return "LittleEndian" }func (littleEndian) GoString() string { return "gnet.LittleEndian" }func (littleEndian) PutUint16(b []byte, v uint16) {	binary.LittleEndian.PutUint16(b, v)}func (littleEndian) PutUint32(b []byte, v uint32) {	binary.LittleEndian.PutUint32(b, v)}func (littleEndian) PutUint64(b []byte, v uint64) {	binary.LittleEndian.PutUint64(b, v)}func (littleEndian) BitSplit(p []byte) *BitSplit {	return binarySplit(p, bitMasksLittle, true)}func (littleEndian) BitMerge(p [8]byte) uint8 {	for _, n := range p {		if n != 0 && n != 1 {			panic("number must be 0 or 1")		}	}	var result uint8	for i := 0; i < len(p); i++ {		result |= p[i] << i	}	return result}// Int16 Range: -32768 through 32767.func (l littleEndian) Int16(p []byte) int16 {	return int16(NegativeCovert(int64(l.Uint16(p))))}func (l littleEndian) Int32(p []byte) int32 {	return int32(NegativeCovert(int64(l.Uint32(p))))}func (l littleEndian) Int64(p []byte) int64 {	return NegativeCovert(int64(l.Uint32(p)))}func (littleEndian) Uint16(p []byte) uint16 {	if len(p) != 2 {		return 0	}	return binary.LittleEndian.Uint16(p)}func (littleEndian) Uint32(p []byte) uint32 {	if len(p) != 4 {		return 0	}	return binary.LittleEndian.Uint32(p)}func (littleEndian) Uint64(b []byte) uint64 {	if len(b) != 8 {		return 0	}	return binary.LittleEndian.Uint64(b)}func (l littleEndian) Float32(p []byte) float32 {	if len(p) != 4 {		return 0	}	return math.Float32frombits(l.Uint32(p))}func (l littleEndian) Float64(p []byte) float64 {	if len(p) != 8 {		return 0	}	return math.Float64frombits(l.Uint64(p))}func NegativeCovert(i int64) int64 {	if i < 0 {		i = -i		i = ^i + 1	}	return i}// 举例:// 数值 0x22 0x11 使用两个字节储存: 高位字节是 0x22, 低位字节是 0x11// BigEndian 高位字节在前, 低位字节在后. 即 0x2211// LittleEndian 低位字节在前, 高位字节在后. 即 0x1122// 只有读取的时候才必须区分字节序, 其他情况都不用考虑var (	BigEndian    bigEndian	LittleEndian littleEndian)type BitSplitter interface {	BitSplit(p []byte) *BitSplit}type BinaryOrder interface {	PutUint16(b []byte, v uint16)	PutUint32(b []byte, v uint32)	PutUint64(b []byte, v uint64)	Int16(p []byte) int16	Int32(p []byte) int32	Int64(p []byte) int64	Uint16(p []byte) uint16	Uint32(p []byte) uint32	Uint64(p []byte) uint64	Float32(p []byte) float32	Float64(p []byte) float64	BitSplitter}
 |