Branko Čibej wrote:
> Stefan Küng wrote:
>
>> [[[
>> Compile time switch to use the Windows API's instead of apr_iconv to do
>> the UTF-8 conversions.
>>
>> * subversion/libsvn_subr/utf.c
>> (win_xlate_conv_buffer): New function, replacing apr_xlate_conv_buffer
>> but using the Windows API instead of iconv.
>> (get_xlate_handle_node): Instead of calling apr_xlate_open fill in the
>> handle struct with Windows API information.
>> (convert_to_stringbuf): Check if the source string has zero length
>> before allocating memory.
>> (convert_to_stringbuf): Call win_xlate_conv_buffer instead of
>> apr_xlate_conv_buffer.
>> ]]]
>> Index: subversion/libsvn_subr/utf.c
>> ===================================================================
>> --- subversion/libsvn_subr/utf.c (Revision 16653)
>> +++ subversion/libsvn_subr/utf.c (Arbeitskopie)
>> @@ -125,6 +125,70 @@
>> }
>> }
>>
>> +#if defined(WIN32) && defined(NOICONV)
>> +/* declare the struct here, so we can use its members */
>> +struct apr_xlate_t {
>> + apr_pool_t *pool;
>> + char *frompage;
>> + char *topage;
>> + char *sbcs_table;
>> +};
>>
>>
> We can't redefine apr_xlate_t. You'll have to call it something else.
Ok, revised patch attached.
> [...]
>
>> + requiredlen = MultiByteToWideChar(fromUTF8 ? CP_UTF8 : CP, 0,
>> inbuf, -1, 0, 0);
>>
>>
> IIRC CP_UTF8 is only supported on Win2k (maybe even WinXP) and later. So
> the conversion will fail on older versions of Windows.
Actually, CP_UTF8 is available for:
Windows 98/Me, Windows NT 4.0 and later
for Win95, you'd have to link with the MSLU (Microsoft Layer for
Unicode) dll to get CP_UTF8. But that's then up to the clients using the
library (if they want to support Win95 at all).
Stefan
--
___
oo // \\ "De Chelonian Mobile"
(_,\/ \_/ \ TortoiseSVN
\ \_/_\_/> The coolest Interface to (Sub)Version Control
/_/ \_\ http://tortoisesvn.tigris.org
[[[
Compile time switch to use the Windows API's instead of apr_iconv to do
the UTF-8 conversions.
* subversion/libsvn_subr/utf.c
(win_xlate_t) : New struct to use instead of apr_xlate_t.
(win_xlate_conv_buffer): New function, replacing apr_xlate_conv_buffer
but using the Windows API instead of iconv.
(get_xlate_handle_node): Instead of calling apr_xlate_open fill in the
handle struct with Windows API information.
(convert_to_stringbuf): Check if the source string has zero length
before allocating memory.
(convert_to_stringbuf): Call win_xlate_conv_buffer instead of
apr_xlate_conv_buffer.
]]]
Index: subversion/libsvn_subr/utf.c
===================================================================
--- subversion/libsvn_subr/utf.c (Revision 16653)
+++ subversion/libsvn_subr/utf.c (Arbeitskopie)
@@ -42,6 +42,14 @@
static apr_thread_mutex_t *xlate_handle_mutex = NULL;
#endif
+#if defined(WIN32) && defined(NOICONV)
+typedef struct win_xlate_t {
+ apr_pool_t *pool;
+ char *frompage;
+ char *topage;
+ char *sbcs_table;
+} win_xlate_t;
+#endif
/* The xlate handle cache is a global hash table with linked lists of xlate
* handles. In multi-threaded environments, a thread "borrows" an xlate
* handle from the cache during a translation and puts it back afterwards.
@@ -52,7 +60,11 @@
* is the number of simultanous handles in use for that key. */
typedef struct xlate_handle_node_t {
+#if defined(WIN32) && defined(NOICONV)
+ win_xlate_t *handle;
+#else
apr_xlate_t *handle;
+#endif
/* FALSE if the handle is not valid, since its pool is being
destroyed. */
svn_boolean_t valid;
@@ -125,6 +137,63 @@
}
}
+#if defined(WIN32) && defined(NOICONV)
+/* almost equivalent of apr_xlate_conv_buffer(), using the Windows API's
+ * MultiByteToWideChar() and WideCharToMultiByte() to get rid of the apr_iconv
+ * or iconv dependency. Since Subversion only converts from or to UTF-8, we
+ * don't really need the whole iconv library. */
+static apr_status_t win_xlate_conv_buffer(win_xlate_t *convset,
+ const char * inbuf,
+ apr_size_t *inbytes_left,
+ char *outbuf,
+ apr_size_t *outbytes_left)
+{
+ svn_boolean_t fromUTF8 = FALSE;
+ int requiredlen = 0;
+ wchar_t * widebuffer = 0;
+ apr_size_t convertedchars = 0;
+ UINT CP = CP_ACP;
+
+ if (convset->frompage)
+ {
+ if (apr_strnatcmp (convset->frompage, "UTF-8") == 0)
+ fromUTF8 = TRUE;
+ else
+ CP = atoi(convset->frompage+2);
+ }
+ if ((fromUTF8)&&(convset->topage))
+ {
+ CP = atoi(convset->topage+2);
+ }
+ if (CP == 0)
+ CP = CP_THREAD_ACP;
+
+ requiredlen = MultiByteToWideChar(fromUTF8 ? CP_UTF8 : CP, 0, inbuf, -1, 0, 0);
+ if (requiredlen == 0)
+ return APR_EINVAL;
+ widebuffer = apr_pcalloc(convset->pool, requiredlen*sizeof(wchar_t));
+ if (widebuffer == 0)
+ return APR_ENOMEM;
+ if (MultiByteToWideChar(fromUTF8 ? CP_UTF8 : CP, 0, inbuf, -1, widebuffer,
+ requiredlen) == 0)
+ return APR_EINVAL;
+ convertedchars = WideCharToMultiByte(fromUTF8 ? CP : CP_UTF8, 0,
+ widebuffer, requiredlen, outbuf,
+ *outbytes_left, NULL, NULL);
+ if ((convertedchars == 0)&&(GetLastError() == ERROR_INSUFFICIENT_BUFFER))
+ {
+ *outbytes_left = 0;
+ return APR_SUCCESS;
+ }
+ if (convertedchars == 0)
+ return APR_EINVAL;
+
+ *inbytes_left = 0;
+ *outbytes_left = *outbytes_left - convertedchars + 1;
+ return APR_SUCCESS;
+}
+#endif
+
/* Set *RET to a handle node for converting from FROMPAGE to TOPAGE,
creating the handle node if it doesn't exist in USERDATA_KEY.
If a node is not cached and apr_xlate_open() returns APR_EINVAL or
@@ -142,7 +211,11 @@
xlate_handle_node_t **old_node_p;
xlate_handle_node_t *old_node = NULL;
apr_status_t apr_err;
- apr_xlate_t *handle;
+#if defined(WIN32) && defined(NOICONV)
+ win_xlate_t *handle = NULL;
+#else
+ apr_xlate_t *handle = NULL;
+#endif
svn_error_t *err = NULL;
/* If we already have a handle, just return it. */
@@ -208,7 +281,28 @@
pool = apr_hash_pool_get (xlate_handle_hash);
/* Try to create a handle. */
+#if defined(WIN32) && defined(NOICONV)
+ /* instead of opening apr_xlate and the iconv library, we just provide
+ * the appropriate information in the handle */
+ apr_err = APR_SUCCESS;
+ handle = (win_xlate_t*)apr_pcalloc(pool, sizeof(win_xlate_t));
+ if (handle)
+ {
+ handle->pool = pool;
+ if ((topage != APR_LOCALE_CHARSET)&&(topage != APR_DEFAULT_CHARSET))
+ handle->topage = apr_pstrdup(pool, topage);
+ else
+ handle->topage = NULL;
+ if ((frompage != APR_LOCALE_CHARSET)&&(frompage != APR_DEFAULT_CHARSET))
+ handle->frompage = apr_pstrdup(pool, frompage);
+ else
+ handle->frompage = NULL;
+ }
+ else
+ apr_err = APR_ENOMEM;
+#else
apr_err = apr_xlate_open (&handle, topage, frompage, pool);
+#endif
if (APR_STATUS_IS_EINVAL (apr_err) || APR_STATUS_IS_ENOTIMPL (apr_err))
handle = NULL;
@@ -400,15 +494,15 @@
apr_size_t destlen = 0;
char *destbuf;
- /* Initialize *DEST to an empty stringbuf. */
- *dest = svn_stringbuf_create ("", pool);
- destbuf = (*dest)->data;
-
/* Not only does it not make sense to convert an empty string, but
apr-iconv is quite unreasonable about not allowing that. */
if (src_length == 0)
return SVN_NO_ERROR;
+ /* Initialize *DEST to an empty stringbuf. */
+ *dest = svn_stringbuf_create ("", pool);
+ destbuf = (*dest)->data;
+
do
{
/* A 1:2 ratio of input characters to output characters should
@@ -429,11 +523,19 @@
destlen = buflen - (*dest)->len;
/* Attempt the conversion. */
+#if defined(WIN32) && defined(NOICONV)
+ apr_err = win_xlate_conv_buffer (node->handle,
+ src_data + (src_length - srclen),
+ &srclen,
+ destbuf,
+ &destlen);
+#else
apr_err = apr_xlate_conv_buffer (node->handle,
src_data + (src_length - srclen),
&srclen,
destbuf,
&destlen);
+#endif
/* Now, update the *DEST->len to track the amount of output data
churned out so far from this loop. */
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Oct 12 20:06:40 2005