summaryrefslogtreecommitdiff
path: root/xdelta3/go/src/xdelta/rstream.go
blob: 1d560318b71452872fd7462d5c7ac0e91ea1d851 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package xdelta


import (
	"io"
	"math/rand"
)

const (
	blocksize = 16380  // A factor of 7
)

func WriteRstreams(seed, offset, len int64,
	first, second io.WriteCloser) {
	go writeOne(seed, 0, len, first)
	go writeOne(seed, offset, len, second)
}

func writeOne(seed, offset, len int64, stream io.WriteCloser) error {
	if offset != 0 {
		// Fill with other random data until the offset
		if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil {
			return err
		}
	}
	if err := writeRand(rand.New(rand.NewSource(seed)),
		len - offset, stream); err != nil {
		return err
	}
	return stream.Close()
}

func writeRand(r *rand.Rand, len int64, s io.Writer) error {
	blk := make([]byte, blocksize)
	for len > 0 {
		fillRand(r, blk)
		c := blocksize
		if len < blocksize {
			c = int(len)
		}
		if _, err := s.Write(blk[0:c]); err != nil {
			return err
		}
		len -= int64(c)
	}
	return nil
}

func fillRand(r *rand.Rand, blk []byte) {
	for p := 0; p < blocksize; {
		v := r.Int63()
		for i := 7; i != 0; i-- {
			blk[p] = byte(v)
			p++
			v >>= 8
		}
	}
}