diff options
| author | Patrick Simianer <p@simianer.de> | 2013-01-21 12:29:43 +0100 | 
|---|---|---|
| committer | Patrick Simianer <p@simianer.de> | 2013-01-21 12:29:43 +0100 | 
| commit | 50f22047eb1b7f2d60e85cdcf0fcd86342e50523 (patch) | |
| tree | 730dabaf2fa57b1e4536d40f036b46795d37f289 /klm/util/stream/stream.hh | |
| parent | 8b399cb09513cd79ed4182be9f75882c1e1b336a (diff) | |
| parent | 608886384da40aedfabd629c882b8ea9b3f6348e (diff) | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'klm/util/stream/stream.hh')
| -rw-r--r-- | klm/util/stream/stream.hh | 74 | 
1 files changed, 74 insertions, 0 deletions
diff --git a/klm/util/stream/stream.hh b/klm/util/stream/stream.hh new file mode 100644 index 00000000..6ff45b82 --- /dev/null +++ b/klm/util/stream/stream.hh @@ -0,0 +1,74 @@ +#ifndef UTIL_STREAM_STREAM__ +#define UTIL_STREAM_STREAM__ + +#include "util/stream/chain.hh" + +#include <boost/noncopyable.hpp> + +#include <assert.h> +#include <stdint.h> + +namespace util { +namespace stream { + +class Stream : boost::noncopyable { +  public: +    Stream() : current_(NULL), end_(NULL) {} + +    void Init(const ChainPosition &position) { +      entry_size_ = position.GetChain().EntrySize(); +      block_size_ = position.GetChain().BlockSize(); +      block_it_.Init(position); +      StartBlock(); +    } + +    explicit Stream(const ChainPosition &position) { +      Init(position); +    } + +    operator bool() const { return current_ != NULL; } +    bool operator!() const { return current_ == NULL; } + +    const void *Get() const { return current_; } +    void *Get() { return current_; } + +    void Poison() { +      block_it_->SetValidSize(current_ - static_cast<uint8_t*>(block_it_->Get())); +      ++block_it_; +      block_it_.Poison(); +    } +     +    Stream &operator++() { +      assert(*this); +      assert(current_ < end_); +      current_ += entry_size_; +      if (current_ == end_) { +        ++block_it_; +        StartBlock(); +      } +      return *this; +    } + +  private: +    void StartBlock() { +      for (; block_it_ && !block_it_->ValidSize(); ++block_it_) {} +      current_ = static_cast<uint8_t*>(block_it_->Get()); +      end_ = current_ + block_it_->ValidSize(); +    } + +    uint8_t *current_, *end_; + +    std::size_t entry_size_; +    std::size_t block_size_; + +    Link block_it_; +}; + +inline Chain &operator>>(Chain &chain, Stream &stream) { +  stream.Init(chain.Add()); +  return chain; +} + +} // namespace stream +} // namespace util +#endif // UTIL_STREAM_STREAM__  | 
