1// Copyright 2016, Joe Tsai. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE.md file.
4
5// +build gofuzz
6
7// This file exists to export internal implementation details for fuzz testing.
8
9package bzip2
10
11func ForwardBWT(buf []byte) (ptr int) {
12	var bwt burrowsWheelerTransform
13	return bwt.Encode(buf)
14}
15
16func ReverseBWT(buf []byte, ptr int) {
17	var bwt burrowsWheelerTransform
18	bwt.Decode(buf, ptr)
19}
20
21type fuzzReader struct {
22	Checksums Checksums
23}
24
25// updateChecksum updates Checksums.
26//
27// If a valid pos is provided, it appends the (pos, val) pair to the slice.
28// Otherwise, it will update the last record with the new value.
29func (fr *fuzzReader) updateChecksum(pos int64, val uint32) {
30	if pos >= 0 {
31		fr.Checksums = append(fr.Checksums, Checksum{pos, val})
32	} else {
33		fr.Checksums[len(fr.Checksums)-1].Value = val
34	}
35}
36
37type Checksum struct {
38	Offset int64  // Bit offset of the checksum
39	Value  uint32 // Checksum value
40}
41
42type Checksums []Checksum
43
44// Apply overwrites all checksum fields in d with the ones in cs.
45func (cs Checksums) Apply(d []byte) []byte {
46	d = append([]byte(nil), d...)
47	for _, c := range cs {
48		setU32(d, c.Offset, c.Value)
49	}
50	return d
51}
52
53func setU32(d []byte, pos int64, val uint32) {
54	for i := uint(0); i < 32; i++ {
55		bpos := uint64(pos) + uint64(i)
56		d[bpos/8] &= ^byte(1 << (7 - bpos%8))
57		d[bpos/8] |= byte(val>>(31-i)) << (7 - bpos%8)
58	}
59}
60
61// Verify checks that all checksum fields in d matches those in cs.
62func (cs Checksums) Verify(d []byte) bool {
63	for _, c := range cs {
64		if getU32(d, c.Offset) != c.Value {
65			return false
66		}
67	}
68	return true
69}
70
71func getU32(d []byte, pos int64) (val uint32) {
72	for i := uint(0); i < 32; i++ {
73		bpos := uint64(pos) + uint64(i)
74		val |= (uint32(d[bpos/8] >> (7 - bpos%8))) << (31 - i)
75	}
76	return val
77}
78