//-----------------------------------------------------------------------------
// AScript hash module
//-----------------------------------------------------------------------------
#ifndef __MODULE_HASH_H__
#define __MODULE_HASH_H__

#include <ascript.h>
#include <md5.h>

AScript_BeginModule(hash)
//-----------------------------------------------------------------------------
// HashBase declaration
//-----------------------------------------------------------------------------
class HashBase : public Stream {
protected:
	Binary _digest;
public:
	inline HashBase(Signal sig) : Stream(sig, ATTR_Infinite | ATTR_Writable) {}
	virtual void Init() = 0;
	virtual void Finish() = 0;
	virtual const Binary &GetDigest() = 0;
	virtual size_t DoRead(Signal sig, void *buff, size_t len);
	virtual size_t DoWrite(Signal sig, const void *buff, size_t len) = 0;
	virtual bool DoSeek(Signal sig, long offset, size_t offsetPrev, SeekMode seekMode);
	virtual bool DoFlush(Signal sig);
	virtual bool DoClose(Signal sig);
};

//-----------------------------------------------------------------------------
// Object_Hash declaration
//-----------------------------------------------------------------------------
AScript_DeclarePrivClass(Hash);

class Object_Hash : public Object_Stream {
public:
	AScript_DeclareObjectAccessor(Hash)
private:
	String _name;
public:
	Object_Hash(Environment &env, HashBase *pHash, const char *name);
	Object_Hash(Class *pClass, HashBase *pHash, const char *name);
	virtual ~Object_Hash();
	virtual Object *Clone() const;
	virtual Value DoPropGet(Signal sig, const Symbol *pSymbol, bool &evaluatedFlag);
	virtual String ToString(Signal sig, bool exprFlag);
	inline HashBase &GetHash() {
		return *dynamic_cast<HashBase *>(&GetStream());
	}
};

//-----------------------------------------------------------------------------
// Hash_MD5 declaration
//-----------------------------------------------------------------------------
class Hash_MD5 : public HashBase {
private:
	md5_state_t _state;
public:
	Hash_MD5(Signal sig);
	virtual void Init();
	virtual const char *GetName() const;
	virtual size_t DoWrite(Signal sig, const void *buff, size_t len);
	virtual void Finish();
	virtual const Binary &GetDigest();
};

//-----------------------------------------------------------------------------
// Hash_SHA1 declaration
//-----------------------------------------------------------------------------
class Hash_SHA1 : public HashBase {
public:
	Hash_SHA1(Signal sig);
	virtual void Init();
	virtual const char *GetName() const;
	virtual size_t DoWrite(Signal sig, const void *buff, size_t len);
	virtual void Finish();
	virtual const Binary &GetDigest();
};

//-----------------------------------------------------------------------------
// Hash_CRC32 declaration
//-----------------------------------------------------------------------------
class Hash_CRC32 : public HashBase {
private:
	CRC32 _crc32;
public:
	Hash_CRC32(Signal sig);
	virtual void Init();
	virtual const char *GetName() const;
	virtual size_t DoWrite(Signal sig, const void *buff, size_t len);
	virtual void Finish();
	virtual const Binary &GetDigest();
};

}}

#endif
