diff --git a/decode.go b/decode.go index 71b4d4d..402307c 100644 --- a/decode.go +++ b/decode.go @@ -51,8 +51,42 @@ func (bs Base) Decode(data []byte) (out []byte) { return } +func (bs Base) DecodeTo(data, out []byte) { + if len(data) == 0 || len(data)%2 != 0 { + return + } + if bits.OnesCount8(bs.bit) == 1 { // 2的幂永无offset, 无需管til (1/2/4/8) + switch bs.bit { + case 8: + dec16blk8(bs.off, data, out) + case 4: + mask := uint32(bs.off) | uint32(bs.off)<<16 + dec32blk4(mask, data, out) + case 2: + mask := uint64(bs.off) | uint64(bs.off)<<16 | uint64(bs.off)<<32 | uint64(bs.off)<<48 + dec64blk2(mask, data, out) + case 1: + mask64 := uint64(bs.off) | uint64(bs.off)<<16 | uint64(bs.off)<<32 | uint64(bs.off)<<48 + mask := uint128be{a: mask64, b: mask64} + dec128blk1(mask, data, out) + } + return + } + switch bs.bit { + case 3, 5, 7, 9, 11, 13, 15: + mask64 := uint64(bs.off) | uint64(bs.off)<<16 | uint64(bs.off)<<32 | uint64(bs.off)<<48 + mask := uint128be{a: mask64, b: mask64} + dec128blk(mask, bs.bit, data, out) + case 6, 10, 12, 14: + mask := uint64(bs.off) | uint64(bs.off)<<16 | uint64(bs.off)<<32 | uint64(bs.off)<<48 + dec64blk(mask, bs.bit, data, out) + } +} + // dec64blk2 for bit 2 -// len(in)>0, len(in)%8==0, len(out)==len(in)/8 +// +// len(in)>0, len(in)%8==0, len(out)==len(in)/8 +// //go:nosplit func dec64blk2(mask uint64, in, out []byte) { for i := range out { @@ -70,7 +104,9 @@ func dec64blk2(mask uint64, in, out []byte) { } // dec32blk4 for bit 4 -// len(in)>0, len(in)%4==0, len(out)==len(in)/4 +// +// len(in)>0, len(in)%4==0, len(out)==len(in)/4 +// //go:nosplit func dec32blk4(mask uint32, in, out []byte) { for i := range out { @@ -84,7 +120,9 @@ func dec32blk4(mask uint32, in, out []byte) { } // dec16blk8 for bit 8 -// len(in)>0, len(in)%2==0, len(out)==len(in)/2 +// +// len(in)>0, len(in)%2==0, len(out)==len(in)/2 +// //go:nosplit func dec16blk8(mask uint16, in, out []byte) { for i := range out { @@ -95,7 +133,9 @@ func dec16blk8(mask uint16, in, out []byte) { } // dec128blk for bit 3 5 6 7 9 11 13 15 -// len(in)>0, len(in)%2==0, len(out)==len(in)/16*bit+offset +// +// len(in)>0, len(in)%2==0, len(out)==len(in)/16*bit+offset +// //go:nosplit func dec128blk(mask uint128be, bit uint8, in, out []byte) { var tmp [16]byte @@ -176,7 +216,9 @@ func dec128blk(mask uint128be, bit uint8, in, out []byte) { } // dec64blk for bit 6 10 12 14 -// len(in)>0, len(in)%2==0, len(out)==len(in)/16*bit+offset +// +// len(in)>0, len(in)%2==0, len(out)==len(in)/16*bit+offset +// //go:nosplit func dec64blk(mask uint64, bit uint8, in, out []byte) { var tmp [8]byte diff --git a/encode.go b/encode.go index f6c1b32..b28afad 100644 --- a/encode.go +++ b/encode.go @@ -11,6 +11,20 @@ func (bs Base) Encode(data []byte) (out []byte) { return nil } out = make([]byte, outlen) + bs.encode(data, out, outlen, offset) + return +} + +// EncodeTo data to base2n +func (bs Base) EncodeTo(data, out []byte) { + outlen, offset := bs.EncodeLen(len(data)) + if outlen <= 0 || offset < 0 { + return + } + bs.encode(data, out, outlen, offset) +} + +func (bs Base) encode(data, out []byte, outlen, offset int) { switch bs.bit { case 3, 5, 7, 9, 11, 13, 15: mask64 := uint64(bs.off) | uint64(bs.off)<<16 | uint64(bs.off)<<32 | uint64(bs.off)<<48 @@ -33,11 +47,12 @@ func (bs Base) Encode(data []byte) (out []byte) { if offset > 0 { binary.BigEndian.PutUint16(out[outlen-2:outlen], bs.til+uint16(offset)) } - return } // enc128blk for bit 3 5 6 7 9 11 13 15 -// len(in)>0, len(out)==len(in)/bit*16 +// +// len(in)>0, len(out)==len(in)/bit*16 +// //go:nosplit func enc128blk(mask uint128be, bit uint8, in, out []byte) { // 由于最后一次处理有读取越界, 因此作扩展 @@ -113,7 +128,9 @@ func enc128blk(mask uint128be, bit uint8, in, out []byte) { } // enc64blk for bit 6 10 12 14 -// len(in)>0, len(out)==len(in)/bit*16 +// +// len(in)>0, len(out)==len(in)/bit*16 +// //go:nosplit func enc64blk(mask uint64, bit uint8, in, out []byte) { // 由于最后一次处理有读取越界, 因此作扩展