1 /* 2 * Copyright (c) 2003 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is contributed to Robin Hu <huxw@knight.6test.edu.cn> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * $DragonFly: src/lib/libc/locale/Attic/gb18030.c,v 1.1 2003/12/01 23:29:25 drhodus Exp $ 35 */ 36 37 #include <sys/cdefs.h> 38 39 #include <rune.h> 40 #include <stddef.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <sys/types.h> 44 45 rune_t _GB18030_sgetrune(const char *, size_t, char const **); 46 int _GB18030_sputrune(rune_t, char *, size_t, char **); 47 48 int 49 _GB18030_init(rl) 50 _RuneLocale *rl; 51 { 52 rl->sgetrune = _GB18030_sgetrune; 53 rl->sputrune = _GB18030_sputrune; 54 _CurrentRuneLocale = rl; 55 __mb_cur_max = 4; 56 return (0); 57 } 58 59 static inline int 60 _gb18030_check_string(s_, n) 61 const char* s_; 62 int n; 63 { 64 const unsigned char* s = s_; 65 if ((s[0]>=0x81&&s[0]<=0xfe)) { 66 if (n<2) goto bad_string; 67 if ((s[1]>=0x40&&s[1]<=0x7e)||(s[1]>=0x80&&s[1]<=0xfe)) 68 return 2; 69 if ((s[1]>=0x30&&s[1]<=0x39)) { 70 if (n<4) goto bad_string; 71 if ((s[2]>=0x81&&s[2]<=0xfe) && (s[3]>=0x30&&s[3]<=0x39)) 72 return 4; 73 else 74 goto bad_string; 75 } 76 } else { 77 return 1; 78 } 79 bad_string: 80 return -1; 81 } 82 83 static inline int 84 _gb18030_check_rune(r) 85 rune_t r; 86 { 87 if (r&0xff000000) { 88 return 4; 89 } 90 if (r&0xff00) { 91 return 2; 92 } 93 return 1; 94 } 95 96 rune_t 97 _GB18030_sgetrune(string, n, result) 98 const char *string; 99 size_t n; 100 char const **result; 101 { 102 rune_t rune = 0; 103 int len; 104 105 len = _gb18030_check_string(string, n); 106 107 if (len == -1) { 108 if (result) 109 *result = string; 110 return (_INVALID_RUNE); 111 } 112 113 while (--len >= 0) 114 rune = (rune << 8) | ((u_int)(*string++) & 0xff); 115 116 rune &= 0x7fffffff; 117 if (result) 118 *result = string; 119 return rune; 120 } 121 122 int 123 _GB18030_sputrune(c, string, n, result) 124 rune_t c; 125 char *string, **result; 126 size_t n; 127 { 128 int len; 129 len = _gb18030_check_rune(c); 130 131 switch (len) { 132 case 1: 133 if (n >= 1) { 134 *string = c & 0xff; 135 if (result) 136 *result = string + 1; 137 return (1); 138 } 139 break; 140 case 2: 141 if (n >= 2) { 142 string[0] = (c >> 8) & 0xff; 143 string[1] = c & 0xff; 144 if (result) 145 *result = string + 2; 146 return (2); 147 } 148 break; 149 case 4: 150 if (n >= 4) { 151 string[0] = ((c >>24) & 0xff) | 0x80; 152 string[1] = (c >>16) & 0xff; 153 string[2] = (c >>8) & 0xff; 154 string[3] = c & 0xff; 155 if (result) 156 *result = string + 4; 157 return (4); 158 } 159 break; 160 default: 161 break; 162 } 163 if (result) 164 *result = string; 165 return (0); 166 } 167 168