Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / libmlrpc / common / ndr_wchar.c
blob81886f3250fd23fd6ff77aa2d544530b82e80776
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
30 * Some wchar support functions used by this library.
31 * Mostlly just wrappers that call sys/u8_textprep.h
32 * functions: uconv_u8tou16, uconv_u16tou8.
35 #include <sys/types.h>
36 #include <sys/u8_textprep.h>
37 #include <string.h>
39 #include "ndr_wchar.h"
42 * When we just want lengths, we need an output buffer to pass to the
43 * uconv_... functions. Nothing ever reads this output, so we can
44 * use shared space for the unwanted output.
46 static uint16_t junk_wcs[NDR_STRING_MAX];
47 static char junk_mbs[NDR_MB_CUR_MAX * NDR_STRING_MAX];
49 static size_t
50 ndr__mbstowcs_x(uint16_t *, const char *, size_t, int);
53 * Like mbstowcs(3C), but with UCS-2 wchar_t
55 size_t
56 ndr__mbstowcs(uint16_t *wcs, const char *mbs, size_t nwchars)
58 return (ndr__mbstowcs_x(wcs, mbs, nwchars,
59 UCONV_OUT_SYSTEM_ENDIAN));
63 * Like above, but put UCS-2 little-endian.
65 size_t
66 ndr__mbstowcs_le(uint16_t *wcs, const char *mbs, size_t nwchars)
68 return (ndr__mbstowcs_x(wcs, mbs, nwchars,
69 UCONV_OUT_LITTLE_ENDIAN));
73 * Like mbstowcs(3C), but with UCS-2 wchar_t, and
74 * one extra arg for the byte order flags.
76 static size_t
77 ndr__mbstowcs_x(uint16_t *wcs, const char *mbs, size_t nwchars, int flags)
79 size_t obytes, mbslen, wcslen;
80 int err;
82 /* NULL or empty input is allowed. */
83 if (mbs == NULL || *mbs == '\0') {
84 if (wcs != NULL && nwchars > 0)
85 *wcs = 0;
86 return (0);
90 * If wcs == NULL, caller just wants the length.
91 * Convert into some throw-away space.
93 obytes = nwchars * 2;
94 if (wcs == NULL) {
95 if (obytes > sizeof (junk_wcs))
96 return ((size_t)-1);
97 wcs = junk_wcs;
100 mbslen = strlen(mbs);
101 wcslen = nwchars;
102 err = uconv_u8tou16((const uchar_t *)mbs, &mbslen,
103 wcs, &wcslen, flags);
104 if (err != 0)
105 return ((size_t)-1);
107 if (wcslen < nwchars)
108 wcs[wcslen] = 0;
110 return (wcslen);
114 * Like wcstombs(3C), but with UCS-2 wchar_t.
116 size_t
117 ndr__wcstombs(char *mbs, const uint16_t *wcs, size_t nbytes)
119 size_t mbslen, wcslen;
120 int err;
122 /* NULL or empty input is allowed. */
123 if (wcs == NULL || *wcs == 0) {
124 if (mbs != NULL && nbytes > 0)
125 *mbs = '\0';
126 return (0);
130 * If mbs == NULL, caller just wants the length.
131 * Convert into some throw-away space.
133 if (mbs == NULL) {
134 if (nbytes > sizeof (junk_mbs))
135 return ((size_t)-1);
136 mbs = junk_mbs;
139 wcslen = ndr__wcslen(wcs);
140 mbslen = nbytes;
141 err = uconv_u16tou8(wcs, &wcslen,
142 (uchar_t *)mbs, &mbslen, UCONV_IN_SYSTEM_ENDIAN);
143 if (err != 0)
144 return ((size_t)-1);
146 if (mbslen < nbytes)
147 mbs[mbslen] = '\0';
149 return (mbslen);
153 * Like wcslen(3C), but with UCS-2 wchar_t.
155 size_t
156 ndr__wcslen(const uint16_t *wc)
158 size_t len = 0;
159 while (*wc++)
160 len++;
161 return (len);