Silly of me to overlook it: another obvious way you might like to
[sgt/charset] / sbcs.c
CommitLineData
c6d25d8d 1/*
2 * sbcs.c - routines to handle single-byte character sets.
3 */
4
5#include "charset.h"
6#include "internal.h"
7
8/*
9 * The charset_spec for any single-byte character set should
10 * provide read_sbcs() as its read function, and its `data' field
11 * should be a wchar_t string constant containing the 256 entries
12 * of the translation table.
13 */
14
01081d4e 15long int sbcs_to_unicode(const struct sbcs_data *sd, long int input_chr)
16{
17 return sd->sbcs2ucs[input_chr];
18}
19
c6d25d8d 20void read_sbcs(charset_spec const *charset, long int input_chr,
21 charset_state *state,
22 void (*emit)(void *ctx, long int output), void *emitctx)
23{
24 const struct sbcs_data *sd = charset->data;
25
26 UNUSEDARG(state);
27
01081d4e 28 emit(emitctx, sbcs_to_unicode(sd, input_chr));
c6d25d8d 29}
30
01081d4e 31long int sbcs_from_unicode(const struct sbcs_data *sd, long int input_chr)
c6d25d8d 32{
c6d25d8d 33 int i, j, k, c;
34
c6d25d8d 35 /*
36 * Binary-search in the ucs2sbcs table.
37 */
38 i = -1;
39 j = sd->nvalid;
40 while (i+1 < j) {
41 k = (i+j)/2;
42 c = sd->ucs2sbcs[k];
3cca0edf 43 if (input_chr < (long int)sd->sbcs2ucs[c])
c6d25d8d 44 j = k;
3cca0edf 45 else if (input_chr > (long int)sd->sbcs2ucs[c])
c6d25d8d 46 i = k;
47 else {
01081d4e 48 return c;
c6d25d8d 49 }
50 }
01081d4e 51 return ERROR;
52}
53
54int write_sbcs(charset_spec const *charset, long int input_chr,
55 charset_state *state,
56 void (*emit)(void *ctx, long int output), void *emitctx)
57{
58 const struct sbcs_data *sd = charset->data;
c601368c 59 long int ret;
01081d4e 60
61 UNUSEDARG(state);
62
63 if (input_chr == -1)
64 return TRUE; /* stateless; no cleanup required */
65
c601368c 66 ret = sbcs_from_unicode(sd, input_chr);
67 if (ret == ERROR)
68 return FALSE;
69
70 emit(emitctx, ret);
71 return TRUE;
c6d25d8d 72}