ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/convcs/utf16_btos.b/
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;
}