]> mj.ucw.cz Git - libucw.git/commitdiff
UCW: Implemented bput_utf16_*.
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Mon, 10 Dec 2007 11:36:50 +0000 (12:36 +0100)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Mon, 10 Dec 2007 11:36:50 +0000 (12:36 +0100)
lib/ff-unicode.c
lib/ff-unicode.h
lib/unicode.h

index 047fff84cf16bb57d05748d38b2f9d8c6e6dfe6a..280b3b75d319111b51408c9c6d022899b14264b4 100644 (file)
@@ -14,6 +14,8 @@
 #include "lib/ff-unicode.h"
 #include "lib/ff-binary.h"
 
+/*** UTF-8 ***/
+
 int
 bget_utf8_slow(struct fastbuf *b, uns repl)
 {
@@ -167,6 +169,8 @@ bput_utf8_32_slow(struct fastbuf *b, uns u)
     }
 }
 
+/*** UTF-16 ***/
+
 int
 bget_utf16_be_slow(struct fastbuf *b, uns repl)
 {
@@ -196,3 +200,41 @@ bget_utf16_le_slow(struct fastbuf *b, uns repl)
     return repl;
   return 0x10000 + (x << 10) + y;
 }
+
+void
+bput_utf16_be_slow(struct fastbuf *b, uns u)
+{
+  if (u < 0xd800 || (u < 0x10000 && u >= 0xe000))
+    {
+      bputc(b, u >> 8);
+      bputc(b, u & 0xff);
+    }
+  else if ((u -= 0x10000) < 0x100000)
+    {
+      bputc(b, 0xd8 | (u >> 18));
+      bputc(b, (u >> 10) & 0xff);
+      bputc(b, 0xdc | ((u >> 8) & 0x3));
+      bputc(b, u & 0xff);
+    }
+  else
+    ASSERT(0);
+}
+
+void
+bput_utf16_le_slow(struct fastbuf *b, uns u)
+{
+  if (u < 0xd800 || (u < 0x10000 && u >= 0xe000))
+    {
+      bputc(b, u & 0xff);
+      bputc(b, u >> 8);
+    }
+  else if ((u -= 0x10000) < 0x100000)
+    {
+      bputc(b, (u >> 10) & 0xff);
+      bputc(b, 0xd8 | (u >> 18));
+      bputc(b, u & 0xff);
+      bputc(b, 0xdc | ((u >> 8) & 0x3));
+    }
+  else
+    ASSERT(0);
+}
index f577c6359685c42a685715f089a24f4d5f6e1fd6..93f8a06ec013bf83dee248eb6f6699f40df081c2 100644 (file)
 #include "lib/fastbuf.h"
 #include "lib/unicode.h"
 
+/*** UTF-8 ***/
+
 int bget_utf8_slow(struct fastbuf *b, uns repl);
 int bget_utf8_32_slow(struct fastbuf *b, uns repl);
 void bput_utf8_slow(struct fastbuf *b, uns u);
 void bput_utf8_32_slow(struct fastbuf *b, uns u);
-int bget_utf16_be_slow(struct fastbuf *b, uns repl);
-int bget_utf16_le_slow(struct fastbuf *b, uns repl);
 
 static inline int
 bget_utf8_repl(struct fastbuf *b, uns repl)
@@ -62,7 +62,6 @@ bget_utf8_32(struct fastbuf *b)
 static inline void
 bput_utf8(struct fastbuf *b, uns u)
 {
-  ASSERT(u < 65536);
   if (bavailw(b) >= 3)
     b->bptr = utf8_put(b->bptr, u);
   else
@@ -72,13 +71,19 @@ bput_utf8(struct fastbuf *b, uns u)
 static inline void
 bput_utf8_32(struct fastbuf *b, uns u)
 {
-  ASSERT(u < (1U<<31));
   if (bavailw(b) >= 6)
     b->bptr = utf8_32_put(b->bptr, u);
   else
     bput_utf8_32_slow(b, u);
 }
 
+/*** UTF-16 ***/
+
+int bget_utf16_be_slow(struct fastbuf *b, uns repl);
+int bget_utf16_le_slow(struct fastbuf *b, uns repl);
+void bput_utf16_be_slow(struct fastbuf *b, uns u);
+void bput_utf16_le_slow(struct fastbuf *b, uns u);
+
 static inline int
 bget_utf16_be_repl(struct fastbuf *b, uns repl)
 {
@@ -117,4 +122,22 @@ bget_utf16_le(struct fastbuf *b)
   return bget_utf16_le_repl(b, UNI_REPLACEMENT);
 }
 
+static inline void
+bput_utf16_be(struct fastbuf *b, uns u)
+{
+  if (bavailw(b) >= 4)
+    b->bptr = utf16_be_put(b->bptr, u);
+  else
+    bput_utf16_be_slow(b, u);
+}
+
+static inline void
+bput_utf16_lbe(struct fastbuf *b, uns u)
+{
+  if (bavailw(b) >= 4)
+    b->bptr = utf16_le_put(b->bptr, u);
+  else
+    bput_utf16_le_slow(b, u);
+}
+
 #endif
index fb8722d09737b72ff2d2ba1db1c4ed7ddf08698e..9a3fe07a27ea2bd7785b2f55c440145fd7d7b266 100644 (file)
@@ -239,8 +239,8 @@ utf16_le_put(void *p, uns u)
     }
   else if ((u -= 0x10000) < 0x100000)
     {
-      put_u16_le(p, u >> 10);
-      put_u16_le(p + 2, u & 0x7ff);
+      put_u16_le(p, 0xd800 | (u >> 10));
+      put_u16_le(p + 2, 0xdc00 | (u & 0x3ff));
       return p + 4;
     }
   else
@@ -257,8 +257,8 @@ utf16_be_put(void *p, uns u)
     }
   else if ((u -= 0x10000) < 0x100000)
     {
-      put_u16_be(p, u >> 10);
-      put_u16_be(p + 2, u & 0x7ff);
+      put_u16_be(p, 0xd800 | (u >> 10));
+      put_u16_be(p + 2, 0xdc00 | (u & 0x3ff));
       return p + 4;
     }
   else