1 // -*- Mode: C++ -*-
2 
3 class Segment {
4  public:
Segment(size_t size,MTRandom * rand)5   Segment(size_t size, MTRandom *rand)
6     : size_(size),
7       seed_(rand->Rand32()),
8       seed_offset_(0),
9       data_(NULL) {
10     CHECK_GT(size_, 0);
11   }
12 
Segment(size_t size,uint32_t seed)13   Segment(size_t size, uint32_t seed)
14     : size_(size),
15       seed_(seed),
16       seed_offset_(0),
17       data_(NULL) {
18     CHECK_GT(size_, 0);
19   }
20 
Segment(size_t size,uint8_t * data)21   Segment(size_t size, uint8_t *data)
22     : size_(size),
23       seed_(0),
24       seed_offset_(0),
25       data_(data) {
26     CHECK_GT(size_, 0);
27   }
28 
Size()29   size_t Size() const {
30     return size_;
31   }
32 
Subseg(size_t start,size_t size)33   Segment Subseg(size_t start, size_t size) const {
34     CHECK_LE(start + size, size_);
35     if (data_) {
36       return Segment(size, data_ + start);
37     } else {
38       return Segment(size, seed_, seed_offset_ + start);
39     }
40   }
41 
Fill(size_t seg_offset,size_t size,uint8_t * data)42   void Fill(size_t seg_offset, size_t size, uint8_t *data) const {
43     CHECK_LE(seg_offset + size, size_);
44     if (data_) {
45       memcpy(data, data_ + seg_offset, size);
46     } else {
47       size_t skip = seg_offset + seed_offset_;
48       MTRandom gen(seed_);
49       MTRandom8 gen8(&gen);
50       while (skip--) {
51 	gen8.Rand8();
52       }
53       for (size_t i = 0; i < size; i++) {
54 	data[i] = gen8.Rand8();
55       }
56     }
57   }
58 
ToString()59   string ToString() const {
60     string r;
61     if (data_) {
62       for (size_t i = 0; i < size_; i++) {
63 	char buf[10];
64 	sprintf(buf, "%02x ", data_[i]);
65 	r.append(buf);
66       }
67     } else {
68       char buf[256];
69       sprintf(buf, "size=%ld,seed=%ud,skip=%ld", size_, seed_, seed_offset_);
70       r.append(buf);
71     }
72     return r;
73   }
74 
75 private:
76   // Used by Subseg()
Segment(size_t size,uint32_t seed,size_t seed_offset)77   Segment(size_t size, uint32_t seed, size_t seed_offset)
78     : size_(size),
79       seed_(seed),
80       seed_offset_(seed_offset),
81       data_(NULL) {
82     CHECK_GT(size_, 0);
83   }
84 
85   size_t size_;  // Size of this segment
86 
87   // For random segments
88   uint32_t seed_;  // Seed used for generating byte sequence
89   size_t seed_offset_;  // Seed positions the sequence this many bytes
90                         // before its beginning.
91 
92   // For literal segments (data is not owned)
93   uint8_t *data_;
94 };
95 
96 typedef map<xoff_t, Segment> SegmentMap;
97 typedef typename SegmentMap::const_iterator ConstSegmentMapIterator;
98 typedef typename SegmentMap::iterator SegmentMapIterator;
99