You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.3 KiB

10 years ago
  1. package mahonia
  2. // Converters for Big 5 encoding.
  3. import (
  4. "sync"
  5. )
  6. func init() {
  7. RegisterCharset(&Charset{
  8. Name: "Big5",
  9. Aliases: []string{"csBig5"},
  10. NewDecoder: func() Decoder {
  11. return decodeBig5Rune
  12. },
  13. NewEncoder: func() Encoder {
  14. big5Once.Do(reverseBig5Table)
  15. return encodeBig5Rune
  16. },
  17. })
  18. }
  19. func decodeBig5Rune(p []byte) (r rune, size int, status Status) {
  20. if len(p) == 0 {
  21. status = NO_ROOM
  22. return
  23. }
  24. b := p[0]
  25. if b < 128 {
  26. return rune(b), 1, SUCCESS
  27. }
  28. if len(p) < 2 {
  29. status = NO_ROOM
  30. return
  31. }
  32. c := int(p[0])<<8 + int(p[1])
  33. c = int(big5ToUnicode[c])
  34. if c > 0 {
  35. return rune(c), 2, SUCCESS
  36. }
  37. return 0xfffd, 1, INVALID_CHAR
  38. }
  39. func encodeBig5Rune(p []byte, r rune) (size int, status Status) {
  40. if len(p) == 0 {
  41. status = NO_ROOM
  42. return
  43. }
  44. if r < 128 {
  45. p[0] = byte(r)
  46. return 1, SUCCESS
  47. }
  48. if len(p) < 2 {
  49. status = NO_ROOM
  50. return
  51. }
  52. if r < 0x10000 {
  53. c := unicodeToBig5[r]
  54. if c > 0 {
  55. p[0] = byte(c >> 8)
  56. p[1] = byte(c)
  57. return 2, SUCCESS
  58. }
  59. }
  60. p[0] = '?'
  61. return 1, INVALID_CHAR
  62. }
  63. var big5Once sync.Once
  64. var unicodeToBig5 []uint16
  65. func reverseBig5Table() {
  66. unicodeToBig5 = make([]uint16, 65536)
  67. for big5, unicode := range big5ToUnicode {
  68. if unicode > 0 {
  69. unicodeToBig5[unicode] = uint16(big5)
  70. }
  71. }
  72. }