code.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package source
  2. import (
  3. "io"
  4. "strings"
  5. "unicode"
  6. "unicode/utf8"
  7. "unicode/utf16"
  8. )
  9. type Code ([] uint16)
  10. func CodeReader(code Code, pos int) io.RuneReader {
  11. return &codeReader { src: code, pos: pos }
  12. }
  13. type codeReader struct {
  14. src Code
  15. pos int
  16. }
  17. func (r *codeReader) ReadRune() (rune, int, error) {
  18. if r.pos >= len(r.src) {
  19. return -1, 0, io.EOF
  20. }
  21. var a = r.src[r.pos]
  22. if utf16.IsSurrogate(rune(a)) {
  23. if (r.pos + 1) < len(r.src) {
  24. var b = r.src[r.pos + 1]
  25. var next = utf16.DecodeRune(rune(a), rune(b))
  26. r.pos += 2
  27. return next, 2, nil
  28. } else {
  29. var next = unicode.ReplacementChar
  30. r.pos += 1
  31. return next, 1, nil
  32. }
  33. } else {
  34. var next = rune(a)
  35. r.pos += 1
  36. return next, 1, nil
  37. }
  38. }
  39. type codeBuilder struct {
  40. current Code
  41. }
  42. func (buf *codeBuilder) Append(char rune) {
  43. var code = &(buf.current)
  44. if 0 <= char && char < unicode.MaxRune {
  45. if char < 0x10000 {
  46. *code = append(*code, uint16(char))
  47. } else {
  48. var a, b = utf16.EncodeRune(char)
  49. *code = append(*code, uint16(a), uint16(b))
  50. }
  51. } else {
  52. *code = append(*code, unicode.ReplacementChar)
  53. }
  54. }
  55. func (buf *codeBuilder) Collect() Code {
  56. return buf.current
  57. }
  58. func CodeToChars(code Code) ([] rune) {
  59. return utf16.Decode(code)
  60. }
  61. func CodeToString(code Code) string {
  62. var buf strings.Builder
  63. var reader = codeReader { src: code, pos: 0 }
  64. for { if char, _, err := reader.ReadRune(); err != io.EOF {
  65. buf.WriteRune(char)
  66. } else {
  67. break
  68. }}
  69. return buf.String()
  70. }
  71. func StringToCode(s string) Code {
  72. var buf codeBuilder
  73. for _, char := range s {
  74. buf.Append(char)
  75. }
  76. return buf.Collect()
  77. }
  78. func DecodeUtf8ToCode(b ([] byte)) Code {
  79. var buf codeBuilder
  80. for len(b) > 0 {
  81. var char, size = utf8.DecodeRune(b)
  82. buf.Append(char)
  83. b = b[size:]
  84. }
  85. return buf.Collect()
  86. }
  87. const placeholder = "<?>"
  88. func Placeholder() Code {
  89. var snippet = make(Code, len(placeholder))
  90. for i := range placeholder {
  91. snippet[i] = uint16(rune(placeholder[i]))
  92. }
  93. return snippet
  94. }
  95. func IsPlaceholder(snippet Code) bool {
  96. if len(snippet) == len(placeholder) {
  97. for i := range placeholder {
  98. if rune(snippet[i]) != rune(placeholder[i]) {
  99. return false
  100. }
  101. }
  102. return true
  103. } else {
  104. return false
  105. }
  106. }