1
0
mirror of https://github.com/fumiama/unibase2n.git synced 2026-06-05 00:32:47 +08:00

add base & pack

This commit is contained in:
源文雨
2022-09-30 20:15:57 +08:00
parent 4d15a66510
commit 35341dcad5
6 changed files with 119 additions and 0 deletions

2
.gitignore vendored
View File

@@ -13,3 +13,5 @@
# Dependency directories (remove the comment below to include it)
# vendor/
*.txt

50
base.go Normal file
View File

@@ -0,0 +1,50 @@
package unibase2n
import (
"errors"
)
// Base has an encoding buffer thus should not be copied.
// total size: 8 bytes
type Base struct {
off uint16 // starting offset
til uint16 // remianing indicator starting offset
bit uint8 // 2^bit, max is 15 (32768)
pos uint8 // bitwise buffer position
buf [2]byte // en/decoding buffer
}
var (
ErrInvalidBitSize = errors.New("bit size >= 16 or == 0")
ErrOffsetOverflow = errors.New("offset overflow")
ErrTailOverflow = errors.New("tail overflow")
ErrTailInCodingArea = errors.New("tail in coding area")
)
// NewBase generates a new base2n config
func NewBase(off, til uint16, bit uint8) (*Base, error) {
if bit >= 16 || bit == 0 {
return nil, ErrInvalidBitSize
}
offe := uint32(off) + 1<<bit // [off, offe)
if offe > 0x10000 {
return nil, ErrOffsetOverflow
}
tile := uint32(til) // [til, tile)
if bit%2 == 0 {
tile += uint32(bit / 2)
} else {
tile += uint32(bit)
}
if tile > 0x10000 {
return nil, ErrTailOverflow
}
if tile > uint32(off) || uint32(til) < offe {
return nil, ErrTailInCodingArea
}
return &Base{
off: off,
til: til,
bit: bit,
}, nil
}

3
go.mod Normal file
View File

@@ -0,0 +1,3 @@
module github.com/fumiama/unibase2n
go 1.18

20
helper.go Normal file
View File

@@ -0,0 +1,20 @@
package unibase2n
import (
"unsafe"
)
// BytesToString 没有内存开销的转换
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// StringToBytes 没有内存开销的转换
func StringToBytes(s string) (b []byte) {
bh := (*slice)(unsafe.Pointer(&b))
sh := (*slice)(unsafe.Pointer(&s))
bh.data = sh.data
bh.len = sh.len
bh.cap = sh.len
return b
}

29
pack.go Normal file
View File

@@ -0,0 +1,29 @@
package unibase2n
import "unsafe"
type Pack uint64
var (
Base16384 = newbasepack(0x4e00, 0x3d00, 14)
Base8192 = newbasepack(0xac00, 0xcc00, 13)
Base256 = newbasepack(0x1100, 0x0000, 4)
)
func newbasepack(off, til uint16, bit uint8) Pack {
b, err := NewBase(off, til, bit)
if err != nil {
panic(err)
}
return b.Pack()
}
func New(pack Pack) *Base {
b := &Base{}
*(*Pack)(unsafe.Pointer(b)) = pack
return b
}
func (b *Base) Pack() Pack {
return *(*Pack)(unsafe.Pointer(b))
}

15
slice.go Normal file
View File

@@ -0,0 +1,15 @@
package unibase2n
import "unsafe"
// slice is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
//
// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the
// data it references will not be garbage collected.
type slice struct {
data unsafe.Pointer
len int
cap int
}