
#ifndef DKUTIL_SIGNATURE_SIGNATURE_BUFFER_HPP
#define DKUTIL_SIGNATURE_SIGNATURE_BUFFER_HPP


//#include <dkutil/shared_buffer.hpp>
#include <dkutil/signature/interface.hpp>

namespace dkutil{

///signature系(CSHA1やCMD5) 用バッファー 計算結果をそのままの値でserializeする時に使ってね。
template<class SignatureClass_>
class signature_buffer_bin{
public:
	typedef SignatureClass_ policy_type;
	typedef typename signature_buffer_bin<policy_type> self_type;
	signature_buffer_bin(){}
	static inline size_t size(){
		return policy_type::bin_size;
	}
	uint8 *get(){
		return mBinBuffer;
	}
	const uint8 *get()const{
		return mBinBuffer;
	}
	void serialize(ISerializeStream *p){
		p->store(mBinBuffer,size());
	}
	///@return シリアライズする時のファイルに出力するサイズを返す。
	static inline serialize_size(){
		return size();
	}
	void set_output(policy_type *pt){
		pt->final();
		pt->getSignature(mBinBuffer,size(),binary_signature);
	}
	friend bool operator==(const self_type &x,const self_type &y)
	{
		return 0==memcmp(x.get(),y.get(),x.size());
	}
	friend bool operator!=(const self_type &x,const self_type &y)
	{
		return !(x==y);
	}
	void clear(){
		memset(mBinBuffer,0,sizeof(mBinBuffer));
	}


private:
	uint8 mBinBuffer[policy_type::bin_size];
};


///signature系(CSHA1やCMD5) 用バッファー 計算結果を文字列にした値をserializeする時に使ってね。
template<class SignatureClass_>
class signature_buffer_str{
public:
	typedef SignatureClass_ policy_type;
	typedef typename signature_buffer_str<policy_type> self_type;

	signature_buffer_str(){}
	static inline size_t size(){
		return policy_type::str_size;
	}


	char *get(){
		return mStrBuffer;
	}
	
	const char *get()const{
		return mStrBuffer;
	}
	size_t length()const{
		return strlen(get());
	}
	static size_t buffer_size(){
		return policy_type::str_size;
	}

	
	void set_output(policy_type *pt)
	{
		pt->final();
		pt->getSignature((BYTE *)mStrBuffer,size(),string_signature);
	}
	void serialize(ISerializeStream *p){
		p->store(mStrBuffer,size());
	}
	///@return シリアライズする時のファイルに出力するサイズを返す。
	static inline serialize_size(){
		return size();
	}
	friend bool operator==(const self_type &x,const self_type &y)
	{
		return DKUTIL_SUCCEEDED(
			dkc_strcmp(x.get(),x.length(),y.get(),y.length())
		);
	}
	friend bool operator!=(const self_type &x,const self_type &y)
	{
		return !(x==y);
	}
	friend bool operator==(const self_type &x,const char *s){
		return DKUTIL_SUCCEEDED(
			dkc_strcmp(x.get(),x.length(),s,strlen(s))
		);
	}
	friend bool operator!=(const self_type &x,const char *s){
		return !(x==y);
	}
	void clear(){
		memset(mStrBuffer,0,sizeof(mStrBuffer));
	}
private:
	
	char mStrBuffer[policy_type::str_size];
};


}//end of dkutil namespace



#endif//end of include once

