2020-03-12 15:40:38 +01:00
//*************************************************************************************************
//*************************************************************************************************
//
2020-04-23 15:20:48 +02:00
// STRING
//
// Developed by jief666, from 1997.
2020-03-12 15:40:38 +01:00
//
//*************************************************************************************************
//*************************************************************************************************
2020-04-23 15:20:48 +02:00
# if !defined(__XString_H__)
# define __XString_H__
2020-03-12 15:40:38 +01:00
2020-04-24 08:36:29 +02:00
# include <XToolsConf.h>
2020-04-23 15:20:48 +02:00
# include "XStringAbstract.h"
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
# include "../../Include/Library/printf_lite.h"
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
# ifndef XString16GrowByDefault
# define XString16GrowByDefault 16
# endif
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
//------------------------------------------------------------------------------------------------------------------
2020-04-30 08:03:56 +02:00
class XString8 ;
class LString8 : public LString < char , XString8 >
2020-04-29 22:34:28 +02:00
{
public :
constexpr LString8 ( ) = delete ;
2020-04-30 08:03:56 +02:00
constexpr LString8 ( const char * s ) : LString < char , XString8 > ( s ) { } ;
2020-04-29 22:34:28 +02:00
// no assignement, no destructor
2020-04-30 08:22:26 +02:00
friend constexpr LString8 operator " " _XS8 ( const char * s , size_t ) { return LString8 ( s ) ; }
2020-08-12 17:15:47 +02:00
const char * c_str ( ) const { return m_data ; }
2020-04-29 22:34:28 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-30 08:03:56 +02:00
class XString8 : public XStringAbstract < char , XString8 >
2020-03-12 15:40:38 +01:00
{
public :
2020-04-30 08:03:56 +02:00
XString8 ( ) : XStringAbstract < char , XString8 > ( ) { } ;
XString8 ( const XString8 & S ) : XStringAbstract < char , XString8 > ( S ) { }
XString8 ( const LString8 & S ) : XStringAbstract < char , XString8 > ( S ) { }
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
2020-04-30 08:03:56 +02:00
XString8 ( const OtherXStringClass & S ) : XStringAbstract < char , XString8 > ( S ) { }
2020-03-28 17:17:02 +01:00
2020-04-30 08:03:56 +02:00
XString8 & operator = ( const XString8 & S ) { this - > XStringAbstract < char , XString8 > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-30 08:03:56 +02:00
using XStringAbstract < char , XString8 > : : operator = ;
2020-08-12 17:15:47 +02:00
const char * c_str ( ) const { return m_data ; }
2020-08-18 18:45:44 +02:00
// char* copy_str() const { return (char*)AllocateCopyPool(length()+1, m_data); }
2020-08-12 17:15:47 +02:00
2020-04-23 15:20:48 +02:00
protected :
2020-08-11 08:00:19 +02:00
static void transmitS8Printf ( const char * buf , unsigned int nbchar , void * context )
2020-04-23 15:20:48 +02:00
{
2020-04-30 08:03:56 +02:00
( ( XString8 * ) ( context ) ) - > strncat ( buf , nbchar ) ;
2020-04-23 15:20:48 +02:00
}
public :
2021-02-10 13:32:07 +01:00
void vS8Printf ( const char * format , XTOOLS_VA_LIST va )
2020-04-23 15:20:48 +02:00
{
setEmpty ( ) ;
2020-08-11 08:00:19 +02:00
vprintf_with_callback ( format , va , transmitS8Printf , this ) ;
2020-04-23 15:20:48 +02:00
}
2020-08-11 08:00:19 +02:00
void S8Printf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
2020-04-23 15:20:48 +02:00
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-03-12 15:40:38 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-08-11 08:00:19 +02:00
vS8Printf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-04-23 15:20:48 +02:00
}
2021-02-10 13:32:07 +01:00
void vS8Catf ( const char * format , XTOOLS_VA_LIST va )
2020-11-12 22:25:56 +01:00
{
vprintf_with_callback ( format , va , transmitS8Printf , this ) ;
}
void S8Catf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-11-12 22:25:56 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-11-12 22:25:56 +01:00
vS8Catf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-11-12 22:25:56 +01:00
}
2020-04-29 22:34:28 +02:00
} ;
2020-04-23 15:20:48 +02:00
2020-04-29 22:34:28 +02:00
//------------------------------------------------------------------------------------------------------------------
class XString16 ;
class LString16 : public LString < char16_t , XString16 >
{
constexpr LString16 ( const char16_t * s ) : LString < char16_t , XString16 > ( s ) { } ;
friend constexpr LString16 operator " " _XS16 ( const char16_t * s , size_t ) { return LString16 ( s ) ; }
2020-04-23 15:20:48 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
class XString16 : public XStringAbstract < char16_t , XString16 >
{
2020-03-12 15:40:38 +01:00
public :
2020-04-23 15:20:48 +02:00
XString16 ( ) : XStringAbstract < char16_t , XString16 > ( ) { } ;
2020-08-10 13:06:06 +02:00
XString16 ( const XString16 & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
XString16 ( const LString16 & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString16 ( const OtherXStringClass & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
2020-03-26 13:59:20 +01:00
2020-04-23 15:20:48 +02:00
XString16 & operator = ( const XString16 & S ) { this - > XStringAbstract < char16_t , XString16 > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
using XStringAbstract < char16_t , XString16 > : : operator = ;
2020-04-29 22:34:28 +02:00
// friend LString16 operator "" _XS16 ( const char16_t* s, size_t len);
} ;
//------------------------------------------------------------------------------------------------------------------
class XString32 ;
class LString32 : public LString < char32_t , XString32 >
{
constexpr LString32 ( const char32_t * s ) : LString < char32_t , XString32 > ( s ) { } ;
friend constexpr LString32 operator " " _XS32 ( const char32_t * s , size_t ) { return LString32 ( s ) ; }
2020-04-23 15:20:48 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
class XString32 : public XStringAbstract < char32_t , XString32 >
{
public :
XString32 ( ) : XStringAbstract < char32_t , XString32 > ( ) { } ;
2020-08-10 13:06:06 +02:00
XString32 ( const XString32 & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
XString32 ( const LString32 & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString32 ( const OtherXStringClass & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
XString32 & operator = ( const XString32 & S ) { this - > XStringAbstract < char32_t , XString32 > : : operator = ( S ) ; return * this ; }
using XStringAbstract < char32_t , XString32 > : : operator = ;
2020-04-29 22:34:28 +02:00
// friend LString32 operator "" _XS32 ( const char32_t* s, size_t len);
} ;
//------------------------------------------------------------------------------------------------------------------
class XStringW ;
class LStringW : public LString < wchar_t , XStringW >
{
public :
constexpr LStringW ( ) = delete ;
constexpr LStringW ( const wchar_t * s ) : LString < wchar_t , XStringW > ( s ) { } ;
friend constexpr LStringW operator " " _XSW ( const wchar_t * s , size_t ) { return LStringW ( s ) ; }
2020-08-12 17:15:47 +02:00
const wchar_t * wc_str ( ) const { return m_data ; }
2020-04-23 15:20:48 +02:00
} ;
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
class XStringW : public XStringAbstract < wchar_t , XStringW >
{
2020-08-11 08:00:19 +02:00
public :
2020-04-23 15:20:48 +02:00
XStringW ( ) : XStringAbstract < wchar_t , XStringW > ( ) { } ;
XStringW ( const XStringW & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-08-10 13:06:06 +02:00
XStringW ( const LStringW & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
2020-04-23 15:20:48 +02:00
XStringW ( const OtherXStringClass & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-04-29 22:34:28 +02:00
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
XStringW & operator = ( const XStringW & S ) { this - > XStringAbstract < wchar_t , XStringW > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
using XStringAbstract < wchar_t , XStringW > : : operator = ;
2020-03-12 15:40:38 +01:00
2020-08-12 17:15:47 +02:00
const wchar_t * wc_str ( ) const { return m_data ; }
2020-04-23 15:20:48 +02:00
protected :
2021-02-04 15:04:31 +01:00
static void transmitSWPrintf ( const wchar_t * buf , unsigned int nbchar , void * context )
2020-04-23 15:20:48 +02:00
{
( ( XStringW * ) ( context ) ) - > strncat ( buf , nbchar ) ;
}
public :
2021-02-10 13:32:07 +01:00
void vSWPrintf ( const char * format , XTOOLS_VA_LIST va )
2020-04-23 15:20:48 +02:00
{
setEmpty ( ) ;
2021-02-04 15:04:31 +01:00
vwprintf_with_callback ( format , va , transmitSWPrintf , this ) ;
2020-04-23 15:20:48 +02:00
}
void SWPrintf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-03-12 15:40:38 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-04-23 15:20:48 +02:00
vSWPrintf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-04-23 15:20:48 +02:00
}
2021-02-10 13:32:07 +01:00
void vSWCatf ( const char * format , XTOOLS_VA_LIST va )
2021-02-04 15:04:31 +01:00
{
vwprintf_with_callback ( format , va , transmitSWPrintf , this ) ;
}
void SWCatf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2021-02-04 15:04:31 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2021-02-04 15:04:31 +01:00
vSWCatf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2021-02-04 15:04:31 +01:00
}
2020-03-12 15:40:38 +01:00
} ;
2020-04-29 22:34:28 +02:00
2020-08-09 17:55:30 +02:00
constexpr LString8 operator " " _XS8 ( const char * s , size_t len ) ;
constexpr LString16 operator " " _XS16 ( const char16_t * s , size_t len ) ;
constexpr LString32 operator " " _XS32 ( const char32_t * s , size_t len ) ;
constexpr LStringW operator " " _XSW ( const wchar_t * s , size_t len ) ;
2020-03-29 11:40:13 +02:00
2020-08-11 08:00:19 +02:00
extern const XString8 NullXString8 ;
2020-04-23 15:20:48 +02:00
extern const XStringW NullXStringW ;
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
# ifdef _MSC_VER
# define __attribute__(x)
2020-03-12 15:40:38 +01:00
# endif
2020-04-23 15:20:48 +02:00
2020-08-11 08:00:19 +02:00
XString8 S8Printf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 1 , 2 ) ) ) ;
2020-04-23 15:20:48 +02:00
XStringW SWPrintf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 1 , 2 ) ) ) ;
2020-03-12 15:40:38 +01:00
2020-04-23 22:43:35 +02:00
//
//XStringAbstract SubString(const T *S, size_t pos, size_t count);
2020-03-12 15:40:38 +01:00
# endif