1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1990 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #if !defined(lint) && defined(SCCSIDS) 30 static char *sccsid = "%Z%%M% %I% %E% SMI"; 31 #endif 32 33 #include <stdio.h> 34 #include <sys/types.h> 35 36 #define CS377 0377 37 #define MASK 0x0000ffff 38 #define TOP1 0x80000000 39 #define TOP2 0x08000000 40 41 42 /* 43 * mbtowc routines for the Xerox XCCS codeset standard 44 */ 45 int 46 _mbtowc_xccs(pwc, s, n) 47 wchar_t *pwc; 48 char *s; 49 int n; 50 { 51 static unsigned int CSselect = 0; 52 static int CSlength = 1; 53 wchar_t twchar = 0; 54 55 /* 56 * If length is negative, return error 57 */ 58 if (n <= 0) 59 return (-1); 60 61 /* 62 * End of string ? 63 */ 64 if (*s == 0 && CSlength == 1) 65 return (0); 66 if (*s == 0 && *(s + 1) == 0 && CSlength == 2) 67 return (0); 68 69 /* 70 * Get a character 71 */ 72 if ((unsigned char)*s == CS377) { 73 /* 74 * Switching code set 75 */ 76 ++s; 77 /* 78 * Change characteristics 79 */ 80 if ((unsigned char)*s == CS377) { 81 ++s; 82 /* 83 * two byte sequence 84 */ 85 if (*s++ != 0) 86 return (-1); 87 CSselect = 0; 88 CSlength = 2; 89 90 } 91 else { 92 /* 93 * Change CSselect 94 */ 95 CSselect = (unsigned int)*s++; 96 CSlength = 1; 97 } 98 } 99 100 /* 101 * Get a character and return 102 */ 103 if (CSlength == 1) { 104 twchar = CSselect; 105 } 106 else { 107 twchar = *s++; 108 } 109 twchar = twchar << 8; 110 twchar = twchar | *s; 111 if (pwc) 112 *pwc = twchar & MASK; 113 /* 114 * Encode additional information 115 */ 116 if (CSlength == 2) 117 if (pwc) 118 *pwc |= TOP1; 119 return (CSlength); 120 } 121 122 /* 123 * wctomb routines 124 */ 125 int 126 _wctomb_xccs(s, pwc) 127 char *s; 128 wchar_t pwc; 129 { 130 unsigned char upper, lower; 131 char *old = s; 132 #ifdef DEBUG 133 printf ("XCCS- xctomb\n"); 134 #endif 135 136 if (!s) 137 return (0); 138 139 /* 140 * Get lower and upper anyway 141 */ 142 lower = pwc & 0x00ff; 143 upper = (pwc >> 8) & 0x00ff; 144 if (lower == CS377 || upper == CS377) 145 return (-1); 146 if (pwc & TOP1) { /* length == 2 */ 147 /* 148 * This was the marker. 149 * Emitt 3 additional characters. 150 */ 151 *s++ = CS377; 152 *s++ = CS377; 153 *s++ = 0; 154 *s++ = upper; 155 *s++ = lower; 156 } 157 else { 158 /* 159 * This was the marker. 160 * Emitt 2 additional characters. 161 */ 162 *s++ = CS377; 163 *s++ = upper; 164 *s++ = lower; 165 } 166 return (s - old); 167 } 168 169 170 /* 171 * mbstowcs routines 172 */ 173 size_t 174 _mbstowcs_xccs(pwc, s, n) 175 wchar_t *pwc; 176 char *s; 177 int n; 178 { 179 static unsigned int CSselect = 0; 180 static int CSlength = 1; 181 wchar_t twchar = 0; 182 int cnt = 0; 183 184 /* 185 * If length is negative, return error 186 */ 187 if (n <= 0) 188 return (-1); 189 190 /* 191 * End of string ? 192 */ 193 if (*s == 0 && CSlength == 1) 194 return (0); 195 if (*s == 0 && *(s + 1) == 0 && CSlength == 2) 196 return (0); 197 198 do { 199 /* 200 * Check for an end of the string 201 */ 202 if (((*s == 0 && CSlength == 1)) || 203 ((*s == 0 && *(s + 1) == 0 && CSlength == 2))) { 204 *pwc = 0; 205 ++cnt; 206 --n; 207 break; 208 } 209 /* 210 * Get a character 211 */ 212 if ((unsigned char)*s == CS377) { 213 ++s; 214 /* 215 * Change characterristics 216 */ 217 if ((unsigned char)*s == CS377) { 218 ++s; 219 /* 220 * two byte sequence 221 */ 222 if (*s++ != 0) 223 return (-1); 224 CSselect = 0; 225 CSlength = 2; 226 227 } 228 else { 229 /* 230 * Change CSselect 231 */ 232 CSselect = (unsigned int)*s++; 233 CSlength = 1; 234 } 235 } 236 237 /* 238 * Get a character and return 239 */ 240 if (CSlength == 1) { 241 twchar = CSselect; 242 } 243 else { 244 twchar = *s++; 245 } 246 twchar = twchar << 8; 247 twchar = twchar | *s++; 248 *pwc = twchar & MASK; 249 if (CSlength == 2) 250 *pwc |= TOP1; 251 ++pwc; 252 ++cnt; 253 --n; 254 } while (n >= 0); 255 return (cnt); 256 } 257 258 259 /* 260 * wcstombs routines 261 */ 262 size_t 263 _wcstombs_xccs(s, pwc, n) 264 char *s; 265 wchar_t *pwc; 266 int n; 267 { 268 int cnt = 0; 269 unsigned char lower, upper; 270 int in_2byte = 0; 271 int in_1byte = 0; 272 int current = 0; 273 274 if (n <= 0) 275 return (-1); 276 277 if (*pwc == 0) 278 return (0); 279 280 do { 281 lower = *pwc & 0x00ff; 282 upper = (*pwc >> 8) & 0x00ff; 283 /* 284 * End of string ? 285 */ 286 if (lower == 0) { 287 *s++ = 0; 288 ++cnt; 289 --n; 290 if (n == 0) 291 break; 292 *s++ = 0; 293 ++cnt; 294 break; 295 } 296 if (lower == CS377 || upper == CS377) 297 return (-1); 298 if (*pwc & TOP1) { /* length == 2 */ 299 if (in_2byte == 0) { 300 /* 301 * This was the marker. 302 * Emitt 3 additional characters. 303 */ 304 *s++ = CS377; ++cnt; --n; 305 *s++ = CS377; ++cnt; --n; 306 *s++ = 0; ++cnt; --n; 307 in_2byte = 1; 308 in_1byte = 0; 309 } 310 *s++ = upper; ++cnt; --n; 311 if (n == 0) 312 break; 313 *s++ = lower; ++cnt; --n; 314 if (n == 0) 315 break; 316 } 317 else { 318 if ((in_1byte == 0 && in_2byte == 1) || 319 (in_1byte == 1 && upper != current) || 320 (in_1byte == 0 && in_2byte == 0 && upper != 0)) { 321 /* 322 * This was the marker. 323 * Emitt 2 additional characters. 324 */ 325 *s++ = CS377; ++cnt; --n; 326 if (n == 0) 327 break; 328 *s++ = upper; ++cnt; --n; 329 if (n == 0) 330 break; 331 in_2byte = 0; 332 in_1byte = 1; 333 current = upper; 334 } 335 *s++ = lower; ++cnt; --n; 336 if (n == 0) 337 break; 338 } 339 ++pwc; 340 } while (n >= 0); 341 return (cnt); 342 } 343