/*--------------------------------------------------------------------*//*:Ignore this sentence.
Copyright (C) 1999, 2001 SIL International. All rights reserved.

Distributable under the terms of either the Common Public License or the
GNU Lesser General Public License, as specified in the LICENSING.txt file.

File: StrAnsiHash.h
Responsibility: Sharon Correll
Last reviewed: Not yet.

Description:
    Functor classes to allow us to use StrAnsi as the key of a hash map.
-------------------------------------------------------------------------------*//*:End Ignore*/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef STRHASH_INCLUDED
#define STRHASH_INCLUDED

#include <cstddef>

/*----------------------------------------------------------------------------------------------
	Functor class for computing a hash value from a StrAnsi object (ANSI string).
	Modelled after HashStrUni functor class.
----------------------------------------------------------------------------------------------*/
class HashStrAnsi
{
public:
	// Constructors/destructors/etc.

	HashStrAnsi()
	{
	}
	~HashStrAnsi()
	{
	}

	// Other public methods

	int operator () (StrAnsi & staKey)
	{
		const schar * psz = staKey.Chars();
		int cchs = staKey.Length();
		int nHash = 0;

		while (cchs--)
			nHash += (nHash << 4) + *psz++;
		return nHash;
	}

//	int operator () (BSTR bstrKey, int cchwKey = -1);

	int operator () (StrAnsi * pstaKey, size_t cbKey)
	{
		Assert(pstaKey);
		Assert(cbKey == sizeof(StrAnsi));
		return operator()(*pstaKey);
	}
};

/*----------------------------------------------------------------------------------------------
	Functor class for comparing two StrAnsi objects (ANSI strings) for equality.
	Modelled after EqlStrUni functor class.
----------------------------------------------------------------------------------------------*/
class EqlStrAnsi
{
public:
	// Constructors/destructors/etc.

	EqlStrAnsi()
	{
	}
	~EqlStrAnsi()
	{
	}

	// Other public methods

	bool operator () (StrAnsi & staKey1, StrAnsi & staKey2)
	{
		const schar * psz1 = staKey1.Chars();
		const schar * psz2 = staKey2.Chars();
		if (psz1 == psz2)
			return true;
		if ((NULL == psz1) || (NULL == psz2))
			return false;

		auto cchs1 = staKey1.Length();
		auto cchs2 = staKey2.Length();
		if (cchs1 != cchs2)
			return false;
		return (0 == memcmp(psz1, psz2, cchs1 * sizeof(schar)));
	}

//	bool operator () (StrAnsi & staKey1, BSTR bstrKey2, int cchwKey2 = -1);

	bool operator () (StrAnsi * pstaKey1, StrAnsi * pstaKey2, size_t cbKey)
	{
		Assert(pstaKey1);
		Assert(pstaKey2);
		Assert(cbKey == sizeof(StrAnsi));
		return operator()(*pstaKey1, *pstaKey2);
	}

};


#endif // STRHASH_INCLUDED
