/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 1, or (at your option)
** any later version.

** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.

** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com> --- January 1997
 */

/*
 * CPStr.h --- simple Pascal-C string
 */

#ifndef CPSTR_H
#define CPSTR_H

#include <string.h>
#include <stdlib.h>
#include <exception>

#include "Persistent.h"
#include "ustr.h"

#if TARGET_RT_MAC_MACHO || qUnix
#	ifndef HAVE_STRICMP
#		define stricmp strcasecmp
#	endif
#	ifndef HAVE_STRNICMP
#		define strnicmp strncasecmp
#	endif
#endif

/// Persistent P string
class PCPStr : public CPStr, public CPersistent
{
	UDECLARE_DYNAMIC(PCPStr)
public:
	// Construction
	inline PCPStr(const char* uniqueName, const char* defValue = 0L, kClassPersistent pclass = kNoClass);
	virtual ~PCPStr();

public:
	// Interface
	virtual unsigned int SizeOf(void) const;
	virtual const void* GetData(void) const;
	virtual void SetData(const void* ptr, unsigned int size);

	inline operator const unsigned char*() const;
	inline operator unsigned char*() EGCS_CONST;

	inline operator const char*() const;
	inline operator char*() EGCS_CONST;

	inline const char* operator=(const char* newstr);
	inline const unsigned char* operator=(const unsigned char* newstr);
};

/// Persistent C string
class PCStr : public CStr, public CPersistent
{
	UDECLARE_DYNAMIC(PCStr)
public:
	// Construction
	inline PCStr(const char* uniqueName, const char* defValue = 0L, kClassPersistent pclass = kNoClass);
	virtual ~PCStr();

public:
	// Interface
	virtual unsigned int SizeOf(void) const;
	virtual const void* GetData(void) const;
	virtual void SetData(const void* ptr, unsigned int size);

	inline operator const char*() const;
	inline operator char*() EGCS_CONST;

	inline const char* operator=(const char* newstr);
	inline const char* operator=(const unsigned char* newstr);
};

//////////////////////////////////////////////////////////////////////////
// PCPStr inline implementation

inline PCPStr::PCPStr(const char* uniqueName, const char* defValue /*= 0L*/, kClassPersistent pclass /*= kNoClass*/) 
	: CPStr(), CPersistent(uniqueName, pclass)
{
	if( defValue != 0L )
		*(CPStr*)this = defValue;
}

/// Access the string as a P string
inline PCPStr::operator const unsigned char*() const
{
	return *(CPStr*)this;
}

/// Access the string as a P string
inline PCPStr::operator unsigned char*() EGCS_CONST
{
	return *(CPStr*)this;
}

/// Access the string as a C string
inline PCPStr::operator const char*() const
{
	return *(CPStr*)this;
}

/// Access the string as a C string
inline PCPStr::operator char*() EGCS_CONST
{
	return *(CPStr*)this;
}

/// Set from a C String (0L is OK)
inline const char* PCPStr::operator=(const char* newstr)
{
	return ((CPStr*)this)->operator=(newstr);
}

/// Set from a P String (0L is OK)
inline const unsigned char* PCPStr::operator=(const unsigned char* newstr)
{
	return ((CPStr*)this)->operator=(newstr);
}

//////////////////////////////////////////////////////////////////////////
// PCStr inline implementation

inline PCStr::PCStr(const char* uniqueName, const char* defValue /*= 0L*/, kClassPersistent pclass /*= kNoClass*/)
	: CStr(), CPersistent(uniqueName, pclass)
{
	if( defValue != 0L )
		*(CStr*)this = defValue;
}

/// Access the string as a C string
inline PCStr::operator const char*() const
{
	return *(CStr*)this;
}

/// Access the string as a C string
inline PCStr::operator char*() EGCS_CONST
{
	return *(CStr*)this;
}

/// Set from a C String (0L is OK)
inline const char* PCStr::operator=(const char* newstr)
{
	TouchTimeStamp();
	return ((CStr*)this)->operator=(newstr);
}

/// Set from a P String (0L is OK)
inline const char* PCStr::operator=(const unsigned char* newstr)
{
	TouchTimeStamp();
	return ((CStr*)this)->operator=(newstr);
}

#endif /* CPSTR_H */
