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
_UTF2_init(rl)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
_UTF2_sgetrune(string,n,result)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
_UTF2_sputrune(c,string,n,result)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