diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2009-04-23 16:03:19 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2009-04-23 17:50:18 +0200 |
commit | 598f78bd1f3c59cfdca91a590bd95298b7d28d9e (patch) | |
tree | dcf557d1c5f0d93c6a20de162a038e6455e390dd | |
parent | 80420745ff2998626a302b5f863db8364e858f8f (diff) | |
download | samba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.tar.gz samba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.tar.bz2 samba-598f78bd1f3c59cfdca91a590bd95298b7d28d9e.zip |
charcnv: Import push_codepoint().
-rw-r--r-- | source3/lib/charcnv.c | 61 |
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; +} + + |