160475Sbostic /*-
2*61137Sbostic * Copyright (c) 1993
3*61137Sbostic * The Regents of the University of California. All rights reserved.
460475Sbostic *
560475Sbostic * This code is derived from software contributed to Berkeley by
660475Sbostic * Paul Borman at Krystal Technologies.
760475Sbostic *
860475Sbostic * %sccs.include.redist.c%
960475Sbostic */
1060475Sbostic
1160475Sbostic #if defined(LIBC_SCCS) && !defined(lint)
12*61137Sbostic static char sccsid[] = "@(#)utf2.c 8.1 (Berkeley) 06/04/93";
1360475Sbostic #endif /* LIBC_SCCS and not lint */
1460475Sbostic
1560475Sbostic #include <errno.h>
1660475Sbostic #include <rune.h>
1760475Sbostic #include <stddef.h>
1860475Sbostic #include <stdio.h>
1960475Sbostic #include <stdlib.h>
2060475Sbostic
2160475Sbostic rune_t _UTF2_sgetrune __P((const char *, size_t, char const **));
2260475Sbostic int _UTF2_sputrune __P((rune_t, char *, size_t, char **));
2360475Sbostic
2460475Sbostic static _utf_count[16] = {
2560475Sbostic 1, 1, 1, 1, 1, 1, 1, 1,
2660475Sbostic 0, 0, 0, 0, 2, 2, 3, 0,
2760475Sbostic };
2860475Sbostic
2960475Sbostic int
_UTF2_init(rl)3060475Sbostic _UTF2_init(rl)
3160475Sbostic _RuneLocale *rl;
3260475Sbostic {
3360475Sbostic rl->sgetrune = _UTF2_sgetrune;
3460475Sbostic rl->sputrune = _UTF2_sputrune;
3560475Sbostic _CurrentRuneLocale = rl;
3660475Sbostic __mb_cur_max = 3;
3760475Sbostic return (0);
3860475Sbostic }
3960475Sbostic
4060475Sbostic rune_t
_UTF2_sgetrune(string,n,result)4160475Sbostic _UTF2_sgetrune(string, n, result)
4260475Sbostic const char *string;
4360475Sbostic size_t n;
4460475Sbostic char const **result;
4560475Sbostic {
4660475Sbostic int c;
4760475Sbostic
4860475Sbostic if (n < 1 || (c = _utf_count[(*string >> 4) & 0xf]) > n) {
4960475Sbostic if (result)
5060475Sbostic *result = string;
5160475Sbostic return (_INVALID_RUNE);
5260475Sbostic }
5360475Sbostic switch (c) {
5460475Sbostic case 1:
5560475Sbostic if (result)
5660475Sbostic *result = string + 1;
5760475Sbostic return (*string & 0xff);
5860475Sbostic case 2:
5960475Sbostic if ((string[1] & 0xC0) != 0x80)
6060475Sbostic goto encoding_error;
6160475Sbostic if (result)
6260475Sbostic *result = string + 2;
6360475Sbostic return (((string[0] & 0x1F) << 6) | (string[1] & 0x3F));
6460475Sbostic case 3:
6560475Sbostic if ((string[1] & 0xC0) != 0x80 || (string[2] & 0xC0) != 0x80)
6660475Sbostic goto encoding_error;
6760475Sbostic if (result)
6860475Sbostic *result = string + 3;
6960475Sbostic return (((string[0] & 0x1F) << 12) | ((string[1] & 0x3F) << 6)
7060475Sbostic | (string[2] & 0x3F));
7160475Sbostic default:
7260475Sbostic encoding_error: if (result)
7360475Sbostic *result = string + 1;
7460475Sbostic return (_INVALID_RUNE);
7560475Sbostic }
7660475Sbostic }
7760475Sbostic
7860475Sbostic int
_UTF2_sputrune(c,string,n,result)7960475Sbostic _UTF2_sputrune(c, string, n, result)
8060475Sbostic rune_t c;
8160475Sbostic char *string, **result;
8260475Sbostic size_t n;
8360475Sbostic {
8460475Sbostic if (c & 0xF800) {
8560475Sbostic if (n >= 3) {
8660475Sbostic if (string) {
8760475Sbostic string[0] = 0xE0 | ((c >> 12) & 0x0F);
8860475Sbostic string[1] = 0x80 | ((c >> 6) & 0x3F);
8960475Sbostic string[2] = 0x80 | ((c) & 0x3F);
9060475Sbostic }
9160475Sbostic if (result)
9260475Sbostic *result = string + 3;
9360475Sbostic } else
9460475Sbostic if (result)
9560475Sbostic *result = NULL;
9660475Sbostic
9760475Sbostic return (3);
9860475Sbostic } else
9960475Sbostic if (c & 0x0780) {
10060475Sbostic if (n >= 2) {
10160475Sbostic if (string) {
10260475Sbostic string[0] = 0xC0 | ((c >> 6) & 0x1F);
10360475Sbostic string[1] = 0x80 | ((c) & 0x3F);
10460475Sbostic }
10560475Sbostic if (result)
10660475Sbostic *result = string + 2;
10760475Sbostic } else
10860475Sbostic if (result)
10960475Sbostic *result = NULL;
11060475Sbostic return (2);
11160475Sbostic } else {
11260475Sbostic if (n >= 1) {
11360475Sbostic if (string)
11460475Sbostic string[0] = c;
11560475Sbostic if (result)
11660475Sbostic *result = string + 1;
11760475Sbostic } else
11860475Sbostic if (result)
11960475Sbostic *result = NULL;
12060475Sbostic return (1);
12160475Sbostic }
12260475Sbostic }
123