diff options
| author | Charles.Forsyth <devnull@localhost> | 2007-01-31 21:35:05 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2007-01-31 21:35:05 +0000 |
| commit | 313166a4d9889f8e2a542d19b2b9051eea4ee35b (patch) | |
| tree | 45b143402f8fc29327ba0327b46e432baac2185b /appl/lib/convcs | |
| parent | ef16591df27afae3267b1ea5bfab68429be51dc6 (diff) | |
add utf16_btos/stob to convcs(2)
Diffstat (limited to 'appl/lib/convcs')
| -rw-r--r-- | appl/lib/convcs/utf16_btos.b | 66 | ||||
| -rw-r--r-- | appl/lib/convcs/utf16_stob.b | 47 |
2 files changed, 113 insertions, 0 deletions
diff --git a/appl/lib/convcs/utf16_btos.b b/appl/lib/convcs/utf16_btos.b new file mode 100644 index 00000000..c08e04eb --- /dev/null +++ b/appl/lib/convcs/utf16_btos.b @@ -0,0 +1,66 @@ +implement Btos; + +include "sys.m"; +include "convcs.m"; + +Littleendian, Bigendian: con iota; + +sys : Sys; +default := Bigendian; + +init(arg : string) : string +{ + sys = load Sys Sys->PATH; + case arg { + "le" => + default = Littleendian; + "be" => + default = Bigendian; + } + return nil; +} + + +btos(state : Convcs->State, b : array of byte, n : int) : (Convcs->State, string, int) +{ + endian: int; + i := 0; + if(state != nil) + endian = state[0]; + else if (len b >= 2) { + state = " "; + # XXX should probably not do this if we've been told the endianness + case (int b[0] << 8) | int b[1] { + 16rfeff => + endian = Bigendian; + i += 2; + 16rfffe => + endian = Littleendian; + i += 2; + * => + endian = guessendian(b); + } + state[0] = endian; + } + nb := len b & ~1; + if(n > 0 && nb - i > n * 2) + nb = i + n * 2; + out := ""; + if(endian == Bigendian){ + for(; i < nb; i += 2) + out[len out] = (int b[i] << 8) | int b[i + 1]; + }else{ + for(; i < nb; i += 2) + out[len out] = int b[i] | int b[i + 1] << 8; + } + if(n == 0 && i < len b) + out[len out] = Sys->UTFerror; + + return (state, out, i); +} + +guessendian(nil: array of byte): int +{ + # XXX might be able to do better than this in the absence of endian hints. + return default; +} diff --git a/appl/lib/convcs/utf16_stob.b b/appl/lib/convcs/utf16_stob.b new file mode 100644 index 00000000..312add88 --- /dev/null +++ b/appl/lib/convcs/utf16_stob.b @@ -0,0 +1,47 @@ +implement Stob; + +include "sys.m"; + sys: Sys; +include "convcs.m"; + +bigendian := 1; +header := 1; + +init(arg : string) : string +{ + sys = load Sys Sys->PATH; + case arg { + "le" => + bigendian = 0; + header = 0; + "be" => + header = 0; + } + return nil; +} + +stob(state : Convcs->State, s : string) : (Convcs->State, array of byte) +{ + if(state == nil){ + if(header) + s = sys->sprint("%c", 16rfeff) + s; + state = "doneheader"; + } + + b := array[len s * 2] of byte; + j := 0; + if(bigendian){ + for(i := 0; i < len s; i++){ + c := s[i]; + b[j++] = byte (c >> 8); + b[j++] = byte c; + } + }else{ + for(i := 0; i < len s; i++){ + c := s[i]; + b[j++] = byte c; + b[j++] = byte (c >> 8); + } + } + return (state, b); +} |
