in pkg/unpack/unpack.go [40:101]
func UnpackBlock(unpacked, packed []byte, radix, pre int) (int, error) {
if len(packed) == 0 || len(unpacked) == 0 {
return 0, nil
}
dpw := ycd.DigitsPerWord(radix)
unpackedLen := UnpackedLen(int64(len(packed)-1), radix) - int64(pre)
if int64(len(unpacked)) < unpackedLen {
return 0, fmt.Errorf("%w: required = %v bytes, actual buffer = %v bytes",
ErrBufferTooSmall, unpackedLen, len(unpacked))
}
// Unpack the first word with pre.
// Copy dpw-pre bytes.
s := strconv.FormatUint(binary.LittleEndian.Uint64(packed), radix)
nz := dpw - len(s)
if nz < 0 {
return 0, fmt.Errorf("%w: word = %16x, unpacked = %s",
ErrInvalidWord, packed[:WordSize], s)
}
nzNeeded := nz - pre
if nzNeeded < 0 {
nzNeeded = 0
}
n := copy(unpacked, zeros[:nzNeeded])
if n < dpw-pre && n < len(unpacked) {
if nz < pre {
n += copy(unpacked[n:], s[pre-nz:dpw-pre-n+(pre-nz)])
} else {
n += copy(unpacked[n:], s[:dpw-pre-n])
}
}
if len(packed) == WordSize {
return n, nil
}
// Process until the second last word.
for i := WordSize; i < len(packed)-WordSize; i += WordSize {
s := strconv.FormatUint(binary.LittleEndian.Uint64(packed[i:]), radix)
nz := dpw - len(s)
if nz < 0 {
return n, fmt.Errorf("%w: word = %16x, unpacked = %s", ErrInvalidWord,
packed[i:i+WordSize], s)
}
n += copyWithZero(unpacked[n:], s, nz)
}
// Process the last word with post.
s = strconv.FormatUint(binary.LittleEndian.Uint64(packed[len(packed)-WordSize:]), radix)
nz = dpw - len(s)
if nz < 0 {
return n, fmt.Errorf("%w: word = %16x, unpacked = %s", ErrInvalidWord,
packed[len(packed)-WordSize:], s)
}
n += copy(unpacked[n:], zeros[:nz])
if n < len(unpacked) {
n += copy(unpacked[n:], s)
}
return n, nil
}