/*------------------------------------------------------------------------------*
 * File Name: string.h															*
 * Creation: CPY 4/2/2001														*
 * Purpose: Origin C header	for string class and other related functions		*
 * Copyright (c) OriginLab Corp.2001											*
 * All Rights Reserved															*
 *------------------------------------------------------------------------------*/

#ifndef _STRING_H
#define _STRING_H

#include <common.h> // must always include this
#include <OC_const.h> // consts used in Origin internal functions

 
typedef vector<string> StringArray;

/** >Composite Data Types
		An Origin C string is a null terminated array of characters similar to objects
		created using the MFC CString class. The Origin C string class includes many
		useful methods for manipulating strings (text data). An array of strings has been
		implmented using the following type definition: typedef vector<string> StringArray;
	Example:
		string str = "  abcdefg   ";
		str.TrimRight();
		str.TrimLeft();
		ASSERT( str.Compare("abcdefg")==0 );
		ASSERT( str.Compare("ABCDEFG")!=0 );
		ASSERT( str.CompareNoCase("ABCDEFG")==0 );
		str = str.Left(5);
		str = str.Mid(1);
		ASSERT( str.Compare("bcde")==0 );
		ASSERT( str.Find('d')==2 );
*/
class string  
{

public:

	/**
		Remarks:
			Default constructor, creates a new empty string object
		Example:
			string str1;  //empty string
			ASSERT(str1.IsEmpty());
		Parameters:
			None.
		Return:
			None.
	*/
	string( );
	
	/**
		Remarks:
			Constructs a string object from a null-terminated string.
		Example:
			string str2("cow");  //create from a string literal
			ASSERT(str2.Compare("cow")==0);
		Parameters:
			lpcszSrc = A null-terminated string to be copied into this string object.
		Return:
			None.
	*/
	string( LPCSTR lpcszSrc );
	
	/**
		Remarks:
			Constructs a string object from a character that is repeated nRepeat times.
		Example:
			string str3('a',6);  
			ASSERT(str3.Compare("aaaaaa")==0);
		Parameters:
			ch = A single character to be repeated nRepeat times.
			nRepeat = The repeat count for ch.
		Return:
			None.
	*/
	string( char ch, int nRepeat = 1 );	
		
	/**
		Remarks:
			Constructs a string object from an array of characters of length nlength,
			not null-terminated.
		Example:
			char * str="Origin C";
			int nLength=8;
			string str4(str,nLength);
			ASSERT(str4.Compare("Origin C")==0);
		Parameters:
			lpch = A pointer to an array of characters.
			nLength = length of characters.
		Return:
			None.
	*/
	string( LPCTSTR lpch, int nLength );

#ifdef	ORIGIN_COM_SUPPORT
	/**
			Constructs a string object from any _VARIANT type variable which holds a string
		Remarks:
			This function is available only for OriginPro versions, or with a special COM enabled license
		Example:
			void test()
			{
			   _VARIANT obj;
			   string s = "Hello";
			   obj = s;
			   string str = obj;
			}
 
		Parameters:
			var = a _VARIANT object
		Return:
			None.
	*/
	string( _VARIANT var );
	
#endif //#ifdef	ORIGIN_COM_SUPPORT

#if  _OC_VER > 0x0703
	/**
			Set the content of this string from a vector of bytes
		Example:
			vector<byte> vTemp = {'A','B','C','D'};
			string str ="something to make it longer";
			str.SetBytes(vTemp);
			ASSERT(str.Compatre("ABCD") == 0);
			
		Parameters:
			vb = [in] vector of bytes to be put into this string
		Return:
			Returns TRUE on success
		SeeAlso:
			vectorbase::SetBytes
	*/
 	BOOL     SetBytes(vector<byte>& vb);

	/**
			Copy the charactors of this string into a byte vector
		Example:
			string str = "ABCD";
			vector<byte> vResult;
			str.GetBytes(vResult);
			ASSERT(vResult.GetSize() == 4);
		Parameters:
			vb = [out] vector of bytes to receive the charactors from this string
		Return:
			Returns TRUE on success
		SeeAlso:
			vectorbase::GetBytes
	*/
 	BOOL     GetBytes(vector<byte>& vb);
#endif // _OC_VER > 0x0703
	/**
		Remarks:
			This member function outputs the string. 
		Example:
			string str="Hello World";
			str.Write(WRITE_OUTPUT_LOG);  //Hello World typed out to the Results Log
		Parameters:
			iDestination = one of enum {WRITE_SCRIPT_WINDOW, WRITE_STATUS_BAR, WRITE_OUTPUT_LOG, WRITE_MESSAGE_BOX, WRITE_COMPILER_OUTPUT};
		Return:
			None.
		SeeAlso:
			string::WriteLine
	*/
	void	Write( int iDestination );// 0 = ScriptWindow
	
	/**
		Remarks:
			This member function outputs the string adding return and
			newline characters automatically. 
		Example:
			string str="Hello World";
			str.WriteLine(2);  //Hello World typed out to the Results Log cursor is at next line
		Parameters:
			iDestination = one of enum {WRITE_SCRIPT_WINDOW, WRITE_STATUS_BAR, WRITE_OUTPUT_LOG, WRITE_MESSAGE_BOX, WRITE_COMPILER_OUTPUT};
		Return:
			None.
		SeeAlso:
			string::Write
	*/
	void	WriteLine( int iDestination );// will add \r\n automatically

	
	/**
		Remarks:
			This member function formats and stores a series of characters 
			and values in the string. Each optional argument (if any) is
			converted and output according to the corresponding format 
			specification in lpcszFormat.  Please note that it is your responsibility
			to match the data type with the correct formatting specification.
		Example1:
			char sz[10] = "abcdefg";
			int nn = 10;
			double dd = 3.1416;
			string str;
			str.Format("Results = %s, %d, %5.4f", sz, nn, dd);
			ASSERT(0 == str.Compare("Results = abcdefg, 10, 3.1416"));

		Example2:
			// the following usage will generate runtime error due to 
			// incorrect data being used
			string str;
			str.Format("x1=%f, x2=%f", 5, 3.4); // 5 is not a double, will generate runtime error
			str.Format("x1=%f, x2=%f", 5.0, 3.4);// this will work correctly

		Parameters:
			lpcszFormat = A format-control string.
		Return:
			none.
		SeeAlso:
			printf
	*/
	void	Format( LPCSTR lpcszFormat, ... );
	
	
	/**
		Remarks:
			This member function returns the number of bytes (or number
			of characters in this string object.  The count does not 
			include a null terminator.
		Example:
			string str1( "cow" );
			ASSERT( str1.GetLength() == 3 );
		Parameters:
			None.
		Return:
			An integer value equal to the length (number of bytes minus 
			the null character) of this string.
	*/
	int		GetLength( );		

	/**
		Remarks:
			This member function with no parameters trims leading whitespace
			characters from the string.  It removes newline, space, and tab
			characters.
		Example:
			string str="   Hello World";
			str.TrimLeft();
			ASSERT(str.Compare("Hello World")==0);
		Parameters:
			None.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/
	void	TrimLeft( );
	
	/**
		Remarks:
			Remove a particular character from this string.
		Example:
			string str="Hello World";
			str.TrimLeft('H');
			ASSERT(str.Compare("ello World")==0);
		Parameters:
			chTarget = character to be trimmed.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/		
	void	TrimLeft( char chTarget );
	
	/**
		Remarks:
			Remove a group of characters from this string.
		Example:
			string str="****Hello World";
			str.TrimLeft("****");
			ASSERT(str.Compare("Hello World")==0);
		Parameters:
			lpszTargets = A pointer to a string containing the target
			characters to be trimmed.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/
	void	TrimLeft( LPCSTR lpszTargets );
	
	/**
		Remarks:
			This member function with no parameters trims trailing 
			whitespace characters from the string. It removes trailing 
			newline, space, and tab characters from the string. 
		Example:
			string str="Hello World    ";
			str.TrimRight();
			ASSERT(str.Compare("Hello World")==0);
		Parameters:
			None.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/
	void	TrimRight( );
	
	/**
		Remarks:
			Removes a particular character from the end of a string. 
		Example:
			string str="Hello World";
			str.TrimRight('d');
			ASSERT(str.Compare("Hello Worl")==0);
		Parameters:
			chTarget = character to be trimmed.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/
	void    TrimRight( char chTarget );
	
	/**
		Remarks:
			Removes a particular group of character from the end of a 
			string. 
		Example:
			string str="Hello World****";
			str.TrimRight("****");
			ASSERT(str.Compare("Hello World")==0);
		Parameters:
			lpszTargets = A pointer to a string containing the target
			characters to be trimmed.
		Return:
			None.
		SeeAlso:
			string::Mid, string::Left, string::Right, string::MakeUpper, string::MakeLower, string::Format
	*/
	void	TrimRight( LPCSTR lpszTargets );
	
	/**
		Remarks:
			Extracts the leftmost nCount characters from this string
			object and returns a copy of the extracted substring. If
			nCount exceeds the string length, then the entire string 
			is extracted.
		Example:
			string str1("abcdef");
			ASSERT ( 0==str1.Left(2).Compare("ab") );
		Parameters:
			nCount = The number of characters to extract starting from the
			left.
		Return:
			A string object containing a copy of the specified range of 
			characters. Note that the returned string object may be 
			empty. 
		SeeAlso:
			string::Right
	*/
	string  Left( int nCount );	
		
	/**
		Remarks:
			Extracts the rightmost nCount characters from this string
			object and returns a copy of the extracted substring. If
			nCount exceeds the string length, then the entire string is
			extracted. 
		Example:
			string str1("abcdef");
			ASSERT ( 0 == str1.Right(2).Compare("ef") );
		Parameters:
			nCount = The number of characters to extract starting from the
			right.
		Return:
			A string object containing a copy of the specified range of 
			characters. Note that the returned string object may be 
			empty. 
		SeeAlso:
			string::Left
	*/
	string  Right( int nCount );
	
	/**
		Remarks:
			This member function performs a case-sensitive comparison 
			of this string object with another string.
		Example:
			string str1("abc");
			string str2("abd");
			ASSERT(str1.Compare("abb")==1);
			ASSERT(str1.Compare(str2)==-1);
			ASSERT(str1.Compare("abc")==0);
		Parameters:
			lpsz = The other string used for comparison.
		Return:
			Zero if the strings are identical, < 0 if this string 
			object is less than lpsz, or > 0 if this string object
			is greater than lpsz.
		SeeAlso:
			string::CompareNoCase.
	*/
	int		Compare( LPCSTR lpsz );	
	
	/**
		Remarks:
			This member function performs a case-insensitive comparison 
			of this string object with another string.
		Example:
			string str1("abc");
			string str2("ABD");
			ASSERT(str1.CompareNoCase("abb")==1);
			ASSERT(str1.CompareNoCase(str2)==-1);
			ASSERT(str1.CompareNoCase("ABC")==0);
		Parameters:
			lpsz = The other string used for comparison.
		Return:
			Zero if the strings are identical, < 0 if this string 
			object is less than lpsz, or > 0 if this string object
			is greater than lpsz.
		SeeAlso:
			string::Compare
	*/
	int		CompareNoCase( LPCSTR lpsz );
	
	/**
		Remarks:
			This overloaded member function searches this string for the
			first match of a single character.
		Example:
			string str1("abcdef");
			ASSERT(str1.Find('c')==2);
		Parameters:
			ch = A single character to search for.
		Return:
			Returns the zero-based index of the first character in this string
			object that matches the character.  It will return -1 if the character
			is not found.
		SeeAlso:
			string::ReverseFind, string::FindOneOf
	*/
	int		Find( char ch );
	
	/**
		Remarks:
			This overloaded member function searches this string for the
			first match of a substring.
		Example:
			string str2("abcdef");
			ASSERT(str2.Find("de") == 3);
		Parameters:
			lpszsub = A substring to search for.
		Return:
			Returns the zero-based index of the first character in this string
			object that matches the character.  It will return -1 if the character
			is not found.
		SeeAlso:
			string::ReverseFind, string::FindOneOf
	*/
	int		Find( LPCSTR lpszSub );
	
	/**
		Remarks:
			This overloaded member function searches this string for the
			match of a character.
		Example:
			string str3("Hello World");
			ASSERT(str3.Find('o',5)==7);
		Parameters:
			ch = A single character to search for.
			nStart = The index of the character in the string to begin the
			search with.  If nStart equals 0, search starts from the
			beginning.  The character at nStart is excluded from the search
			 if nStart is not equal to 0.
		Return:
			Returns the zero-based index of the first character in this string
			object that matches the character.  It will return -1 if the character
			is not found.
		SeeAlso:
			string::ReverseFind, string::FindOneOf
	*/
	int		Find( char ch, int nStart );
	
	/**
		Remarks:
			This overloaded member function searches this string for the
			match of a substring.
		Example:
			string str4("Happy Birthday");
			ASSERT(str4.Find("day",4)==11);
		Parameters:
			pstr = A pointer to a string to search for.
			nStart = The index of the character in the string to begin the
			search with.  If nStart equals 0, search starts from the
			beginning.  The character at nStart is excluded from the search
			 if nStart is not equal to 0.
		Return:
			Returns the zero-based index of the first character in this string
			object that matches the requested substring.  It will return -1 if 
			the character is not found.
		SeeAlso:
			string::ReverseFind, string::FindOneOf
	*/
	int		Find( LPCSTR lpszSub, int nStart );
		
	/**
		Remarks:
			This member function searches this string object for the 
			last match of a character.
		Example:
			string str1("abcabc");
			ASSERT(str1.ReverseFind('b') == 4 );
		Parameters:
			ch = The character to search for.
		Return:
			Returns the index of the last character in this string 
			object that matches the requested character; -1 if the 
			character is not found.
		SeeAlso:
			string::Find, string::FindOneOf
	*/
	int		ReverseFind( char ch );	

	/**
		Remarks:
			This overloaded member function inserts a single character at the 
			given index within the string.  The nIndex parameter 
			identifies the first character that will be moved to make 
			room for the character. If nIndex is zero, the insertion 
			will occur before the entire string. If nIndex is higher 
			than the length of the string, the function will concatenate 
			the string and the character.
		Example:
			string str1("love summer");
			str1.Insert(0,'I');
			ASSERT(str1.Compare("Ilove summer")==0);
		Parameters:
			nIndex = The index of the character before which the insertion 
			will take place.
			ch = The character to be inserted.
		Return:
			The length of the changed string.
		SeeAlso:
			string::Delete
	*/
	int		Insert( int nIndex, char ch );
	
	/**
		Remarks:
			This overloaded member function inserts a substring at the 
			given index within the string.  The nIndex parameter 
			identifies the first character that will be moved to make 
			room for the substring. If nIndex is zero, the insertion 
			will occur before the entire string. If nIndex is higher 
			than the length of the string, the function will concatenate 
			the string and the substring.
		Example:
			string str1("I summer");
			str1.Insert(2,"love");
			ASSERT(str1.Compare("I lovesummer")==0);
		Parameters:
			nIndex = The index of the character before which the insertion 
			will take place.
			pstr = A pointer to the substring to be inserted.
		Return:
			The length of the changed string.
		SeeAlso:
			string::Delete
	*/
	int		Insert( int nIndex, LPCTSTR pstr );
	
	/**
		Remarks:
			This member function deletes a character or characters 
			from a string starting with the character at nIndex. If 
			nCount is longer than the string, the remainder of the 
			string will be removed.
		Example:
			string str("Summer is best");
			str.Delete(6,3);
			ASSERT(0 == str.Compare("Summer best"));
			ASSERT(str.GetLength()==11);
		Parameters:
			nIndex = The index of the first character to delete.
			nCount = The number of characters to be removed.
		Return:
			The length of the changed string.
		SeeAlso:
			string::Insert
	*/
	int     Delete( int nIndex, int nCount = 1 );

	/**
		Remarks:
			Converts this string object to a lowercase string.
		Example:
			string str("ABCD");
			str.MakeLower();
			ASSERT(str.Compare("abcd")==0);
		Parameters:
			None.
		Return:
			None.
		SeeAlso:
			string::MakeUpper
	*/
	void	MakeLower( );
	
	/**
		Remarks:
			Converts this string object to an uppercase string.
		Example:
			string str("abcd");
			str.MakeUpper();
			ASSERT(str.Compare("ABCD")==0);
		Parameters:
			None.
		Return:
			None.
		SeeAlso:
			string::MakeLower
	*/
	void	MakeUpper( );
		
	/**
		Remarks:
			Extracts a substring of length nCount characters from this 
			string object, starting at position nFirst (zero-based). 
		Example:
			string str1("I love summer!");
			string str2=str1.Mid(2,4);
			ASSERT(str2.Compare("love")==0);
		Parameters:
			nFirst = The zero-based index of the first character in this 
			string object that is to be included in the extracted 
			substring.
			nCount = The number of characters to extract from this 
			string object. If this parameter is not supplied, then the 
			remainder of the string is extracted.
		Return:
			Returns a copy of the extracted substring. 
		SeeAlso:
			string::Left, string::Right
	*/
	string  Mid( int nFirst, int nCount );
	string  Mid( int nFirst );

	/**
		Remarks:
			This member function returns a single character specified 
			by an index number. 
		Example:
			string str( "abcdef" );
			ASSERT( str.GetAt(2) == 'c' );
		Parameters:
			nIndex = Zero-based index of the character in the string 
			object. The nIndex parameter must be greater than or equal 
			to 0 and less than the value returned by GetLength.
		Return:
			A char containing the character at the specified position in the string.
		SeeAlso:
			string::SetAt, string::GetLength
	*/ 
	char	GetAt( int nIndex ); 

	/**
		Remarks:
			This member function overwrites a single character specified 
			by an index number. SetAt will not enlarge the string if the 
			index exceeds the bounds of the existing string.
		Example:
			string str( "abcdef" );
			str.SetAt(2,'z');
			ASSERT(str.Compare("abzdef")==0);
		Parameters:
			nIndex = Zero-based index of the character in the string object.
			The nIndex parameter must be greater than or equal to 0 and
			less than the value returned by GetLength. 
			ch = The character to insert.
		Return:
			None.
		SeeAlso:
			string::GetAt
	*/
	void	SetAt( int nIndex, char ch );
		
	/**
		Remarks:
			This member function returns the nth token where a token is 
			separated by the delimiter specified by chDelimiter.  Default
			is 0 (null constant) so chDelimiter does not have to be specified 
			when any white space (space, tab, newline, etc.) is to be used 
			as the delimiter.
		Example:
			string str1("apples peaches pumpkins");
			string str3("apples,peaches,pumpkins");
			string str2=str1.GetToken(1);
			string str4=str3.GetToken(1,',');
			ASSERT(str2.Compare("peaches")==0);
			ASSERT(str4.Compare("peaches")==0);
		Parameters:
			nToken = An integer representing the token to get.
			chDelimiter = A character representing the delimiter.
		Return:
			The extracted string token.
		SeeAlso:
			string::GetNumTokens, string::GetTokens	
	
	*/
	string	GetToken( int nToken, char chDelimiter = 0 );
	
	/**
		Remarks:
			This member function returns the number of tokens in this string
			where a token is separated by the delimiter specified by chDelimiter. 
			Default is 0 (null constant) so chDelimiter does not have to be 
			specified when any white space (space, tab, newline, etc.) is to be 
			used as the delimiter.
		Example:
			string str1("apples peaches pumpkins");
			string str2("apples,peaches,pumpkins");
			ASSERT(str1.GetNumTokens()==3);
			ASSERT(str2.GetNumTokens(',')==3);
		Parameters:
			chDelimiter = A character representing the delimiter.
		Return:
			The number of tokens in this string.
		SeeAlso:
			string::GetToken, string::GetTokens	

	*/
	int		GetNumTokens( char chDelimiter = 0 );

	/**
		Remarks:
			Create a StringArray from this string
		Example:
			StringArray strTokens;
			strTokens.SetSize(3);
			string str = "1@2@3#4#5$6$";
			ASSERT( 3 == str.GetTokens( strTokens, '@') );
			ASSERT( 0 == strTokens[0].Compare("1") );
			ASSERT( 0 == strTokens[1].Compare("2") );
			ASSERT( 0 == strTokens[2].Compare("3#4#5$6$") );
		Parameters:
			saTokens = string array which store the results found.	
			chDelimiter = A character representing the delimiter.
		Return:
			Number of tokens (strings) found
		SeeAlso:
			string::GetNumTokens, string::GetToken	
	*/
	int		GetTokens( StringArray& saTokens, char chDelimiter = 0 );

	/**#
		Remarks:
			Copy a StringArray into this string and separate them with specified delimiter
		Example:
			StringArray saColors = {"red", "green", "blue"};
			for( int n = 0; n < saColors.GetSize(); n++ )
				printf("Array element %d = %s\n", n, saColors[n]);
			string strColors;
			strColors.SetTokens(saColors, '|');
			printf("Delimited string = %s\n", strColors);
		Parameters:
			saTokens = string array containing the tokens
			chDelimiter = character to use as the delimiter
		Return:
			Number of tokens in this string, -1 for error
		SeeAlso:
			string::GetNumTokens, string::GetTokens
	*/
	int SetTokens(StringArray& saTokens, char chDelimiter = '\t');

	/**#
		Remarks:
			Find a token in this string
		Example:
			StringArray saColors = {"red", "green", "blue"};
			for( int n = 0; n < saColors.GetSize(); n++ )
				printf("Array element %d = %s\n", n, saColors[n]);
			string strColors;
			strColors.SetTokens(saColors, '|');
			printf("Delimited string = %s\n", strColors);
		
			saColors.Add("yellow"); // add string not in delimited string
			
			string strToken;
			int nToken;
			for( n = 0; n < saColors.GetSize(); n++ )
			{
				strToken = saColors[n];
				nToken = strColors.FindToken(strToken, '|');
				printf("%s is token %d\n", strToken, nToken);
			}
		Parameters:
			lpcszToken = pointer to a string representing the token to find
			chDelimiter = character to use as the delimiter
		Return:
			The zero based index of the token if found, -1 if token was not found
		SeeAlso:
			string::GetNumTokens, string::GetToken	
	*/
	int FindToken(LPCSTR lpcszToken, char chDelimiter = 0);

	/**
		Remarks:
			Makes this string object an empty string (0 length) and 
			frees memory as appropriate.
		Example:
			string str("abc");
			str.Empty();
			ASSERT(str.GetLength( ) == 0);
		Parameters:
			None.
		Return:
			None.
		SeeAlso:
			string::IsEmpty
	*/
	void	Empty( );

	/**
		Remarks:
			Tests a string object for the empty condition.  
			Tests whether a string object contains any characters.
		Example:
			string str;
			ASSERT(str.IsEmpty());
		Parameters:
			None.
		Return:
			Nonzero if the string object has 0 length; otherwise 0.
		SeeAlso:
			string::GetLength
	*/
	BOOL	IsEmpty( ); 

	/**
		Remarks:
			This member function extracts characters from the string, 
			starting with the first character, that are in the set of 
			characters identified by lpszCharSet. If the first 
			character of the string is not in the character set, then 
			SpanIncluding returns an empty string. Otherwise, it returns
			a sequence of consecutive characters which are in the set.
		Example:
			string str1("cabinet");
			string str2=str1.SpanIncluding("abc");
			ASSERT(str2.Compare("cab")==0);
			string str3=str1.SpanIncluding("xyz");
			ASSERT(str3.IsEmpty());
		Parameters:
			lpszCharSet = A string interpreted as a set of characters.
		Return:
			A substring that contains characters in the string that are
			in lpszCharSet, beginning with the first character in the 
			string and ending when a character is found in the string 
			that is not in lpszCharSet. SpanIncluding returns an empty 
			substring if the first character in the string is not in the 
			specified set.
		SeeAlso:
			string::SpanExcluding
	*/
	string	SpanIncluding( LPCSTR lpszCharSet );
	
	/**
		Remarks:
			This member function searches the string for the first 
			occurrence of any character in the specified set lpszCharSet.
			SpanExcluding extracts and returns all characters preceding
			the first occurrence of a character from lpszCharSet 
			(in other words, the character from lpszCharSet and all 
			characters following it in the string, are not returned). If
			no character from lpszCharSet is found in the string, then 
			SpanExcluding returns the entire string.
		Example:
			string str1("Hello World! Goodbye!");
			string str2("Hello World Goodbye");
			string str3=str1.SpanExcluding(".!?");
			string str4=str2.SpanExcluding(".!?");
			ASSERT(str3.Compare("Hello World")==0);
			ASSERT(str4.Compare("Hello World Goodbye")==0);
		Parameters:
			lpszCharSet = A string interpreted as a set of characters.
		Return:
			A substring that contains characters in the string that are
			not in lpszCharSet, starting with the first character in the 
			string and up to but excluding the first character in the 
			string that is found lpszCharSet). It returns the entire 
			string if no character in lpszCharSet is found in the string. 
		SeeAlso:
			string::SpanIncluding
	*/
	string	SpanExcluding( LPCSTR lpszCharSet );

	/**
		Remarks:
			This overloaded member function replaces a character with 
			another.   (Comparison is case-sensitive in all cases.)
		Example:
			string str("A+B+C+");
			ASSERT(str.Replace('+','-')==3);
		Parameters:
			chOld = The character to be replaced by chNew.
			chNew = The character replacing chOld.
		Return:
			The number of replaced instances of the character. 
			Zero if the string isn't changed.
		SeeAlso:
			string::Remove
	*/
	int		Replace( char chOld, char chNew );
	
	/**
		Remarks:
			This overloaded member function replaces instances of the 
			substring lpszOld with instances of the string lpszNew.  
		Example:
			string str("Today is Friday");
			ASSERT(str.Replace("Friday","Monday")==1);
			ASSERT(str.Compare("Today is Monday")==0);
		Parameters:
			lpszOld = A pointer to a string containing the characters to 
			be replaced by lpszNew.
			lpszNew = A pointer to a string containing the characters 
			replacing lpszOld.
		Return:
			The number of replaced instances of the character. Zero if 
			the string isn't changed.
		SeeAlso:
			string::Remove
	*/
	int		Replace( LPCSTR lpszOld, LPCSTR lpszNew );
	
	/**
		Remarks:
			This overloaded member function replaces instances of the 
			all characters as specified by lpszOneOf with the character chNew.
			If the resulted string has repeated occurance of chNew, they are
			stripped so that only one is left
		Example:
			string str("123  \t456,  789;\n\r1212");
			str.Replace(" \t\n\r,;",',');
			ASSERT(str.Compare("123,456,789,1212")==0);
		Parameters:
			lpszOneOf = A pointer to a string containing the characters that all are to 
			be replaced by chNew.
			chNew = The character replacing lpszOneOf.
		Return:
			The number of replaced instances of the chNew. Zero if no replacement
			took place.
	*/
	int		Replace( LPCSTR lpszOneOf, char chNew );
	
	/**
		Remarks:
			This member function removes instances of ch from the string. 
			Comparisons for the character are case-sensitive.
		Example:
			string str("apple");
			str.Remove('p');
			ASSERT(str.Compare("ale")==0);
		Parameters:
			ch = The character to be removed from a string.
		Return:
			The count of characters removed from the string. 
			Zero if the string isn't changed.
		SeeAlso:
			string::Replace
	*/
	int		Remove( char ch );
	
	/**
		Remarks:
			This member function searches this string for the first 
			character that matches any character contained in lpszCharSet.
		Example:
			string str("abcdef");
			ASSERT(str.FindOneOf("xd")==3); // 'd' is first match
		Parameters:
			lpszCharSet = string containing characters for matching.
		Return:
			The zero-based index of the first character in this string that is 
			also in lpszCharSet; -1 if there is no match.
		SeeAlso:
			string::Find
	*/
	int		FindOneOf( LPCSTR lpszCharSet );

	/**
		Remarks:
			This method retrieves a pointer to the internal character buffer for the string. 
			If you use the pointer returned by GetBuffer to change the string contents, 
			you must call ReleaseBuffer before using any other string methods. 
		Example:
			string str = "abcdefg";
			char *p = str.GetBuffer( 20 ); 
			out_str( p );		//output should be "abcdefg"
			str.ReleaseBuffer();
		Parameters:
			nMinBufLength = Specifies the minimum size of the character buffer in characters. 
			This value does not include space for a null terminator. 
		Return:
			This is an LPTSTR pointer to the character buffer of the null-terminated object.
		SeeAlso:  
			string::ReleaseBuffer.
	*/
	char*	GetBuffer( int nMinBufLength );
	
	/**
		Remarks:
			This method retrieves a pointer to the internal character buffer for the string, 
			truncating or growing its length, if necessary, to exactly match the length 
			specified in nNewLength.  
		Example:
			string str;
			char* pstr = str.GetBufferSetLength(3);
 			pstr[0] = 'I';
			pstr[1] = 'c';
			pstr[2] = 'e';
			out_str(str);		//output should be "Ice"
		Parameters:
			nNewLength = Specifies the exact size of the string character buffer in characters. 
		Return:
			This is an LPTSTR pointer to the character buffer of the null-terminated object.
	*/
	char*	GetBufferSetLength( int nNewLength );

	/**
		Remarks:
			Use ReleaseBuffer to end use of a buffer allocated by GetBuffer.
		Example:
			string str = "abcdefg";
			char *p = str.GetBuffer( 20 ); 
			str.ReleaseBuffer();
		Parameters:
			nNewLength = The new length of the string in characters, not counting a null terminator. 
			If the string is null-terminated, the -1 default value sets the string size to the 
			current length of the string.
		Return:
			None.
		SeeAlso:
			string::GetBuffer
	*/
	void	ReleaseBuffer( int nNewLength = -1 );

	/**
		Remarks:
			String pattern matching, any number of wildchars are supported, which can be * or ?.
		Example:
			string str = "abcdefg";
			ASSERT(str.Match("ab*"));
			ASSERT(str.Match("a*c*f?"));
			ASSERT(str.Match("a*d*"));
			ASSERT(str.Match("?*e*f?"));
		Parameters:
			strPattern = the string will be matched.
		Return:
			TRUE if the provided pattern matches the string.
	*/
	BOOL Match( LPCSTR strPattern, BOOL bCaseSensitive = FALSE );

	/**
		Remarks:
			This member function tests a string object is a valid or
			invalid	path.
		Example:
			string strPath="c:\\Program Files";
			ASSERT(strPath.IsPath());
		Parameters:
			None.
		Return:
			returns TRUE if the string object is a "path" that exists.
	*/
	BOOL	IsPath( ); 
	
	/**
		Remarks:
			This member function tests to see if the string is a valid full path file name
		Example:
			string strFile("c:\\Program Files\\Originlab\\origin70.exe");
			ASSERT(strFile.IsFile());
		Parameters:
			None.
		Return:
			returns TRUE if the string is a filename that exist		
	*/
	BOOL	IsFile( );

	/**
		Remarks:
			Modify a string to be a valid C identifier name.
			A C Identifier name must begin with a letter and can contain only letters,
			numbers, and underscore characters.
		Parameters:
			cPrefixIf1stCharNumber = If not zero and the string begins with a number then this character will be
				inserted before the first character.  If the first character of the string is not a digit or if
				the specified prefix character is not a letter or underscore then this argument will have no effect.
		Return:
			None
		Example:
			string str = "23 * this & this";
			printf("Before: %s\n", str);
			str.MakeValidCName('a'); // prefix with 'a', delete all spaces, and delete '*' and '&'
			printf("After: %s\n", str);
	*/
	void MakeValidCName(char cPrefixIf1stCharNumber=0);
};


////////////////////////////////////////////////////////////////////
#pragma dll(kernel32, system)

// GJL 11/18/02 v7.0437 ADD_ANSI_C_STRING_FUNCS1
/** >Character/String Manipulation
		The lstrcpy (alias strcpy) function copies a string to a buffer. 
	Example:
		char		szStr[80];
		string		str1 = "Here is some text";
		// Copy str1 to szStr: 
		lstrcpy(szStr, str1);
		out_str(szStr);
	Parameters:
		lpString1=Pointer to the destination buffer to receive the contents of the string pointed to by the lpString2 parameter. 
			The buffer must be large enough to contain the string, including the terminating null character. 
		lpString=Pointer to the null-terminated source string to be copied. 
	Return:
		If the function succeeds, the return value is a pointer to the destination buffer. If the function fails,
		the return value is NULL. 
*/
LPSTR WINAPI lstrcpy(LPSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
		The lstrcat (alias strcat) function appends one string to another.
	Example:
		char		szStr[80] = "This is the first part. ";
		string		str1 = "This is the second part.";
		// Concatenate: 
		lstrcat(szStr, str1);
		out_str(szStr);
	Parameters:
		lpString1=Pointer to a null-terminated string. The buffer must be large enough to contain both strings. 
		lpString2=Pointer to the null-terminated string to be appended to the string specified in the lpString1 parameter.
	Return:
		If the function succeeds, the return value is a pointer to the buffer.  If the function fails, the return value is NULL.  
*/
LPSTR WINAPI lstrcat(LPSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
		The lstrlen (alias strlen) function returns the length of a string in bytes.
	Example:
		string		str1 = "Hello World!";	
		int			len = lstrlen(str1);	// len is 12 (the length of str1).
		out_int("The length is ", len);
	Parameters:
		lpString=Pointer to a null-terminated string. 
	Return:
		the length of the string (not including zero termination).
*/
int	WINAPI lstrlen(LPCSTR lpString);
		
/** >Character/String Manipulation
		The lstrcpyn (alias strncpy) function copies a specified number of characters from a source string into a buffer. 
	Parameters:
		lpString1=Pointer to a buffer into which the function copies characters. The buffer must be large enough to contain 
			the number of characters specified by iMaxLength, including room for a terminating null character. 
		lpString2=Pointer to a null-terminated string from which the function copies characters. 
		iMaxLength=Specifies the number of characters to be copied from the string pointed to by lpString2 into the buffer 
			pointed to by lpString1, including a terminating null character. 
	Return:
		If the function succeeds, the return value is a pointer to the buffer.  If the function fails, the return value is NULL. 	
	Example:
		string		str1 = "Hello World!";
		char		szStr[80];
		lstrcpyn(szStr, str1, 5);
		out_str(szStr);	// Should be "Hell"
*/
LPSTR WINAPI lstrcpyn(LPSTR lpString1, LPCSTR lpString2, int iMaxLength);

/** >Character/String Manipulation
		The lstrcmp (alias strcmp) function compares two character strings. The comparison is case sensitive.
	Example:
		string	str1 = "Hello World!";
		int 	cmp = lstrcmp(str1, "HELLO WORLD!");	// cmp equals -1.
		out_int("cmp = ", cmp);
	Parameters:
		lpString1=Pointer to the first null-terminated string to be compared. 
		lpString2=Pointer to the second null-terminated string to be compared.
	Return:
		If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. 
		If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. 
		If the strings are equal, the return value is zero. 
*/
int	WINAPI lstrcmp(LPCSTR lpString1, LPCSTR lpString2);
	
/** >Character/String Manipulation
		The lstrcmpi (alias stricmp) function compares two character strings. The comparison is not case sensitive.
	Example:
		string	str1 = "Hello World!";
		int 	cmp = lstrcmpi(str1, "HELLO WORLD!");	// cmp equals 0.
		out_int("cmp = ", cmp);
	Parameters:
		lpString1=Pointer to the first null-terminated string to be compared. 
		lpString2=Pointer to the second null-terminated string to be compared.
	Return:
		If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. 
		If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. 
		If the strings are equal, the return value is zero.
*/
int WINAPI lstrcmpi(LPCSTR lpString1, LPCSTR lpString2);

////////////////////////////////////////////////////////////////////

#pragma dll(msvcrt, system)

/** >Character/String Manipulation
*/
LPSTR strcpy(LPSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
*/
LPSTR strcat(LPSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
*/
int	strlen(LPCSTR lpString);

/** >Character/String Manipulation
		The strncpy function copies a specified number of characters from a source string into a buffer.
	Example: 
		string		str1 = "Hello World!";
		char		szStr[80];
		strncpy(szStr, str1, 5);
		out_str(szStr);	// Should be "Hello"
	Parameters:
		lpString1=Pointer to a buffer into which the function copies characters. The buffer must be large enough to contain the number of characters specified by iMaxLength.
		lpString2=Pointer to a null-terminated string from which the function copies characters.
		iMaxLength=Specifies the number of characters to be copied from the string pointed to by lpString2 into the buffer pointed to by lpString1, without a terminating null character.
	Return values: 
		If the function succeeds, the return value is a pointer to the buffer.  If the function fails, the return value is NULL.
*/
LPSTR strncpy(LPSTR lpString1, LPCSTR lpString2, int iMaxLength);

/** >Character/String Manipulation
*/
int	strcmp(LPCSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
*/
int _stricmp(LPCSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
*/
int stricmp(LPCSTR lpString1, LPCSTR lpString2);

/** >Character/String Manipulation
		Find the first occurrence of a character in a string.
	Example:
		string	str1 = "Hello World!";
		out_str(strchr(str1,'W'));
		ASSERT(strchr(str1,'A')==NULL);
	Parameters:
		lpcszStr=NULL terminated source string
		cc=Character to be located
	Return:
		Returns a pointer to the first occurrence of a character in a string.
*/
LPSTR	strchr(LPCSTR lpcszStr, int cc); // Find the first occurrence of a character in a string.

/** >Character/String Manipulation
		Scan a string for the last occurrence of a character.
	Example:
		string	str1 = "Hello World!";
		out_str(strrchr(str1,'o'));
		ASSERT(strrchr(str1,'A')==NULL);
	Parameters:
		lpcszStr=Null terminated source string
		cc=Character to be located
	Return:
		Returns a pointer to the last occurrence of a character in a string.
*/
LPSTR	strrchr(LPCSTR lpcszStr, int cc); // Scan a string for the last occurrence of a character.

/** >Character/String Manipulation
		Append the first N characters of one string to a second string.
	Example:
		char str1[]="Hello world from ";
		strncat( str1, "strcpy!xxxxxxxx", 7 );
		out_str( str1 );
	Parameters:
		lpszDestination=String that is appended to
		lpcszSource=String that is appended
		count=Number of characters to append
	Return:
		Returns a pointer to the destination string with N characters from source string appended.
*/
LPSTR	strncat( LPSTR lpszDestination, LPCSTR lpcszSource, size_t count ); // Append the first N characters of one string to a second string.

/** >Character/String Manipulation
		Compare the first N characters of two strings.
	Example:
		char str1[] = "Hello world!xxxxxxxx";
		char str2[] = "Hello world!";		
		printf( "String1 = %s\n", str1 );
		printf( "String2 = %s\n", str2 );
		ASSERT(strcmp(str1,str2)!=0);
		ASSERT(strncmp(str1,str2,12)==0);
	Parameters:
		lpcszString1=First of two strings to compare
		lpcszString2=Second of two strings to compare
		count=Number of characters N to compare
	Return:
		Returns an integer < 0 if the first N characters of string1 are alpha-numerically less than
		string2, returns 0 if the first N characters of string1 are the same as string2, and returns
		an integer > 0 if the first N characters of string1 are alpha-numerically greater than string2.
*/
int 	strncmp( LPCSTR lpcszString1, LPCSTR lpcszString2, size_t count ); // Compare the first N characters of two strings.

/** >Character/String Manipulation
		Find a prefix substring in a string consisting entirely of characters
		in a specified character set.
	Example:
		char str1[] = "Mississippi";
		ASSERT(strspn( str1, "Mis" )==8);
		ASSERT(strspn( str1, "Misp" )==strlen(str1));
	Parameters:
		lpcszString=String to search through
		lpcszCharSet=String containing specified character set
	Return:
		Returns the 0 based index of the first character in a string that is
		not in a specified character set. All characters before returned index
		are in the character set.
*/ 
size_t	 strspn( LPCSTR lpcszString, LPCSTR lpcszCharSet ); // Find a prefix substring in a string consisting entirely of characters in a specified character set.

/** >Character/String Manipulation
		Find a prefix substring in a string not containing any characters
		in a specified character set.
	Example:
		char str1[] = "Mississippi";
		ASSERT(strcspn( str1, "qrst" )==2);
	Parameters:
		lpcszString=String to search through
		lpcszCharSet=String containing specified character set
	Return:
		Returns the 0 based index of the first character in a string that is
		in a specified character set. All characters before returned index
		are not in character set.
*/
size_t	strcspn( LPCSTR lpcszString, LPCSTR lpcszCharSet ); // Find a prefix substring in a string not containing any characters in a specified character set.

/** >Character/String Manipulation
		Scan strings for characters in a specified character set.
	Example:
		char str1[] = "I saw 3 blind mice";
		char* pdest = strpbrk(str1,"123456789");
		out_str(pdest);
		ASSERT(strcmp(pdest,"3 blind mice")==0);
	Parameters:
		lpcszString=String to search through
		lpcszCharSet=String containing specified character set
	Return:
		Returns a pointer to the first occurrence of a character in a string that is in specified a character set.
*/
LPSTR	strpbrk( LPCSTR lpcszString, LPCSTR lpcszCharSet ); // Scan strings for characters in a specified character set.

/** >Character/String Manipulation
		Find a substring.
	Example:
		char str1[] = "I saw 3 blind mice";
		char * pdest = strstr(str1,"blind");
		out_str(pdest);
		ASSERT(strcmp(pdest,"blind mice")==0);
	Parameters:
		lpcszString=String to search through
		lpcszCharSet=Substring to search for
	Return:
		Returns a pointer to the first character of a substring.
*/
LPSTR	 strstr( LPCSTR lpcszString, LPCSTR lpcszCharSet ); // Find a substring.

/** >Character/String Manipulation
		Get a system error message (strerror) or print a user-supplied error message (_strerror).
	Example:
		char * pErr;
		string strPrevious;
		int ii = 0;
		for(;1;)
		{
			strPrevious = pErr;
			pErr = strerror(ii++);
			if( strcmp(pErr,strPrevious)==0 )
				break;
			out_str(pErr);
		}
	Parameters:
		iErrNum=Error number whose error message is returned
	Return:
		Returns a pointer to the first character of an error message associated with iErrNum.
*/
LPSTR	strerror( int iErrNum ); // Get a system error message (strerror) or print a user-supplied error message (_strerror).

/** >Character/String Manipulation
		Find the next token in a string.
	Example:
		char str9[] = "This,is a.list\tof:tokens";
		char str10[] = ", .\t:";
		char * ptok;
		ptok = strtok(str9,str10);
		out_str(ptok);
		while(ptok=strtok(NULL,str10))
			out_str(ptok);
	Parameters:
		lpszStrToken=String containing tokens to be parsed
		lpcszDelimit=String containing delimiters
	Return:
		Returns a pointer to the first character of the next token.
*/
LPSTR	strtok( LPCSTR lpszStrToken, LPCSTR lpcszDelimit ); // Find the next token in a string.

/** >Character/String Manipulation
		Copy characters between buffers.
	Example:
		struct myStruct
		{
				int myint;
				double mydouble;
		};
	
		myStruct aa, bb;	
		memset(&aa, 5, sizeof(myStruct));	// Set every byte of structure aa to 5.
		memset(&bb, 0, sizeof(myStruct));	// Set every byte of structure bb to 0.
		memcpy(&aa, &bb, sizeof(myStruct));	// Now every byte of structure aa is 0 too.
	Parameters:
		lpDestination=New buffer
		lpSource=Buffer to copy from
		nSize=Number of characters to copy
	Returns:
		The value of lpDestination.
*/ 
LPVOID	memcpy(LPVOID lpDestination, const LPVOID lpSource, UINT uSize); // Copy characters between buffers.

/** >Character/String Manipulation
		Set buffers to a specified character.
	Example:
		int aa;
		memset(&aa, 10, sizeof(int));
	Parameters:
		lpMem=Pointer to lpMem
		nValue=Integer value to set
		nSize=Number of integer value
	Return:
		The value of lpMem.
*/ 
LPVOID	memset(LPVOID lpMem, int nValue, UINT uSize); // Set buffers to a specified character.

/** >Character/String Manipulation
		Compares characters between two buffers.
	Example:
		char	szFirst[] = "12345678901234567890";
		char	szSecond[] = "12345678901234567891";
		int		nNumerOfBytesToCompare = 19;	// change this to 20 to see a different result
		
		int		nResult = memcmp(szFirst, szSecond, nNumerOfBytesToCompare);
		if (0 == nResult)
			out_str("Equal");
		else if (0 > nResult)
			out_str("First is less than second");
		else
			out_str("First is greater than second");
	Parameters:
		lpMem1: First buffer 
		lpMem2: Second buffer
		nSize:  Number of characters to compare.
	Return:
		Returns an integer < 0 if lpMem1 is less than lpMem2, returns 0 if lpMem1 is identical to lpMem2, and returns
		an integer > 0 if lpMem1 greater than lpMem2.
*/
int		memcmp(LPCVOID lpMem1, LPCVOID lpMem2, UINT uSize); // Compares characters between two buffers.

/** >Character/String Manipulation
		Move contents of one buffer to another.
	Example:
		char * pRet;
		char str1[40];
		char str2[] = "Hello World!xxxxxxxx";
		printf( "String1 = %s\n", str1 );
		printf( "String2 = %s\n", str2 );
		pRet = (char *) memmove(str1,str2,12);
		out_str(pRet);
		printf( "String1 = %s\n", str1 );
		printf( "String2 = %s\n", str2 );
	Parameters:
		dest=Destination buffer
		src=Source buffer
		count=Number of characters to move
	Return:
		Returns a pointer to moved characters.
*/
LPVOID	memmove( LPVOID dest, LPCVOID src, size_t count ); // Move contents of one buffer to another.

/** >Character/String Manipulation
		Find a pointer to first occurrence of character.
	Example:
		char * pChar;
		char str1[] = "Mississippi";
		pChar=(char*) memchr(str1,'s',11);
		out_str(pChar);
	Parameters:
		buf=Buffer to search in 
		c=Character to search for
		count=Number of characters to search in buffer
	Return:
		Returns a pointer to first occurrence of character.
*/
LPVOID	memchr( LPCVOID buf, int c, size_t count ); // Find a pointer to first occurrence of character.
// End GJL 11/18/02 v7.0437 ADD_ANSI_C_STRING_FUNCS1

// GJL 11/18/02 v7.0437 ADD_ANSI_C_STRING_FUNCS2
/** >Character/String Manipulation
		Read data from a string according to a standard C format specification and return data
		values in a series of user specified receptor variables.
	Example:
		char str2[10], str1[]="Hello C 15 17.56";
		char cChar;
		int iInt;
		float fFloat;
		int N;
		N = sscanf( str1, "%s %c %d %f", str2, &cChar, &iInt, &fFloat);
		out_str(str1);
		out_str(str2);
		printf("%c\n",cChar);
		out_int("",iInt);
		out_double("",fFloat);
	Parameters:
		lpcszBuffer=String to search through for formated data
		lpcszFormat=Standard C format specification
		...=A comma separated list of receptor variables to hold returned data values
	Return:
		Returns the number of data values which are returned in receptor variables and data values
		in receptor variables.
*/
int sscanf( LPCSTR lpcszBuffer, LPCSTR lpcszFormat, ... ); // Read data from a string according to a standard C format specification.

/** >Character/String Manipulation
		Write data values stored in a series of user specified variables into a string according
		to a standard C format specification.
	Example:
		char str1[] = "Hello", str2[50];
		char cChar = 'C';
		int N, iInt = 15;
		float fFloat = 17.56;
		N = sprintf( str2, "%s %c %d %f", str1, cChar, iInt, fFloat);
		out_str(str1);
		printf("%c\n",cChar);
		out_int("",iInt);
		out_double("",fFloat);
		out_str(str2);
	Parameters:
		lpcszBuffer=String where formated data is written
		lpcszFormat=Standard C format specification
		...=A comma separated list of user specified variables holding data values
	Return:
		Returns the number of characters which are written into the string.
	SeeAlso:
		string::Format
*/
int sprintf( LPSTR lpszBuffer, LPCSTR lpcszFormat, ... ); // Write data into a string according to a standard C format specification.
// End GJL 11/18/02 v7.0437 ADD_ANSI_C_STRING_FUNCS2

#endif //!_STRING_H