Utf8.mod 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. IMPLEMENTATION MODULE Utf8;
  2. PROCEDURE Decode (s : ARRAY OF CHAR; lo : CARDINAL;
  3. VAR cp : UCHAR; VAR next : CARDINAL) : BOOLEAN;
  4. VAR b0, b1, b2, b3, v : INTEGER;
  5. i : CARDINAL;
  6. PROCEDURE Cont (VAR b : INTEGER) : BOOLEAN;
  7. (* consume a continuation byte (0x80..0xBF), or fail *)
  8. BEGIN
  9. IF i > HIGH(s) THEN RETURN FALSE END;
  10. b := ORD(s[i]); INC(i);
  11. RETURN (b >= 128) AND (b <= 191)
  12. END Cont;
  13. BEGIN
  14. cp := UCHR(0);
  15. next := lo;
  16. IF lo > HIGH(s) THEN RETURN FALSE END;
  17. b0 := ORD(s[lo]); i := lo + 1; v := -1;
  18. IF b0 <= 127 THEN
  19. v := b0
  20. ELSIF (b0 >= 194) AND (b0 <= 223) THEN
  21. IF Cont(b1) THEN v := ((b0 - 192) * 64) + (b1 - 128) END
  22. ELSIF (b0 >= 224) AND (b0 <= 239) THEN
  23. IF Cont(b1) AND Cont(b2) THEN
  24. v := ((b0 - 224) * 4096) + ((b1 - 128) * 64) + (b2 - 128);
  25. IF v < 2048 THEN v := -1 END
  26. END
  27. ELSIF (b0 >= 240) AND (b0 <= 244) THEN
  28. IF Cont(b1) AND Cont(b2) AND Cont(b3) THEN
  29. v := ((b0 - 240) * 262144) + ((b1 - 128) * 4096)
  30. + ((b2 - 128) * 64) + (b3 - 128);
  31. IF v < 65536 THEN v := -1 END
  32. END
  33. ELSE
  34. v := -1
  35. END;
  36. IF v < 0 THEN RETURN FALSE END;
  37. IF (v >= 55296) AND (v <= 57343) THEN RETURN FALSE END;
  38. IF v > 1114111 THEN RETURN FALSE END;
  39. cp := UCHR(v);
  40. next := i;
  41. RETURN TRUE
  42. END Decode;
  43. PROCEDURE Encode (cp : UCHAR; VAR buf : ARRAY OF CHAR) : CARDINAL;
  44. VAR v : INTEGER;
  45. n : CARDINAL;
  46. BEGIN
  47. v := UORD(cp);
  48. IF (v >= 0) AND (v <= 127) THEN
  49. buf[0] := CHR(v); n := 1
  50. ELSIF (v >= 128) AND (v <= 2047) THEN
  51. buf[0] := CHR(192 + (v DIV 64));
  52. buf[1] := CHR(128 + (v MOD 64));
  53. n := 2
  54. ELSIF (v >= 2048) AND (v <= 65535) THEN
  55. buf[0] := CHR(224 + (v DIV 4096));
  56. buf[1] := CHR(128 + ((v DIV 64) MOD 64));
  57. buf[2] := CHR(128 + (v MOD 64));
  58. n := 3
  59. ELSIF (v >= 65536) AND (v <= 1114111) THEN
  60. buf[0] := CHR(240 + (v DIV 262144));
  61. buf[1] := CHR(128 + ((v DIV 4096) MOD 64));
  62. buf[2] := CHR(128 + ((v DIV 64) MOD 64));
  63. buf[3] := CHR(128 + (v MOD 64));
  64. n := 4
  65. ELSE
  66. n := 0
  67. END;
  68. RETURN n
  69. END Encode;
  70. END Utf8.