| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 | 
							- package gnet
 
- import (
 
- 	"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 int
 
- }
 
- func (b BitSplit) Size() int {
 
- 	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 int) bool {
 
- 	if i >= b.size {
 
- 		return false
 
- 	}
 
- 	return b.p[i] == 0
 
- }
 
- func (b BitSplit) Is1(i int) 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 := 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 = 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
 
- // 只有读取的时候才必须区分字节序, 其他情况都不用考虑
 
- // BigEndian 与 LittleEndian 已实现 binary.ByteOrder
 
- var (
 
- 	BigEndian    bigEndian
 
- 	LittleEndian littleEndian
 
- )
 
- type BitSplitter interface {
 
- 	BitSplit(p []byte) *BitSplit
 
- }
 
 
  |