| // -*- Mode: C++ -*- |
| |
| namespace regtest { |
| |
| class Segment { |
| public: |
| Segment(size_t size, MTRandom *rand) |
| : size_(size), |
| seed_(rand->Rand32()), |
| seed_offset_(0), |
| data_(NULL) { |
| CHECK_GT(size_, 0); |
| } |
| |
| Segment(size_t size, uint32_t seed) |
| : size_(size), |
| seed_(seed), |
| seed_offset_(0), |
| data_(NULL) { |
| CHECK_GT(size_, 0); |
| } |
| |
| Segment(size_t size, uint8_t *data) |
| : size_(size), |
| seed_(0), |
| seed_offset_(0), |
| data_(data) { |
| CHECK_GT(size_, 0); |
| } |
| |
| size_t Size() const { |
| return size_; |
| } |
| |
| Segment Subseg(size_t start, size_t size) const { |
| CHECK_LE(start + size, size_); |
| if (data_) { |
| return Segment(size, data_ + start); |
| } else { |
| return Segment(size, seed_, seed_offset_ + start); |
| } |
| } |
| |
| void Fill(size_t seg_offset, size_t size, uint8_t *data) const { |
| CHECK_LE(seg_offset + size, size_); |
| if (data_) { |
| memcpy(data, data_ + seg_offset, size); |
| } else { |
| size_t skip = seg_offset + seed_offset_; |
| MTRandom gen(seed_); |
| MTRandom8 gen8(&gen); |
| while (skip--) { |
| gen8.Rand8(); |
| } |
| for (size_t i = 0; i < size; i++) { |
| data[i] = gen8.Rand8(); |
| } |
| } |
| } |
| |
| private: |
| // Used by Subseg() |
| Segment(size_t size, uint32_t seed, size_t seed_offset) |
| : size_(size), |
| seed_(seed), |
| seed_offset_(seed_offset), |
| data_(NULL) { |
| CHECK_GT(size_, 0); |
| } |
| |
| friend ostream& operator<<(ostream& os, const Segment &seg); |
| |
| size_t size_; // Size of this segment |
| |
| // For random segments |
| uint32_t seed_; // Seed used for generating byte sequence |
| size_t seed_offset_; // Seed positions the sequence this many bytes |
| // before its beginning. |
| |
| // For literal segments (data is not owned) |
| uint8_t *data_; |
| }; |
| |
| ostream& operator<<(ostream& os, const Segment &seg) { |
| if (seg.data_) { |
| for (size_t i = 0; i < seg.size_; i++) { |
| char buf[10]; |
| sprintf(buf, "%02x ", seg.data_[i]); |
| os << buf; |
| } |
| return os; |
| } else { |
| return os << "size=" << seg.size_ << ",seed=" << seg.seed_ |
| << ",skip=" << seg.seed_offset_; |
| } |
| } |
| |
| typedef map<xoff_t, Segment> SegmentMap; |
| |
| } // namespace regtest |