#ifndef SQPLUS_OCHARBUF_H #define SQPLUS_OCHARBUF_H // Conversion routines between different character encodings, to be used in // Push/Get/Match handlers of SqPlus. It enables using both of char* and // wchar_t* as function arguments. // // When converting from wchar_t to char, the choice is between using a Latin1 // or a UTF8 representation in 8-bit mode. This is probably most useful if // Squirrel is compiled in ANSI mode and the app uses some wchar_t strings // (UNICODE mode on Win32). // // A char is either // - A Latin1 character (first code page, coincides with Unicode points 0..255) // - Part of an UTF8 character // // Note: SQUTF8 requires Squirrel sources that have been patched for UTF8 strings // internally (when converting function arguments). #ifndef SQUTF8 // Default to Latin1 conversion //#undef SQPLUS_USE_LATIN1 #ifndef SQPLUS_USE_LATIN1 #define SQPLUS_USE_LATIN1 1 #endif #else // Using Squirrel with internal UTF8 string encoding //#undef SQPLUS_USE_LATIN1 #ifndef SQPLUS_USE_LATIN1 #define SQPLUS_USE_LATIN1 0 #endif #endif // The various ol_... functions sets up for a conversion scheme // that can be used in both wchar_t => char and char => wchar_t. int ol_strlen(const wchar_t* pwc); int ol_buflen(const wchar_t* pwc); int ol_charlen(const wchar_t* pwc); int ol_char(const wchar_t* pwc); bool ol_writechar(wchar_t*& pwc, int ch); int ol_strlen(const char* pc); int ol_buflen(const char* pc); int ol_charlen(const char* pc); int ol_char(const char* pc); bool ol_writechar(char*& pc, int ch); #ifdef SQUNICODE // SQChar is wchar_t, convert to/from either Latin1 or UTF8 typedef char SQOtherChar; #else // SQChar is char, convert to/from wchar_t typedef wchar_t SQOtherChar; #endif // Buffer to hold a string and release it in destructor. // SQT is input character type // SQOT is the opposite type of SQChar // If 'try_borrow' is set, it will not allocate a new buffer when no // conversion is done, it will just keep the input pointer (beware). template struct SQCharBufImpl { // Allocate a buffer from string of same type SQCharBufImpl(const SQT *poc=NULL, bool try_borrow=true ) : m_poc(0), m_own(false) { Init( poc, try_borrow ); } // This does conversion from other char type SQCharBufImpl(const SQOT *ps, bool try_borrow=false ) : m_poc(0), m_own(false) { Init( ps ); // Cannot borrow pointer when doing conversion } void Init( const SQT *poc, bool try_borrow ){ m_own = !try_borrow; if( try_borrow ){ m_poc = (SQT*)poc; } else { int sl = poc ? ol_buflen(poc) : 0; if( poc ){ m_poc = poc ? new SQT[sl+1] : NULL; if( m_poc ) memcpy( m_poc, poc, (sl+1)*sizeof(SQT) ); } else m_poc = NULL; } } void Init( const SQOT *ps ){ m_own = true; if( ps ){ int sl = ps ? ol_strlen(ps) : 0; // Length of string in characters (not bytes) int scl = 0; // Length of converted string in char/wchar_t count // How much storage needed? if( !use_latin1 && sizeof(SQT) UTF8 const SQOT *ps1 = ps; // It is wchar_t* here SQT tmp_buf[8]; SQT *ptmp; while( *ps1 ){ ptmp = tmp_buf; if( ol_writechar(ptmp,*ps1++) ) scl += ol_charlen(tmp_buf); else scl++; } } else scl = sl; // Converting to wchar_t or Latin1, keep length m_poc = new SQT[scl+1]; if( !m_poc ) return; // Convert SQT *poc = m_poc; while( *ps ){ ol_writechar( poc, ol_char(ps) ); ps += ol_charlen(ps); } *poc = 0; // Terminating zero } else m_poc = NULL; } ~SQCharBufImpl(){ Release(); } void Release( ){ if(m_poc && m_own ) delete [] m_poc; m_poc = NULL; } SQT* Set( const SQOT *ps ){ Release( ); Init( ps ); return m_poc; } operator SQT*() const { return m_poc; } SQCharBufImpl& operator = (const SQT *ps){ Release(); Init( ps, false ); return *this; } SQCharBufImpl& operator = (const SQOT *ps){ Release(); Init( ps ); return *this; } // Move string from other here - Note: Empties the input argument (other) SQCharBufImpl& operator = (const SQCharBufImpl& other){ Release(); m_poc = other.m_poc; m_own = other.m_own; SQT **psqt = (SQT**)&other.m_poc; *psqt = NULL; return *this; } protected: SQT *m_poc; bool m_own; }; typedef SQCharBufImpl SQOthCharBuf; typedef SQCharBufImpl SQDefCharBuf; typedef SQCharBufImpl SQWCharBuf; typedef SQCharBufImpl SQACharBuf; #ifdef SQUNICODE // SQChar is wchar_t, convert to/from to either Latin1 or UTF8 #define WC2SQ(s) s #define SQ2WC(s) s SQDefCharBuf CH2SQ( const char* ps ); SQOthCharBuf SQ2CH( const wchar_t* pws ); #else // SQChar is char, convert to/from wchar_t SQDefCharBuf WC2SQ( const wchar_t* pws ); SQOthCharBuf SQ2WC( const char* pws ); #define CH2SQ(s) s #define SQ2CH(s) s #endif #endif // SQPLUS_CHARBUF_H