You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by am...@apache.org on 2006/07/04 13:57:03 UTC
svn commit: r418988 - in /xerces/c/trunk: configure.ac
src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp
Author: amassari
Date: Tue Jul 4 04:57:03 2006
New Revision: 418988
URL: http://svn.apache.org/viewvc?rev=418988&view=rev
Log:
Removed usage of MB_CUR_MAX from iconv transcoder; if the block-oriented APIs are available, use them (jira# 1444, patch by Axel Weiss)
Modified:
xerces/c/trunk/configure.ac
xerces/c/trunk/src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp
Modified: xerces/c/trunk/configure.ac
URL: http://svn.apache.org/viewvc/xerces/c/trunk/configure.ac?rev=418988&r1=418987&r2=418988&view=diff
==============================================================================
--- xerces/c/trunk/configure.ac (original)
+++ xerces/c/trunk/configure.ac Tue Jul 4 04:57:03 2006
@@ -95,6 +95,7 @@
strcasecmp strncasecmp stricmp strnicmp strchr strdup \
strrchr strstr strtol strtoul \
towupper towlower iswspace \
+ mbrlen wcsrtombs mbsrtowcs \
])
AC_SUBST([SHREXT], [$shrext_cmds])
Modified: xerces/c/trunk/src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp
URL: http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp?rev=418988&r1=418987&r2=418988&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp (original)
+++ xerces/c/trunk/src/xercesc/util/Transcoders/Iconv/IconvTransService.cpp Tue Jul 4 04:57:03 2006
@@ -66,6 +66,10 @@
chLatin_I, chLatin_C, chLatin_o, chLatin_n, chLatin_v, chNull
};
+// ---------------------------------------------------------------------------
+// the following is defined by 'man mbrtowc':
+// ---------------------------------------------------------------------------
+static const size_t TRANSCODING_ERROR = (size_t)(-1);
// ---------------------------------------------------------------------------
// Local methods
@@ -231,14 +235,22 @@
if (!srcText)
return 0;
- unsigned int len=0;
- unsigned int size=strlen(srcText);
- for( unsigned int i = 0; i < size; ++len )
- {
- unsigned int retVal=::mblen( &srcText[i], MB_CUR_MAX );
- if( -1 == retVal )
+ unsigned int len = 0;
+ const char *src = srcText;
+#if HAVE_MBRLEN
+ mbstate_t st;
+ memset(&st, 0, sizeof(st));
+#endif
+ for ( ; *src; ++len)
+ {
+#if HAVE_MBRLEN
+ int l=::mblen( src, MB_CUR_MAX );
+#else
+ int l=::mbrlen( src, MB_CUR_MAX, &st );
+#endif
+ if( l == TRANSCODING_ERROR )
return 0;
- i += retVal;
+ src += l;
}
return len;
}
@@ -388,13 +400,14 @@
}
-static void reallocString(char *&ref, size_t &size, MemoryManager* const manager, bool releaseOld)
+template <typename T>
+void reallocString(T *&ref, size_t &size, MemoryManager* const manager, bool releaseOld)
{
- char *tmp = (char*)manager->allocate(2 * size * sizeof(char));
- memcpy(tmp, ref, size * sizeof(char));
- if (releaseOld) manager->deallocate(ref);
- ref = tmp;
- size *= 2;
+ T *tmp = (T*)manager->allocate(2 * size * sizeof(T));
+ memcpy(tmp, ref, size * sizeof(T));
+ if (releaseOld) manager->deallocate(ref);
+ ref = tmp;
+ size *= 2;
}
@@ -403,46 +416,74 @@
{
if (!toTranscode)
return 0;
+ size_t srcCursor = 0, dstCursor = 0;
+ size_t resultSize = gTempBuffArraySize;
+ char localBuffer[gTempBuffArraySize];
+ char* resultString = localBuffer;
+
+#if HAVE_WCSRTOMBS
+ mbstate_t st;
+ memset(&st, 0, sizeof(st));
+ wchar_t srcBuffer[gTempBuffArraySize];
+ srcBuffer[gTempBuffArraySize - 1] = 0;
+ const wchar_t *src = 0;
+
+ while (toTranscode[srcCursor] || src)
+ {
+ if (src == 0) // copy a piece of the source string into a local
+ // buffer, converted to wchar_t and NULL-terminated.
+ // after that, src points to the beginning of the
+ // local buffer and is used for the call to ::wcsrtombs
+ {
+ size_t i;
+ for (i=0; i<gTempBuffArraySize-1; ++i)
+ {
+ srcBuffer[i] = toTranscode[srcCursor];
+ if (srcBuffer[i] == '\0')
+ break;
+ ++srcCursor;
+ }
+ src = srcBuffer;
+ }
+
+ size_t len = ::wcsrtombs(resultString + dstCursor, &src, resultSize - dstCursor, &st);
+ if (len == TRANSCODING_ERROR)
+ {
+ dstCursor = 0;
+ break;
+ }
+ dstCursor += len;
+ if (src != 0) // conversion not finished. This *always* means there
+ // was not enough room in the destination buffer.
+ {
+ reallocString<char>(resultString, resultSize, manager, resultString != localBuffer);
+ }
+ }
+#else
+ while (toTranscode[srcCursor])
+ {
+ char mbBuf[16]; // MB_CUR_MAX is not defined as a constant on some platforms
+ int len = wctomb(mbBuf, toTranscode[srcCursor++]);
+ if (len < 0)
+ {
+ dstCursor = 0;
+ break;
+ }
+ if (dstCursor + len >= resultSize - 1)
+ reallocString<char>(resultString, resultSize, manager, resultString != localBuffer);
+ for (int j=0; j<len; ++j)
+ resultString[dstCursor++] = mbBuf[j];
+ }
+#endif
- size_t resultSize = gTempBuffArraySize;
- size_t srcCursor = 0, dstCursor = 0;
- char localBuffer[gTempBuffArraySize];
- char* resultString = localBuffer;
-
- while (toTranscode[srcCursor])
- {
- char mbBuf[MB_CUR_MAX];
- int len = wctomb(mbBuf, toTranscode[srcCursor++]), j;
- if (len < 0)
- {
- dstCursor = 0;
- break;
- }
- if (dstCursor + len >= resultSize - 1)
- reallocString(resultString, resultSize, manager, resultString != localBuffer);
- for (j=0; j<len; ++j)
- resultString[dstCursor++] = mbBuf[j];
- }
-
- if (resultString == localBuffer)
- {
- resultString = (char*)manager->allocate((dstCursor + 1) * sizeof(char));
- memcpy(resultString, localBuffer, dstCursor * sizeof(char));
- }
-
- resultString[dstCursor] = '\0';
- return resultString;
-}
-
-
+ if (resultString == localBuffer)
+ {
+ resultString = (char*)manager->allocate((dstCursor + 1) * sizeof(char));
+ memcpy(resultString, localBuffer, dstCursor * sizeof(char));
+ }
-static void reallocXMLString(XMLCh *&ref, size_t &size, MemoryManager* const manager, bool releaseOld)
-{
- XMLCh *tmp = (XMLCh*)manager->allocate(2 * size * sizeof(XMLCh));
- memcpy(tmp, ref, size * sizeof(XMLCh));
- if (releaseOld) manager->deallocate(ref);
- ref = tmp;
- size *= 2;
+ resultString[dstCursor] = '\0';
+ return resultString;
}
XMLCh* IconvLCPTranscoder::transcode(const char* const toTranscode,
@@ -450,35 +491,68 @@
{
if (!toTranscode)
return 0;
- XMLCh localBuffer[gTempBuffArraySize];
- XMLCh* resultString = localBuffer;
- size_t resultSize = gTempBuffArraySize;
- size_t srcCursor = 0, dstCursor = 0, srcLen = strlen(toTranscode);
-
- for ( ;; )
- {
- wchar_t wcBuf[1];
- int len = mbtowc(wcBuf, toTranscode + srcCursor, srcLen - srcCursor);
- if (len <= 0)
- {
- if (len < 0)
- dstCursor = 0;
- break;
- }
- srcCursor += len;
- if (dstCursor + 1 >= resultSize - 1)
- reallocXMLString(resultString, resultSize, manager, resultString != localBuffer);
- resultString[dstCursor++] = wcBuf[0];
- }
-
- if (resultString == localBuffer)
- {
- resultString = (XMLCh*)manager->allocate((dstCursor + 1) * sizeof(XMLCh));
- memcpy(resultString, localBuffer, dstCursor * sizeof(XMLCh));
- }
+ size_t resultSize = gTempBuffArraySize;
+ size_t srcCursor = 0, dstCursor = 0;
+
+#if HAVE_MBSRTOWCS
+ wchar_t localBuffer[gTempBuffArraySize];
+ wchar_t *tmpString = localBuffer;
+
+ mbstate_t st;
+ memset(&st, 0, sizeof(st));
+ const char *src = toTranscode;
+
+ while(true)
+ {
+ size_t len = ::mbsrtowcs(tmpString + dstCursor, &src, resultSize - dstCursor, &st);
+ if (len == TRANSCODING_ERROR)
+ {
+ dstCursor = 0;
+ break;
+ }
+ dstCursor += len;
+ if (src == 0) // conversion finished
+ break;
+ if (dstCursor >= resultSize - 1)
+ reallocString<wchar_t>(tmpString, resultSize, manager, tmpString != localBuffer);
+ }
+ // make a final copy, converting from wchar_t to XMLCh:
+ XMLCh* resultString = (XMLCh*)manager->allocate((dstCursor + 1) * sizeof(XMLCh));
+ size_t i;
+ for (i=0; i<dstCursor; ++i)
+ resultString[i] = tmpString[i];
+ if (tmpString != localBuffer) // did we allocate something?
+ manager->deallocate(tmpString);
+#else
+ XMLCh localBuffer[gTempBuffArraySize];
+ XMLCh* resultString = localBuffer;
+ size_t srcLen = strlen(toTranscode);
+
+ while(true)
+ {
+ wchar_t wcBuf[1];
+ int len = mbtowc(wcBuf, toTranscode + srcCursor, srcLen - srcCursor);
+ if (len <= 0)
+ {
+ if (len < 0)
+ dstCursor = 0;
+ break;
+ }
+ srcCursor += len;
+ if (dstCursor + 1 >= resultSize - 1)
+ reallocString<XMLCh>(resultString, resultSize, manager, resultString != localBuffer);
+ resultString[dstCursor++] = wcBuf[0];
+ }
+
+ if (resultString == localBuffer)
+ {
+ resultString = (XMLCh*)manager->allocate((dstCursor + 1) * sizeof(XMLCh));
+ memcpy(resultString, localBuffer, dstCursor * sizeof(XMLCh));
+ }
+#endif
- resultString[dstCursor] = L'\0';
- return resultString;
+ resultString[dstCursor] = L'\0';
+ return resultString;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org