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