]> mj.ucw.cz Git - libucw.git/commitdiff
Well, a simple variant of stk_conv.
authorPavel Charvat <pchar@camellia.ms.mff.cuni.cz>
Mon, 6 Mar 2006 12:06:20 +0000 (13:06 +0100)
committerPavel Charvat <pchar@camellia.ms.mff.cuni.cz>
Mon, 6 Mar 2006 12:06:20 +0000 (13:06 +0100)
I leave the complex one for experiments... ;)

charset/stk-charconv.c
charset/stk-charconv.h

index 2d5c206636feea3fa7e34bb6afe80f99db53eff0..10af721180478165c5947ae189f62fa3748eb034 100644 (file)
@@ -15,83 +15,46 @@ void
 stk_conv_init(struct stk_conv_context *c, byte *s, uns in_cs, uns out_cs)
 {
   uns l = strlen(s);
-  c->count = 0;
-
-  /* For in_cs == out_cs, we emulate stk_strdup */
   if (in_cs == out_cs)
   {
-    c->size[0] = c->request = l + 1;
-    c->buf[0] = s;
-    c->c.source = NULL;
+    c->c.source = s;
+    c->c.source_end = NULL;
+    c->len = l + 1;
     return;
   }
-  /* Initialization */
   conv_init(&c->c);
   conv_set_charset(&c->c, in_cs, out_cs);
   c->c.source = s;
   c->c.source_end = s + l + 1;
-  c->sum = 0;
-
-  /* Size of the first buffer */
   if (l < (INITIAL_MIN_SIZE - 1) / INITIAL_SCALE)
-    c->request = INITIAL_MIN_SIZE;
+    c->len = INITIAL_MIN_SIZE;
   else
-    c->request = l * INITIAL_SCALE + 1;
+    c->len = l * INITIAL_SCALE + 1;
+  c->len = 1;
 }
 
 int
 stk_conv_step(struct stk_conv_context *c, byte *buf)
 {
-  /* Merge all buffers to the new one and exit */
-  if (!c->c.source)
+  if (!c->c.source_end)
   {
+    memcpy(buf, c->c.source, c->len);
     c->c.dest_start = buf;
-    for (uns i = 0; i <= c->count; i++)
-    {
-      memcpy(buf, c->buf[i], c->size[i]);
-      buf += c->size[i];
-    }  
     return 0;
   }
-  
-  /* Run conv_run using the new buffer */
-  c->buf[c->count] = c->c.dest_start = c->c.dest = buf;
-  c->c.dest_end = buf + c->request;
-  if (!(conv_run(&c->c) & CONV_SOURCE_END))
+  if (c->c.dest_start)
   {
-
-    /* Buffer is too small, continue with a new one */
-    c->size[c->count++] = c->request;
-    c->sum += c->request;
-    c->request <<= 1; /* This can be freely changed */
-    return 1;
+    uns l = c->c.dest_end - c->c.dest_start;
+    memcpy(buf, c->c.dest_start, l);
+    c->c.dest = buf + l;
   }
-
-  /* We have used only one buffer for the conversion, no merges are needed */
-  if (!c->count)
-    return 0;
-  
-  /* We can merge everything to the current buffer ... */
-  uns s = c->c.dest - c->c.dest_start;
-  if (c->sum + s <= c->request)
-  {
-    memmove(buf + c->sum, buf, s);
-    for (uns i = 0; i < c->count; i++)
-    {
-      memcpy(buf, c->buf[i], c->size[i]);
-      buf += c->size[i];
-    }
-    return 0;
-  }
-  
-  /* ... or we allocate a new one */
   else
-  {
-    c->request = c->sum + s;
-    c->size[c->count] = s;
-    c->c.source = NULL;
-    return 1;
-  }
+    c->c.dest = buf;
+  c->c.dest_start = buf;
+  c->c.dest_end = buf + c->len;
+  if ((conv_run(&c->c) & CONV_SOURCE_END))
+    return 0;
+  c->len <<= 1;
+  return 1;
 }
 
index d8ae585c4fefa91d9e570ed77090bad63f002792..a8c6afd89d7c37ad60909e166adc6d52c2acea70 100644 (file)
@@ -14,7 +14,7 @@
 
 #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.request))); _c.c.dest_start; })
+       while (stk_conv_step(&_c, alloca(_c.len))); _c.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)
 
 struct stk_conv_context {
   struct conv_context c;
-  uns count;
-  uns sum;
-  uns request;
-  byte *buf[16]; 
-  uns size[16];
+  uns len;
 };
 
 void stk_conv_init(struct stk_conv_context *c, byte *s, uns cs_in, uns cs_out);