#include "sha1.h"
#include "linus_sha1.h"
#include <cstring>
#include <cstdio>

SHA1Hash::SHA1Hash() {}

SHA1Hash::SHA1Hash(const char * str) {
	blk_SHA_CTX ctx;
	blk_SHA1_Init(&ctx);
	blk_SHA1_Update(&ctx, (const unsigned char*)str, strlen(str));
	blk_SHA1_Final(data, &ctx);
}

SHA1Hash::SHA1Hash(const std::string str) {
	blk_SHA_CTX ctx;
        blk_SHA1_Init(&ctx);
        blk_SHA1_Update(&ctx, (const unsigned char*)str.c_str(), str.length());
        blk_SHA1_Final(data, &ctx);
}

SHA1Hash::SHA1Hash(const SHA1Hash & other) {
	memcpy(data, other.data, sizeof(unsigned char) * 20);
}

SHA1Hash & SHA1Hash::operator=(const SHA1Hash & other) {
	memcpy(data, other.data, sizeof(unsigned char) * 20);
	return *this;
}

std::string SHA1Hash::toHex() {
	char bfr[41];
	for(int i=0;i<20;++i)
		snprintf(bfr + 2*i, 3, "%02x", data[i]);
	return std::string(bfr);
}

void SHA1Hash::fromHex(std::string s) {
	if(s.length() != 40)
		return;
	for(int i=0;i<20;++i)
		data[i] = 16 * ((s[2*i] > '9') ? (s[2*i] - 87) : (s[2*i] - 48))
			+ ((s[2*i+1] > '9') ? (s[2*i+1] - 87) : (s[2*i+1] - 48));
}

void SHA1Hash::set(const unsigned char * from) {
	memcpy(data, from, sizeof(unsigned char) * 20);
}

void SHA1Hash::get(unsigned char * to) const {
	memcpy(to, data, sizeof(unsigned char) * 20);
}

bool SHA1Hash::operator==(const SHA1Hash & other) const {
	bool res = true;
	for(int i=0;i<20;++i)
		res &= (other.data[i] == data[i]);
	return res;
}

bool SHA1Less::operator()(const SHA1Hash & lhs, const SHA1Hash & rhs) const {
	int i;
	for(i=0;i<20;++i) {
		if(lhs.data[i] < rhs.data[i])
			break;
		else if(lhs.data[i] > rhs.data[i])
			return false;
	}

	return (i < 20);
}

