]> mj.ucw.cz Git - libucw.git/commitdiff
Slightly faster mp-charconv... minor change
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Wed, 8 Mar 2006 20:46:05 +0000 (21:46 +0100)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Wed, 8 Mar 2006 20:46:05 +0000 (21:46 +0100)
charset/mp-charconv.c
charset/mp-charconv.h
charset/stk-charconv.c
charset/stk-charconv.h

index 0235ae7693257fd00037d38ea06f78a2902f8b4f..6976212be5928bad1f48a5a4209df6f9aafd0f48 100644 (file)
@@ -2,15 +2,50 @@
  *     Sherlock Library -- Character Conversion with Allocation on a Memory Pool 
  *
  *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
  */
 
 #include "lib/lib.h"
 #include "lib/mempool.h"
 #include "charset/mp-charconv.h"
-#include "charset/stk-charconv.h"
+#include <string.h>
+#include <alloca.h>
 
 byte *
 mp_conv(struct mempool *mp, byte *s, uns in_cs, uns out_cs)
 {
-  return mp_strdup(mp, stk_conv(s, in_cs, out_cs));
+  if (in_cs == out_cs)
+    return mp_strdup(mp, s);
+  struct conv_context c;
+  char *b[32];
+  uns bs[32], n = 0, sum = 0;
+  uns l = strlen(s) + 1;
+  
+  conv_init(&c);
+  conv_set_charset(&c, in_cs, out_cs);
+  c.source = s;
+  c.source_end = s + l;
+
+  for (;;)
+    {
+      l <<= 1;
+      c.dest_start = c.dest = b[n] = alloca(l);
+      c.dest_end = c.dest_start+ l;
+      uns r = conv_run(&c);
+      sum += bs[n++] = c.dest - c.dest_start;
+      if (r & CONV_SOURCE_END)
+        {
+          c.dest_start = c.dest = mp_alloc(mp, sum);
+          for (uns i = 0; i < n; i++)
+            {
+              memcpy(c.dest, b[i], bs[i]);
+              c.dest += bs[i];
+            }
+         return c.dest_start;
+        }
+    }
 }
+
index f3d7bd232016375eaf93c1059fde0a4a1b788e26..2677c8049a1ba32fec9e93b56f717d95a79c05f8 100644 (file)
@@ -2,6 +2,9 @@
  *     Sherlock Library -- Character Conversion with Allocation on a Memory Pool 
  *
  *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
  */
 
 #ifndef _CHARSET_MP_CHARCONV_H
index 10af721180478165c5947ae189f62fa3748eb034..2dca1c56b7ba525a190f7fc1e60ef3950facbca1 100644 (file)
@@ -2,6 +2,9 @@
  *     Sherlock Library -- Character Conversion with Allocation on the Stack 
  *
  *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
  */
 
 #include "lib/lib.h"
 #define INITIAL_MIN_SIZE       16
 #define INITIAL_SCALE          2
 
-void
-stk_conv_init(struct stk_conv_context *c, byte *s, uns in_cs, uns out_cs)
+uns
+stk_conv_init(struct conv_context *c, byte *s, uns in_cs, uns out_cs)
 {
   uns l = strlen(s);
   if (in_cs == out_cs)
   {
-    c->c.source = s;
-    c->c.source_end = NULL;
-    c->len = l + 1;
-    return;
+    c->source = s;
+    c->source_end = NULL;
+    return l + 1;
   }
-  conv_init(&c->c);
-  conv_set_charset(&c->c, in_cs, out_cs);
-  c->c.source = s;
-  c->c.source_end = s + l + 1;
+  conv_init(c);
+  conv_set_charset(c, in_cs, out_cs);
+  c->source = s;
+  c->source_end = s + l + 1;
   if (l < (INITIAL_MIN_SIZE - 1) / INITIAL_SCALE)
-    c->len = INITIAL_MIN_SIZE;
+    return INITIAL_MIN_SIZE;
   else
-    c->len = l * INITIAL_SCALE + 1;
-  c->len = 1;
+    return l * INITIAL_SCALE + 1;
 }
 
-int
-stk_conv_step(struct stk_conv_context *c, byte *buf)
+uns
+stk_conv_step(struct conv_context *c, byte *buf, uns len)
 {
-  if (!c->c.source_end)
+  if (!c->source_end)
   {
-    memcpy(buf, c->c.source, c->len);
-    c->c.dest_start = buf;
+    memcpy(buf, c->source, len);
+    c->dest_start = buf;
     return 0;
   }
-  if (c->c.dest_start)
+  if (c->dest_start)
   {
-    uns l = c->c.dest_end - c->c.dest_start;
-    memcpy(buf, c->c.dest_start, l);
-    c->c.dest = buf + l;
+    uns l = c->dest_end - c->dest_start;
+    memcpy(buf, c->dest_start, l);
+    c->dest = buf + l;
   }
   else
-    c->c.dest = buf;
-  c->c.dest_start = buf;
-  c->c.dest_end = buf + c->len;
-  if ((conv_run(&c->c) & CONV_SOURCE_END))
+    c->dest = buf;
+  c->dest_start = buf;
+  c->dest_end = buf + len;
+  if (conv_run(c) & CONV_SOURCE_END)
     return 0;
-  c->len <<= 1;
-  return 1;
+  return len << 1;
 }
 
index a8c6afd89d7c37ad60909e166adc6d52c2acea70..9f01000440f0e475add4de0fa8a2cb41d1f0c6f9 100644 (file)
@@ -2,6 +2,9 @@
  *     Sherlock Library -- Character Conversion with Allocation on the Stack 
  *
  *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
  */
 
 #ifndef _CHARSET_STK_CHARCONV_H
 /* The following macros convert strings between given charsets (CONV_CHARSET_x). */
 
 #define stk_conv(s, cs_in, cs_out) \
-    ({ struct stk_conv_context _c; stk_conv_init(&_c, (s), (cs_in), (cs_out)); \
-       while (stk_conv_step(&_c, alloca(_c.len))); _c.c.dest_start; })
+    ({ struct conv_context _c; uns _l=stk_conv_init(&_c, (s), (cs_in), (cs_out)); \
+       while (_l) _l=stk_conv_step(&_c, alloca(_l), _l); _c.dest_start; })
 
 #define stk_conv_to_utf8(s, cs_in) stk_conv(s, cs_in, CONV_CHARSET_UTF8)
 #define stk_conv_from_utf8(s, cs_out) stk_conv(s, CONV_CHARSET_UTF8, cs_out)
    
-/* Internal structure and routines. */
-
-struct stk_conv_context {
-  struct conv_context c;
-  uns len;
-};
+/* Internals */
 
-void stk_conv_init(struct stk_conv_context *c, byte *s, uns cs_in, uns cs_out);
-int stk_conv_step(struct stk_conv_context *c, byte *buf);
+uns stk_conv_init(struct conv_context *c, byte *s, uns cs_in, uns cs_out);
+uns stk_conv_step(struct conv_context *c, byte *buf, uns len);
 
 #endif