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.

88 lines
1.4 KiB

10 years ago
  1. package mahonia
  2. // Converters for the Shift-JIS encoding.
  3. import (
  4. "unicode/utf8"
  5. )
  6. func init() {
  7. RegisterCharset(&Charset{
  8. Name: "Shift_JIS",
  9. Aliases: []string{"MS_Kanji", "csShiftJIS", "SJIS", "ibm-943", "windows-31j", "cp932", "windows-932"},
  10. NewDecoder: func() Decoder {
  11. return decodeSJIS
  12. },
  13. NewEncoder: func() Encoder {
  14. shiftJISOnce.Do(reverseShiftJISTable)
  15. return encodeSJIS
  16. },
  17. })
  18. }
  19. func decodeSJIS(p []byte) (c rune, size int, status Status) {
  20. if len(p) == 0 {
  21. return 0, 0, NO_ROOM
  22. }
  23. b := p[0]
  24. if b < 0x80 {
  25. return rune(b), 1, SUCCESS
  26. }
  27. if 0xa1 <= b && b <= 0xdf {
  28. return rune(b) + (0xff61 - 0xa1), 1, SUCCESS
  29. }
  30. if b == 0x80 || b == 0xa0 {
  31. return utf8.RuneError, 1, INVALID_CHAR
  32. }
  33. if len(p) < 2 {
  34. return 0, 0, NO_ROOM
  35. }
  36. jis := int(b)<<8 + int(p[1])
  37. c = rune(shiftJISToUnicode[jis])
  38. if c == 0 {
  39. return utf8.RuneError, 2, INVALID_CHAR
  40. }
  41. return c, 2, SUCCESS
  42. }
  43. func encodeSJIS(p []byte, c rune) (size int, status Status) {
  44. if len(p) == 0 {
  45. return 0, NO_ROOM
  46. }
  47. if c < 0x80 {
  48. p[0] = byte(c)
  49. return 1, SUCCESS
  50. }
  51. if 0xff61 <= c && c <= 0xff9f {
  52. // half-width katakana
  53. p[0] = byte(c - (0xff61 - 0xa1))
  54. return 1, SUCCESS
  55. }
  56. if len(p) < 2 {
  57. return 0, NO_ROOM
  58. }
  59. if c > 0xffff {
  60. p[0] = '?'
  61. return 1, INVALID_CHAR
  62. }
  63. jis := unicodeToShiftJIS[c]
  64. if jis == 0 {
  65. p[0] = '?'
  66. return 1, INVALID_CHAR
  67. }
  68. p[0] = byte(jis >> 8)
  69. p[1] = byte(jis)
  70. return 2, SUCCESS
  71. }