// If the input is malformed, Decode returns the number
// of bytes decoded before the error.
func Decode(dst, src []byte) (int, error) {
- var i int
- for i = 0; i < len(src)/2; i++ {
- a, ok := fromHexChar(src[i*2])
+ i, j := 0, 1
+ for ; j < len(src); j += 2 {
+ a, ok := fromHexChar(src[j-1])
if !ok {
- return i, InvalidByteError(src[i*2])
+ return i, InvalidByteError(src[j-1])
}
- b, ok := fromHexChar(src[i*2+1])
+ b, ok := fromHexChar(src[j])
if !ok {
- return i, InvalidByteError(src[i*2+1])
+ return i, InvalidByteError(src[j])
}
dst[i] = (a << 4) | b
+ i++
}
if len(src)%2 == 1 {
// Check for invalid char before reporting bad length,
// since the invalid char (if present) is an earlier problem.
- if _, ok := fromHexChar(src[i*2]); !ok {
- return i, InvalidByteError(src[i*2])
+ if _, ok := fromHexChar(src[j-1]); !ok {
+ return i, InvalidByteError(src[j-1])
}
return i, ErrLength
}
}
}
+func BenchmarkDecode(b *testing.B) {
+ for _, size := range []int{256, 1024, 4096, 16384} {
+ src := bytes.Repeat([]byte{'2', 'b', '7', '4', '4', 'f', 'a', 'a'}, size/8)
+ sink = make([]byte, size/2)
+
+ b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
+ b.SetBytes(int64(size))
+ for i := 0; i < b.N; i++ {
+ Decode(sink, src)
+ }
+ })
+ }
+}
+
func BenchmarkDump(b *testing.B) {
for _, size := range []int{256, 1024, 4096, 16384} {
src := bytes.Repeat([]byte{2, 3, 5, 7, 9, 11, 13, 17}, size/8)