summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2009-04-23 16:03:19 +0200
committerJelmer Vernooij <jelmer@samba.org>2009-04-23 17:50:18 +0200
commit598f78bd1f3c59cfdca91a590bd95298b7d28d9e (patch)
treedcf557d1c5f0d93c6a20de162a038e6455e390dd
parent80420745ff2998626a302b5f863db8364e858f8f (diff)
downloadsamba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.tar.gz
samba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.tar.bz2
samba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.zip
charcnv: Import push_codepoint().
-rw-r--r--source3/lib/charcnv.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 374079c8ae..eb794d8347 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -1861,3 +1861,64 @@ codepoint_t next_codepoint(const char *str, size_t *size)
/* no other length is valid */
return INVALID_CODEPOINT;
}
+
+/*
+ push a single codepoint into a CH_UNIX string the target string must
+ be able to hold the full character, which is guaranteed if it is at
+ least 5 bytes in size. The caller may pass less than 5 bytes if they
+ are sure the character will fit (for example, you can assume that
+ uppercase/lowercase of a character will not add more than 1 byte)
+
+ return the number of bytes occupied by the CH_UNIX character, or
+ -1 on failure
+*/
+_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c)
+{
+ smb_iconv_t descriptor;
+ uint8_t buf[4];
+ size_t ilen, olen;
+ const char *inbuf;
+
+ if (c < 128) {
+ *str = c;
+ return 1;
+ }
+
+ lazy_initialize_conv();
+
+ descriptor = conv_handles[CH_UNIX][CH_UTF16LE];
+ if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
+ return -1;
+ }
+
+ if (c < 0x10000) {
+ ilen = 2;
+ olen = 5;
+ inbuf = (char *)buf;
+ SSVAL(buf, 0, c);
+ smb_iconv(descriptor, &inbuf, &ilen, &str, &olen);
+ if (ilen != 0) {
+ return -1;
+ }
+ return 5 - olen;
+ }
+
+ c -= 0x10000;
+
+ buf[0] = (c>>10) & 0xFF;
+ buf[1] = (c>>18) | 0xd8;
+ buf[2] = c & 0xFF;
+ buf[3] = ((c>>8) & 0x3) | 0xdc;
+
+ ilen = 4;
+ olen = 5;
+ inbuf = (char *)buf;
+
+ smb_iconv(descriptor, &inbuf, &ilen, &str, &olen);
+ if (ilen != 0) {
+ return -1;
+ }
+ return 5 - olen;
+}
+
+