1 /*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Paul Borman at Krystal Technologies. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)utf2.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <errno.h> 16 #include <rune.h> 17 #include <stddef.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 21 rune_t _UTF2_sgetrune __P((const char *, size_t, char const **)); 22 int _UTF2_sputrune __P((rune_t, char *, size_t, char **)); 23 24 static _utf_count[16] = { 25 1, 1, 1, 1, 1, 1, 1, 1, 26 0, 0, 0, 0, 2, 2, 3, 0, 27 }; 28 29 int 30 _UTF2_init(rl) 31 _RuneLocale *rl; 32 { 33 rl->sgetrune = _UTF2_sgetrune; 34 rl->sputrune = _UTF2_sputrune; 35 _CurrentRuneLocale = rl; 36 __mb_cur_max = 3; 37 return (0); 38 } 39 40 rune_t 41 _UTF2_sgetrune(string, n, result) 42 const char *string; 43 size_t n; 44 char const **result; 45 { 46 int c; 47 48 if (n < 1 || (c = _utf_count[(*string >> 4) & 0xf]) > n) { 49 if (result) 50 *result = string; 51 return (_INVALID_RUNE); 52 } 53 switch (c) { 54 case 1: 55 if (result) 56 *result = string + 1; 57 return (*string & 0xff); 58 case 2: 59 if ((string[1] & 0xC0) != 0x80) 60 goto encoding_error; 61 if (result) 62 *result = string + 2; 63 return (((string[0] & 0x1F) << 6) | (string[1] & 0x3F)); 64 case 3: 65 if ((string[1] & 0xC0) != 0x80 || (string[2] & 0xC0) != 0x80) 66 goto encoding_error; 67 if (result) 68 *result = string + 3; 69 return (((string[0] & 0x1F) << 12) | ((string[1] & 0x3F) << 6) 70 | (string[2] & 0x3F)); 71 default: 72 encoding_error: if (result) 73 *result = string + 1; 74 return (_INVALID_RUNE); 75 } 76 } 77 78 int 79 _UTF2_sputrune(c, string, n, result) 80 rune_t c; 81 char *string, **result; 82 size_t n; 83 { 84 if (c & 0xF800) { 85 if (n >= 3) { 86 if (string) { 87 string[0] = 0xE0 | ((c >> 12) & 0x0F); 88 string[1] = 0x80 | ((c >> 6) & 0x3F); 89 string[2] = 0x80 | ((c) & 0x3F); 90 } 91 if (result) 92 *result = string + 3; 93 } else 94 if (result) 95 *result = NULL; 96 97 return (3); 98 } else 99 if (c & 0x0780) { 100 if (n >= 2) { 101 if (string) { 102 string[0] = 0xC0 | ((c >> 6) & 0x1F); 103 string[1] = 0x80 | ((c) & 0x3F); 104 } 105 if (result) 106 *result = string + 2; 107 } else 108 if (result) 109 *result = NULL; 110 return (2); 111 } else { 112 if (n >= 1) { 113 if (string) 114 string[0] = c; 115 if (result) 116 *result = string + 1; 117 } else 118 if (result) 119 *result = NULL; 120 return (1); 121 } 122 } 123