X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/25dd56b1d32f01cb770fbbeb50851c2814fd09a6..c4d83d0a592c9d3918c7db26a7b1ca97d646e831:/src/common/string.cpp?ds=sidebyside diff --git a/src/common/string.cpp b/src/common/string.cpp index c866ca4589..c0f3c6e218 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -56,6 +56,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject) #endif //WXSTRING_IS_WXOBJECT +#if wxUSE_UNICODE +#undef wxUSE_EXPERIMENTAL_PRINTF +#define wxUSE_EXPERIMENTAL_PRINTF 1 +#endif + // allocating extra space for each string consumes more memory but speeds up // the concatenation operations (nLen is the current string's length) // NB: EXTRA_ALLOC must be >= 0! @@ -80,15 +85,22 @@ static const struct { wxStringData data; wxChar dummy; -} g_strEmpty = { {-1, 0, 0}, _T('\0') }; +} g_strEmpty = { {-1, 0, 0}, wxT('\0') }; // empty C style string: points to 'string data' byte of g_strEmpty -extern const wxChar WXDLLEXPORT *g_szNul = &g_strEmpty.dummy; +extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy; // ---------------------------------------------------------------------------- // conditional compilation // ---------------------------------------------------------------------------- +#if !defined(__WXSW__) && wxUSE_UNICODE + #ifdef wxUSE_EXPERIMENTAL_PRINTF + #undef wxUSE_EXPERIMENTAL_PRINTF + #endif + #define wxUSE_EXPERIMENTAL_PRINTF 1 +#endif + // we want to find out if the current platform supports vsnprintf()-like // function: for Unix this is done with configure, for Windows we test the // compiler explicitly. @@ -113,7 +125,7 @@ extern const wxChar WXDLLEXPORT *g_szNul = &g_strEmpty.dummy; #elif defined(__GNUG__) && !defined(__UNIX__) #warning "Using sprintf() because no snprintf()-like function defined" #elif defined(__MWERKS__) - #warning "Using sprintf() because no snprintf()-like function defined" + #warning "Using sprintf() because no snprintf()-like function defined" #endif //compiler #endif // no vsnprintf @@ -126,7 +138,7 @@ extern const wxChar WXDLLEXPORT *g_szNul = &g_strEmpty.dummy; // global functions // ---------------------------------------------------------------------------- -#ifdef wxSTD_STRING_COMPATIBILITY +#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM // MS Visual C++ version 5.0 provides the new STL headers as well as the old // iostream ones. @@ -272,7 +284,7 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength) } } -#else +#else // ANSI #if wxUSE_WCHAR_T // from wide string @@ -290,9 +302,9 @@ wxString::wxString(const wchar_t *pwz) Init(); } } -#endif +#endif // wxUSE_WCHAR_T -#endif +#endif // Unicode/ANSI // --------------------------------------------------------------------------- // memory allocation @@ -315,7 +327,7 @@ void wxString::AllocBuffer(size_t nLen) pData->nDataLength = nLen; pData->nAllocLength = nLen + EXTRA_ALLOC; m_pchData = pData->data(); // data starts after wxStringData - m_pchData[nLen] = _T('\0'); + m_pchData[nLen] = wxT('\0'); } // must be called before changing this string @@ -367,7 +379,7 @@ void wxString::Alloc(size_t nLen) pData->nDataLength = 0; pData->nAllocLength = nLen; m_pchData = pData->data(); // data starts after wxStringData - m_pchData[0u] = _T('\0'); + m_pchData[0u] = wxT('\0'); } else if ( pData->IsShared() ) { pData->Unlock(); // memory not freed because shared @@ -449,7 +461,7 @@ void wxString::AssignCopy(size_t nSrcLen, const wxChar *pszSrcData) AllocBeforeWrite(nSrcLen); memcpy(m_pchData, pszSrcData, nSrcLen*sizeof(wxChar)); GetStringData()->nDataLength = nSrcLen; - m_pchData[nSrcLen] = _T('\0'); + m_pchData[nSrcLen] = wxT('\0'); } } @@ -551,7 +563,7 @@ void wxString::ConcatSelf(int nSrcLen, const wxChar *pszSrcData) // fast concatenation - all is done in our buffer memcpy(m_pchData + nLen, pszSrcData, nSrcLen*sizeof(wxChar)); - m_pchData[nNewLen] = _T('\0'); // put terminating '\0' + m_pchData[nNewLen] = wxT('\0'); // put terminating '\0' GetStringData()->nDataLength = nNewLen; // and fix the length } //else: the string to append was empty @@ -710,7 +722,7 @@ wxString wxString::Left(size_t nCount) const wxString wxString::BeforeFirst(wxChar ch) const { wxString str; - for ( const wxChar *pc = m_pchData; *pc != _T('\0') && *pc != ch; pc++ ) + for ( const wxChar *pc = m_pchData; *pc != wxT('\0') && *pc != ch; pc++ ) str += *pc; return str; @@ -750,7 +762,7 @@ size_t wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplace wxString strTemp; const wxChar *pCurrent = m_pchData; const wxChar *pSubstr; - while ( *pCurrent != _T('\0') ) { + while ( *pCurrent != wxT('\0') ) { pSubstr = wxStrstr(pCurrent, szOld); if ( pSubstr == NULL ) { // strTemp is unused if no replacements were made, so avoid the copy @@ -852,8 +864,8 @@ wxString& wxString::MakeLower() wxString& wxString::Trim(bool bFromRight) { // first check if we're going to modify the string at all - if ( !IsEmpty() && - ( + if ( !IsEmpty() && + ( (bFromRight && wxIsspace(GetChar(Len() - 1))) || (!bFromRight && wxIsspace(GetChar(0u))) ) @@ -870,7 +882,7 @@ wxString& wxString::Trim(bool bFromRight) psz--; // truncate at trailing space start - *++psz = _T('\0'); + *++psz = wxT('\0'); GetStringData()->nDataLength = psz - m_pchData; } else @@ -912,7 +924,7 @@ wxString& wxString::Truncate(size_t uiLen) if ( uiLen < Len() ) { CopyBeforeWrite(); - *(m_pchData + uiLen) = _T('\0'); + *(m_pchData + uiLen) = wxT('\0'); GetStringData()->nDataLength = uiLen; } //else: nothing to do, string is already short enough @@ -946,7 +958,7 @@ int wxString::Find(const wxChar *pszSub) const wxString& wxString::operator<<(int i) { wxString res; - res.Printf(_T("%d"), i); + res.Printf(wxT("%d"), i); return (*this) << res; } @@ -954,7 +966,7 @@ wxString& wxString::operator<<(int i) wxString& wxString::operator<<(float f) { wxString res; - res.Printf(_T("%f"), f); + res.Printf(wxT("%f"), f); return (*this) << res; } @@ -962,7 +974,7 @@ wxString& wxString::operator<<(float f) wxString& wxString::operator<<(double d) { wxString res; - res.Printf(_T("%g"), d); + res.Printf(wxT("%g"), d); return (*this) << res; } @@ -985,240 +997,243 @@ int wxString::Printf(const wxChar *pszFormat, ...) int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) { // static buffer to avoid dynamic memory allocation each time - static char s_szScratch[1024]; + char s_szScratch[1024]; // using static buffer causes internal compiler err +#if 0 #if wxUSE_THREADS // protect the static buffer static wxCriticalSection critsect; wxCriticalSectionLocker lock(critsect); #endif +#endif -#if 1 // the new implementation +#if wxUSE_EXPERIMENTAL_PRINTF +// the new implementation Reinit(); for (size_t n = 0; pszFormat[n]; n++) - if (pszFormat[n] == _T('%')) { + if (pszFormat[n] == wxT('%')) { static char s_szFlags[256] = "%"; size_t flagofs = 1; bool adj_left = FALSE, in_prec = FALSE, - prec_dot = FALSE, done = FALSE; + prec_dot = FALSE, done = FALSE; int ilen = 0; size_t min_width = 0, max_width = wxSTRING_MAXLEN; do { #define CHECK_PREC if (in_prec && !prec_dot) { s_szFlags[flagofs++] = '.'; prec_dot = TRUE; } - switch (pszFormat[++n]) { - case _T('\0'): - done = TRUE; - break; - case _T('%'): - *this += _T('%'); - done = TRUE; - break; - case _T('#'): - case _T('0'): - case _T(' '): - case _T('+'): - case _T('\''): - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('-'): - CHECK_PREC - adj_left = TRUE; - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('.'): - CHECK_PREC - in_prec = TRUE; - prec_dot = FALSE; - max_width = 0; - // dot will be auto-added to s_szFlags if non-negative number follows - break; - case _T('h'): - ilen = -1; - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('l'): - ilen = 1; - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('q'): - case _T('L'): - ilen = 2; - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('Z'): - ilen = 3; - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - break; - case _T('*'): - { - int len = va_arg(argptr, int); - if (in_prec) { - if (len<0) break; - CHECK_PREC - max_width = len; - } else { - if (len<0) { - adj_left = !adj_left; - s_szFlags[flagofs++] = '-'; - len = -len; - } - min_width = len; - } - flagofs += ::sprintf(s_szFlags+flagofs,"%d",len); - } - break; - case _T('1'): case _T('2'): case _T('3'): - case _T('4'): case _T('5'): case _T('6'): - case _T('7'): case _T('8'): case _T('9'): - { - int len = 0; - CHECK_PREC - while ((pszFormat[n]>=_T('0')) && (pszFormat[n]<=_T('9'))) { - s_szFlags[flagofs++] = pszFormat[n]; - len = len*10 + (pszFormat[n] - _T('0')); - n++; - } - if (in_prec) max_width = len; - else min_width = len; - n--; // the main loop pre-increments n again - } - break; - case _T('d'): - case _T('i'): - case _T('o'): - case _T('u'): - case _T('x'): - case _T('X'): - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - s_szFlags[flagofs] = '\0'; - if (ilen == 0 ) { - int val = va_arg(argptr, int); - ::sprintf(s_szScratch, s_szFlags, val); - } - else if (ilen == -1) { - short int val = va_arg(argptr, short int); - ::sprintf(s_szScratch, s_szFlags, val); - } - else if (ilen == 1) { - long int val = va_arg(argptr, long int); - ::sprintf(s_szScratch, s_szFlags, val); - } - else if (ilen == 2) { + switch (pszFormat[++n]) { + case wxT('\0'): + done = TRUE; + break; + case wxT('%'): + *this += wxT('%'); + done = TRUE; + break; + case wxT('#'): + case wxT('0'): + case wxT(' '): + case wxT('+'): + case wxT('\''): + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('-'): + CHECK_PREC + adj_left = TRUE; + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('.'): + CHECK_PREC + in_prec = TRUE; + prec_dot = FALSE; + max_width = 0; + // dot will be auto-added to s_szFlags if non-negative number follows + break; + case wxT('h'): + ilen = -1; + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('l'): + ilen = 1; + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('q'): + case wxT('L'): + ilen = 2; + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('Z'): + ilen = 3; + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + break; + case wxT('*'): + { + int len = va_arg(argptr, int); + if (in_prec) { + if (len<0) break; + CHECK_PREC + max_width = len; + } else { + if (len<0) { + adj_left = !adj_left; + s_szFlags[flagofs++] = '-'; + len = -len; + } + min_width = len; + } + flagofs += ::sprintf(s_szFlags+flagofs,"%d",len); + } + break; + case wxT('1'): case wxT('2'): case wxT('3'): + case wxT('4'): case wxT('5'): case wxT('6'): + case wxT('7'): case wxT('8'): case wxT('9'): + { + int len = 0; + CHECK_PREC + while ((pszFormat[n]>=wxT('0')) && (pszFormat[n]<=wxT('9'))) { + s_szFlags[flagofs++] = pszFormat[n]; + len = len*10 + (pszFormat[n] - wxT('0')); + n++; + } + if (in_prec) max_width = len; + else min_width = len; + n--; // the main loop pre-increments n again + } + break; + case wxT('d'): + case wxT('i'): + case wxT('o'): + case wxT('u'): + case wxT('x'): + case wxT('X'): + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + s_szFlags[flagofs] = '\0'; + if (ilen == 0 ) { + int val = va_arg(argptr, int); + ::sprintf(s_szScratch, s_szFlags, val); + } + else if (ilen == -1) { + short int val = va_arg(argptr, short int); + ::sprintf(s_szScratch, s_szFlags, val); + } + else if (ilen == 1) { + long int val = va_arg(argptr, long int); + ::sprintf(s_szScratch, s_szFlags, val); + } + else if (ilen == 2) { #if SIZEOF_LONG_LONG - long long int val = va_arg(argptr, long long int); - ::sprintf(s_szScratch, s_szFlags, val); + long long int val = va_arg(argptr, long long int); + ::sprintf(s_szScratch, s_szFlags, val); #else - long int val = va_arg(argptr, long int); - ::sprintf(s_szScratch, s_szFlags, val); + long int val = va_arg(argptr, long int); + ::sprintf(s_szScratch, s_szFlags, val); #endif - } - else if (ilen == 3) { - size_t val = va_arg(argptr, size_t); - ::sprintf(s_szScratch, s_szFlags, val); - } - *this += wxString(s_szScratch); - done = TRUE; - break; - case _T('e'): - case _T('E'): - case _T('f'): - case _T('g'): - case _T('G'): - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - s_szFlags[flagofs] = '\0'; - if (ilen == 2) { - long double val = va_arg(argptr, long double); - ::sprintf(s_szScratch, s_szFlags, val); - } else { - double val = va_arg(argptr, double); - ::sprintf(s_szScratch, s_szFlags, val); - } - *this += wxString(s_szScratch); - done = TRUE; - break; - case _T('p'): - { - void *val = va_arg(argptr, void *); - CHECK_PREC - s_szFlags[flagofs++] = pszFormat[n]; - s_szFlags[flagofs] = '\0'; - ::sprintf(s_szScratch, s_szFlags, val); - *this += wxString(s_szScratch); - done = TRUE; - } - break; - case _T('c'): - { - wxChar val = va_arg(argptr, int); - // we don't need to honor padding here, do we? - *this += val; - done = TRUE; - } - break; - case _T('s'): - if (ilen == -1) { - // wx extension: we'll let %hs mean non-Unicode strings - char *val = va_arg(argptr, char *); + } + else if (ilen == 3) { + size_t val = va_arg(argptr, size_t); + ::sprintf(s_szScratch, s_szFlags, val); + } + *this += wxString(s_szScratch); + done = TRUE; + break; + case wxT('e'): + case wxT('E'): + case wxT('f'): + case wxT('g'): + case wxT('G'): + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + s_szFlags[flagofs] = '\0'; + if (ilen == 2) { + long double val = va_arg(argptr, long double); + ::sprintf(s_szScratch, s_szFlags, val); + } else { + double val = va_arg(argptr, double); + ::sprintf(s_szScratch, s_szFlags, val); + } + *this += wxString(s_szScratch); + done = TRUE; + break; + case wxT('p'): + { + void *val = va_arg(argptr, void *); + CHECK_PREC + s_szFlags[flagofs++] = pszFormat[n]; + s_szFlags[flagofs] = '\0'; + ::sprintf(s_szScratch, s_szFlags, val); + *this += wxString(s_szScratch); + done = TRUE; + } + break; + case wxT('c'): + { + wxChar val = va_arg(argptr, int); + // we don't need to honor padding here, do we? + *this += val; + done = TRUE; + } + break; + case wxT('s'): + if (ilen == -1) { + // wx extension: we'll let %hs mean non-Unicode strings + char *val = va_arg(argptr, char *); #if wxUSE_UNICODE - // ASCII->Unicode constructor handles max_width right - wxString s(val, wxConvLibc, max_width); + // ASCII->Unicode constructor handles max_width right + wxString s(val, wxConvLibc, max_width); #else - size_t len = wxSTRING_MAXLEN; - if (val) { - for (len = 0; val[len] && (len= 1) { - long int *val = va_arg(argptr, long int *); - *val = Len(); - } - done = TRUE; - break; - default: - if (wxIsalpha(pszFormat[n])) - // probably some flag not taken care of here yet - s_szFlags[flagofs++] = pszFormat[n]; - else { - // bad format - *this += _T('%'); // just to pass the glibc tst-printf.c - n--; - done = TRUE; - } - break; - } + if (s.Len() < min_width) + s.Pad(min_width - s.Len(), wxT(' '), adj_left); + *this += s; + } else { + wxChar *val = va_arg(argptr, wxChar *); + size_t len = wxSTRING_MAXLEN; + if (val) { + for (len = 0; val[len] && (len= 1) { + long int *val = va_arg(argptr, long int *); + *val = Len(); + } + done = TRUE; + break; + default: + if (wxIsalpha(pszFormat[n])) + // probably some flag not taken care of here yet + s_szFlags[flagofs++] = pszFormat[n]; + else { + // bad format + *this += wxT('%'); // just to pass the glibc tst-printf.c + n--; + done = TRUE; + } + break; + } #undef CHECK_PREC } while (!done); } else *this += pszFormat[n]; @@ -1264,33 +1279,37 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) // ---------------------------------------------------------------------------- // misc other operations // ---------------------------------------------------------------------------- + +// returns TRUE if the string matches the pattern which may contain '*' and +// '?' metacharacters (as usual, '?' matches any character and '*' any number +// of them) bool wxString::Matches(const wxChar *pszMask) const { // check char by char const wxChar *pszTxt; - for ( pszTxt = c_str(); *pszMask != _T('\0'); pszMask++, pszTxt++ ) { + for ( pszTxt = c_str(); *pszMask != wxT('\0'); pszMask++, pszTxt++ ) { switch ( *pszMask ) { - case _T('?'): - if ( *pszTxt == _T('\0') ) + case wxT('?'): + if ( *pszTxt == wxT('\0') ) return FALSE; - pszTxt++; - pszMask++; + // pszText and pszMask will be incremented in the loop statement + break; - case _T('*'): + case wxT('*'): { // ignore special chars immediately following this one - while ( *pszMask == _T('*') || *pszMask == _T('?') ) + while ( *pszMask == wxT('*') || *pszMask == wxT('?') ) pszMask++; // if there is nothing more, match - if ( *pszMask == _T('\0') ) + if ( *pszMask == wxT('\0') ) return TRUE; // are there any other metacharacters in the mask? size_t uiLenMask; - const wxChar *pEndMask = wxStrpbrk(pszMask, _T("*?")); + const wxChar *pEndMask = wxStrpbrk(pszMask, wxT("*?")); if ( pEndMask != NULL ) { // we have to match the string between two metachars @@ -1320,7 +1339,7 @@ bool wxString::Matches(const wxChar *pszMask) const } // match only if nothing left - return *pszTxt == _T('\0'); + return *pszTxt == wxT('\0'); } // Count the number of chars @@ -1470,7 +1489,7 @@ size_t wxString::find_last_of(const wxChar* sz, size_t nStart) const wxASSERT( nStart <= Len() ); } - for ( const char *p = c_str() + length() - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + length() - 1; p >= c_str(); p-- ) { if ( wxStrchr(sz, *p) ) return p - c_str(); @@ -1490,7 +1509,7 @@ size_t wxString::find_first_not_of(const wxChar* sz, size_t nStart) const wxASSERT( nStart <= Len() ); } - size_t nAccept = strspn(c_str() + nStart, sz); + size_t nAccept = wxStrspn(c_str() + nStart, sz); if ( nAccept >= length() - nStart ) return npos; else @@ -1501,7 +1520,7 @@ size_t wxString::find_first_not_of(wxChar ch, size_t nStart) const { wxASSERT( nStart <= Len() ); - for ( const char *p = c_str() + nStart; *p; p++ ) + for ( const wxChar *p = c_str() + nStart; *p; p++ ) { if ( *p != ch ) return p - c_str(); @@ -1521,7 +1540,7 @@ size_t wxString::find_last_not_of(const wxChar* sz, size_t nStart) const wxASSERT( nStart <= Len() ); } - for ( const char *p = c_str() + nStart - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- ) { if ( !wxStrchr(sz, *p) ) return p - c_str(); @@ -1541,7 +1560,7 @@ size_t wxString::find_last_not_of(wxChar ch, size_t nStart) const wxASSERT( nStart <= Len() ); } - for ( const char *p = c_str() + nStart - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- ) { if ( *p != ch ) return p - c_str(); @@ -1670,7 +1689,12 @@ void wxArrayString::Grow() else { // otherwise when it's called for the first time, nIncrement would be 0 // and the array would never be expanded +#if defined(__VISAGECPP__) + int array_size = ARRAY_DEFAULT_INITIAL_SIZE; + wxASSERT( array_size != 0 ); +#else wxASSERT( ARRAY_DEFAULT_INITIAL_SIZE != 0 ); +#endif // add 50% but not too much size_t nIncrement = m_nSize < ARRAY_DEFAULT_INITIAL_SIZE @@ -1747,7 +1771,7 @@ void wxArrayString::Shrink() // only do it if we have some memory to free if( m_nCount < m_nSize ) { // allocates exactly as much memory as we need - wxChar **pNew = new wxChar *[m_nCount]; + wxChar **pNew = new wxChar *[m_nCount]; // copy data to new location memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *)); @@ -1865,7 +1889,7 @@ static wxArrayString::CompareFunction gs_compareFunction = NULL; static bool gs_sortAscending = TRUE; // function which is called by quick sort -static int wxStringCompareFunction(const void *first, const void *second) +static int LINKAGEMODE wxStringCompareFunction(const void *first, const void *second) { wxString *strFirst = (wxString *)first; wxString *strSecond = (wxString *)second; @@ -1913,424 +1937,3 @@ void wxArrayString::DoSort() qsort(m_pItems, m_nCount, sizeof(wxChar *), wxStringCompareFunction); } -// ============================================================================ -// MBConv -// ============================================================================ - -WXDLLEXPORT_DATA(wxMBConv *) wxConvCurrent = &wxConvLibc; -#if !wxUSE_WCHAR_T -WXDLLEXPORT_DATA(wxMBConv) wxConvLibc, wxConvFile; -#endif - -#if wxUSE_WCHAR_T - -// ---------------------------------------------------------------------------- -// standard libc conversion -// ---------------------------------------------------------------------------- - -WXDLLEXPORT_DATA(wxMBConv) wxConvLibc; - -size_t wxMBConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - return wxMB2WC(buf, psz, n); -} - -size_t wxMBConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const -{ - return wxWC2MB(buf, psz, n); -} - -// ---------------------------------------------------------------------------- -// standard file conversion -// ---------------------------------------------------------------------------- - -WXDLLEXPORT_DATA(wxMBConvFile) wxConvFile; - -// just use the libc conversion for now -size_t wxMBConvFile::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - return wxMB2WC(buf, psz, n); -} - -size_t wxMBConvFile::WC2MB(char *buf, const wchar_t *psz, size_t n) const -{ - return wxWC2MB(buf, psz, n); -} - -// ---------------------------------------------------------------------------- -// standard gdk conversion -// ---------------------------------------------------------------------------- - -#ifdef __WXGTK12__ -WXDLLEXPORT_DATA(wxMBConvGdk) wxConvGdk; - -#include - -size_t wxMBConvGdk::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - if (buf) { - return gdk_mbstowcs((GdkWChar *)buf, psz, n); - } else { - GdkWChar *nbuf = new GdkWChar[n=strlen(psz)]; - size_t len = gdk_mbstowcs(nbuf, psz, n); - delete [] nbuf; - return len; - } -} - -size_t wxMBConvGdk::WC2MB(char *buf, const wchar_t *psz, size_t n) const -{ - char *mbstr = gdk_wcstombs((GdkWChar *)psz); - size_t len = mbstr ? strlen(mbstr) : 0; - if (buf) { - if (len > n) len = n; - memcpy(buf, psz, len); - if (len < n) buf[len] = 0; - } - return len; -} -#endif // GTK > 1.0 - -// ---------------------------------------------------------------------------- -// UTF-7 -// ---------------------------------------------------------------------------- - -WXDLLEXPORT_DATA(wxMBConvUTF7) wxConvUTF7; - -#if 0 -static char utf7_setD[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789'(),-./:?"; -static char utf7_setO[]="!\"#$%&*;<=>@[]^_`{|}"; -static char utf7_setB[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -#endif - -// TODO: write actual implementations of UTF-7 here -size_t wxMBConvUTF7::MB2WC(wchar_t * WXUNUSED(buf), - const char * WXUNUSED(psz), - size_t WXUNUSED(n)) const -{ - return 0; -} - -size_t wxMBConvUTF7::WC2MB(char * WXUNUSED(buf), - const wchar_t * WXUNUSED(psz), - size_t WXUNUSED(n)) const -{ - return 0; -} - -// ---------------------------------------------------------------------------- -// UTF-8 -// ---------------------------------------------------------------------------- - -WXDLLEXPORT_DATA(wxMBConvUTF8) wxConvUTF8; - -static unsigned long utf8_max[]={0x7f,0x7ff,0xffff,0x1fffff,0x3ffffff,0x7fffffff,0xffffffff}; - -size_t wxMBConvUTF8::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - size_t len = 0; - - while (*psz && ((!buf) || (len>cnt); - while (cnt--) { - cc = *psz++; - if ((cc&0xC0)!=0x80) { - // invalid UTF-8 sequence - return (size_t)-1; - } - res=(res<<6)|(cc&0x3f); - } - if (res<=utf8_max[ocnt]) { - // illegal UTF-8 encoding - return (size_t)-1; - } - if (buf) *buf++=res; - len++; - } - } - } - if (buf && (lenutf8_max[cnt]; cnt++); - if (!cnt) { - // plain ASCII char - if (buf) *buf++=cc; - len++; - } else { - len+=cnt+1; - if (buf) { - *buf++=(-128>>cnt)|((cc>>(cnt*6))&(0x3f>>cnt)); - while (cnt--) - *buf++=0x80|((cc>>(cnt*6))&0x3f); - } - } - } - if (buf && (lennames.Add(token.GetNextToken()); - } - else if (cmd == _T("")) - cset->names.Add(token.GetNextToken()); - else if (cmd == _T("")) - comchar = token.GetNextToken(); - else if (cmd == _T("")) - escchar = token.GetNextToken(); - else if (cmd == _T("")) { - delete cset; - cset = (wxCharacterSet *) NULL; - break; // we don't support multibyte charsets ourselves (yet) - } - else if (cmd == _T("CHARMAP")) { - cset->data = (wchar_t *)calloc(256, sizeof(wchar_t)); - in_charset = TRUE; - } - else if (cmd == _T("END")) { - if (token.GetNextToken() == _T("CHARMAP")) - in_charset = FALSE; - } - else if (in_charset) { - // format: /x00 NULL (NUL) - // /x41 LATIN CAPITAL LETTER A - wxString hex = token.GetNextToken(); - // skip whitespace (why doesn't wxStringTokenizer do this?) - while (wxIsEmpty(hex) && token.HasMoreTokens()) hex = token.GetNextToken(); - wxString uni = token.GetNextToken(); - // skip whitespace again - while (wxIsEmpty(uni) && token.HasMoreTokens()) uni = token.GetNextToken(); - - if ((hex.Len() > 2) && (hex.GetChar(0) == escchar) && (hex.GetChar(1) == _T('x')) && - (uni.Left(2) == _T("=0) { - unsigned long uni1 = ::wxHexToDec(uni.Mid(2,2)); - unsigned long uni2 = ::wxHexToDec(uni.Mid(4,2)); - cset->data[pos] = (uni1 << 16) | uni2; - // wxFprintf(stderr,_T("char %02x mapped to %04x (%c)\n"),pos,cset->data[pos],cset->data[pos]); - } - } - } - } - if (cset) { - cset->names.Shrink(); - wxCharsets.Add(cset); - } - } - } -#endif - wxCharsets.Shrink(); -} - -static wxCharacterSet *wxFindCharacterSet(const wxChar *charset) -{ - if (!charset) return (wxCharacterSet *)NULL; - wxLoadCharacterSets(); - for (size_t n=0; n4) { - if (wxString(charset,4) == _T("8859")) { - codeset << _T("8859-"); - if (*charset == _T('-')) charset++; - } - } - } - codeset << charset; - codeset.MakeUpper(); - m_name = wxStrdup(codeset.c_str()); - m_deferred = TRUE; -#endif - } -} - -void wxCSConv::LoadNow() -{ -// wxPrintf(_T("Conversion request\n")); - if (m_deferred) { - if (!m_name) { -#ifdef __UNIX__ - wxChar *lang = wxGetenv(_T("LANG")); - wxChar *dot = lang ? wxStrchr(lang, _T('.')) : (wxChar *)NULL; - if (dot) SetName(dot+1); -#endif - } - m_cset = wxFindCharacterSet(m_name); - m_deferred = FALSE; - } -} - -size_t wxCSConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const -{ - ((wxCSConv *)this)->LoadNow(); // discard constness - if (buf) { - if (m_cset) { - for (size_t c=0; cdata[(unsigned char)(psz[c])]; - } else { - // latin-1 (direct) - for (size_t c=0; cLoadNow(); // discard constness - if (buf) { - if (m_cset) { - for (size_t c=0; cdata[n] != psz[c]); n++); - buf[c] = (n>0xff) ? '?' : n; - } - } else { - // latin-1 (direct) - for (size_t c=0; c0xff) ? '?' : psz[c]; - } - return n; - } - return wcslen(psz); -} - -#endif//wxUSE_WCHAR_T - -#if wxUSE_WCHAR_T -const wxWCharBuffer wxMBConv::cMB2WC(const char *psz) const - { - if (psz) { - size_t nLen = MB2WC((wchar_t *) NULL, psz, 0); - wxWCharBuffer buf(nLen); - MB2WC(WCSTRINGCAST buf, psz, nLen); - return buf; - } else return wxWCharBuffer((wchar_t *) NULL); - } - -const wxCharBuffer wxMBConv::cWC2MB(const wchar_t *psz) const - { - if (psz) { - size_t nLen = WC2MB((char *) NULL, psz, 0); - wxCharBuffer buf(nLen); - WC2MB(MBSTRINGCAST buf, psz, nLen); - return buf; - } else return wxCharBuffer((char *) NULL); - } - -#endif//wxUSE_WCHAR_T -