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.

135 lines
2.4 KiB

10 years ago
  1. package mahonia
  2. import (
  3. "unicode/utf8"
  4. )
  5. // ConvertString converts a string from UTF-8 to e's encoding.
  6. func (e Encoder) ConvertString(s string) string {
  7. dest := make([]byte, len(s)+10)
  8. destPos := 0
  9. for _, rune := range s {
  10. retry:
  11. size, status := e(dest[destPos:], rune)
  12. if status == NO_ROOM {
  13. newDest := make([]byte, len(dest)*2)
  14. copy(newDest, dest)
  15. dest = newDest
  16. goto retry
  17. }
  18. if status == STATE_ONLY {
  19. destPos += size
  20. goto retry
  21. }
  22. destPos += size
  23. }
  24. return string(dest[:destPos])
  25. }
  26. // ConvertString converts a string from d's encoding to UTF-8.
  27. func (d Decoder) ConvertString(s string) string {
  28. bytes := []byte(s)
  29. runes := make([]rune, len(s))
  30. destPos := 0
  31. for len(bytes) > 0 {
  32. c, size, status := d(bytes)
  33. if status == STATE_ONLY {
  34. bytes = bytes[size:]
  35. continue
  36. }
  37. if status == NO_ROOM {
  38. c = 0xfffd
  39. size = len(bytes)
  40. status = INVALID_CHAR
  41. }
  42. bytes = bytes[size:]
  43. runes[destPos] = c
  44. destPos++
  45. }
  46. return string(runes[:destPos])
  47. }
  48. // ConvertStringOK converts a string from UTF-8 to e's encoding. It also
  49. // returns a boolean indicating whether every character was converted
  50. // successfully.
  51. func (e Encoder) ConvertStringOK(s string) (result string, ok bool) {
  52. dest := make([]byte, len(s)+10)
  53. destPos := 0
  54. ok = true
  55. for i, r := range s {
  56. // The following test is copied from utf8.ValidString.
  57. if r == utf8.RuneError && ok {
  58. _, size := utf8.DecodeRuneInString(s[i:])
  59. if size == 1 {
  60. ok = false
  61. }
  62. }
  63. retry:
  64. size, status := e(dest[destPos:], r)
  65. switch status {
  66. case NO_ROOM:
  67. newDest := make([]byte, len(dest)*2)
  68. copy(newDest, dest)
  69. dest = newDest
  70. goto retry
  71. case STATE_ONLY:
  72. destPos += size
  73. goto retry
  74. case INVALID_CHAR:
  75. ok = false
  76. }
  77. destPos += size
  78. }
  79. return string(dest[:destPos]), ok
  80. }
  81. // ConvertStringOK converts a string from d's encoding to UTF-8.
  82. // It also returns a boolean indicating whether every character was converted
  83. // successfully.
  84. func (d Decoder) ConvertStringOK(s string) (result string, ok bool) {
  85. bytes := []byte(s)
  86. runes := make([]rune, len(s))
  87. destPos := 0
  88. ok = true
  89. for len(bytes) > 0 {
  90. c, size, status := d(bytes)
  91. switch status {
  92. case STATE_ONLY:
  93. bytes = bytes[size:]
  94. continue
  95. case NO_ROOM:
  96. c = 0xfffd
  97. size = len(bytes)
  98. ok = false
  99. case INVALID_CHAR:
  100. ok = false
  101. }
  102. bytes = bytes[size:]
  103. runes[destPos] = c
  104. destPos++
  105. }
  106. return string(runes[:destPos]), ok
  107. }