
#ifndef __hash_repl__
#define __hash_repl__

#include "hash.hh"
#include "hash_string.hh"
#include "clone_ptr.hh"
#include "repl.hh"
#include "hash_repl-p.hh"
#include "map_repl.hh"
#include "hash_repl.hh"
#include "refcount.hh"

namespace afilter {

  using namespace autil;

  template <typename T>
  //Note: invalue is expected to be a char
  class HashRepl : public T::Base,
		   public MapReplBase<typename T::InValue, typename T::Value>
  {
  public:
    typedef typename T::Base        Base;
    typedef typename T::Itr         Itr;
    typedef typename T::InValue     InValue;
    typedef typename T::Value       Value;
    typedef typename T::ItrRoot     ItrRoot;
    typedef typename T::Buffer      Buffer;
    typedef typename T::SingleMulti SingleMulti;
    
    typedef MapReplBase<typename T::InValue, typename T::Value> M;
    typedef typename M::InString InString;
    typedef typename M::String   String;

  private:
    InValue          begin_char;
    InValue          end_char;
    typedef hash_map<InString,String,HashString<InString> > Lookup;
    RefCount<Lookup> lookup;
    InString         inbuf;
    ClonePtr<Itr> k;
  
  public:

    HashRepl() {}
    HashRepl(ConfigData *, const ReplOpts *o)
      : begin_char(static_cast<const HashReplOpts *>(o)->begin_char)
      , end_char  (static_cast<const HashReplOpts *>(o)->end_char) 
    {}

    Base * clone() const {return new HashRepl(*this);}
    void assign(const Base * other) {*this = *(const HashRepl *)(other);}

    void add (const InValue * k, const Value * v);
    bool fill(InValue c, Itr * i, Buffer * buffer);
  };
}
#endif
