summaryrefslogtreecommitdiff
path: root/appl/lib/convcs/gb2312_btos.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/lib/convcs/gb2312_btos.b')
-rw-r--r--appl/lib/convcs/gb2312_btos.b70
1 files changed, 70 insertions, 0 deletions
diff --git a/appl/lib/convcs/gb2312_btos.b b/appl/lib/convcs/gb2312_btos.b
new file mode 100644
index 00000000..8a06a75f
--- /dev/null
+++ b/appl/lib/convcs/gb2312_btos.b
@@ -0,0 +1,70 @@
+implement Btos;
+
+include "sys.m";
+include "convcs.m";
+
+GBMAX : con 8795;
+
+GBDATA : con "/lib/convcs/gb2312";
+
+MAXINT : con 16r7fffffff;
+BADCHAR : con 16rFFFD;
+
+gbmap := "";
+
+init(nil : string): string
+{
+ sys := load Sys Sys->PATH;
+ fd := sys->open(GBDATA, Sys->OREAD);
+ if (fd == nil)
+ return sys->sprint("%s: %r", GBDATA);
+
+ buf := array[GBMAX * Sys->UTFmax] of byte;
+ nread := 0;
+ for (;nread < len buf;) {
+ n := sys->read(fd, buf[nread:], Sys->ATOMICIO);
+ if (n <= 0)
+ break;
+ nread += n;
+ }
+ gbmap = string buf[:nread];
+ if (len gbmap != GBMAX) {
+ gbmap = nil;
+ return sys->sprint("%s: corrupt data", GBDATA);
+ }
+ return nil;
+}
+
+btos(nil : Convcs->State, b : array of byte, n : int) : (Convcs->State, string, int)
+{
+ nbytes := 0;
+ str := "";
+
+ if (n == -1)
+ n = MAXINT;
+
+ font := -1;
+ for (i := 0; i < len b && len str < n; i++) {
+ c := int b[i];
+ ch := Sys->UTFerror;
+ if (font == -1) {
+ # idle state
+ if (c >= 16rA1) {
+ font = c;
+ continue;
+ }
+ ch = c;
+ } else {
+ # seen a font spec
+ if (c >= 16rA1) {
+ ix := (font - 16rA0)*100 + (c-16rA0);
+ ch = gbmap[ix];
+ }
+ font = -1;
+ }
+ str[len str] = ch;
+ nbytes = i + 1;
+ }
+ return (nil, str, nbytes);
+}
+