summaryrefslogtreecommitdiff
path: root/app/tools/halibut/charset/sbcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/tools/halibut/charset/sbcs.c')
-rw-r--r--app/tools/halibut/charset/sbcs.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/app/tools/halibut/charset/sbcs.c b/app/tools/halibut/charset/sbcs.c
new file mode 100644
index 0000000..e8be5a8
--- /dev/null
+++ b/app/tools/halibut/charset/sbcs.c
@@ -0,0 +1,72 @@
+/*
+ * sbcs.c - routines to handle single-byte character sets.
+ */
+
+#include "charset.h"
+#include "internal.h"
+
+/*
+ * The charset_spec for any single-byte character set should
+ * provide read_sbcs() as its read function, and its `data' field
+ * should be a wchar_t string constant containing the 256 entries
+ * of the translation table.
+ */
+
+long int sbcs_to_unicode(const struct sbcs_data *sd, long int input_chr)
+{
+ return sd->sbcs2ucs[input_chr];
+}
+
+void read_sbcs(charset_spec const *charset, long int input_chr,
+ charset_state *state,
+ void (*emit)(void *ctx, long int output), void *emitctx)
+{
+ const struct sbcs_data *sd = charset->data;
+
+ UNUSEDARG(state);
+
+ emit(emitctx, sbcs_to_unicode(sd, input_chr));
+}
+
+long int sbcs_from_unicode(const struct sbcs_data *sd, long int input_chr)
+{
+ int i, j, k, c;
+
+ /*
+ * Binary-search in the ucs2sbcs table.
+ */
+ i = -1;
+ j = sd->nvalid;
+ while (i+1 < j) {
+ k = (i+j)/2;
+ c = sd->ucs2sbcs[k];
+ if (input_chr < (long int)sd->sbcs2ucs[c])
+ j = k;
+ else if (input_chr > (long int)sd->sbcs2ucs[c])
+ i = k;
+ else {
+ return c;
+ }
+ }
+ return ERROR;
+}
+
+int write_sbcs(charset_spec const *charset, long int input_chr,
+ charset_state *state,
+ void (*emit)(void *ctx, long int output), void *emitctx)
+{
+ const struct sbcs_data *sd = charset->data;
+ long int ret;
+
+ UNUSEDARG(state);
+
+ if (input_chr == -1)
+ return TRUE; /* stateless; no cleanup required */
+
+ ret = sbcs_from_unicode(sd, input_chr);
+ if (ret == ERROR)
+ return FALSE;
+
+ emit(emitctx, ret);
+ return TRUE;
+}