No Description

code.go 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Copyright (C) 2017 Keelan Lightfoot
  2. // Copyright (C) 2007-2008 Board of Regents of the University of Wisconsin
  3. // System (Univ. of Wisconsin-Madison, Trace R&D Center)
  4. // Copyright (C) 2007-2008 Omnitor AB
  5. // Copyright (C) 2007-2008 Voiceriver Inc
  6. //
  7. // This library is free software; you can redistribute it and/or modify it
  8. // under the terms of the GNU Lesser General Public License as published by
  9. // the Free Software Foundation; either version 2.1 of the License, or (at
  10. // your option) any later version.
  11. package openbaudot
  12. import "unicode"
  13. const (
  14. shiftUnknown = iota
  15. shiftLetter
  16. shiftFigure
  17. shiftWhitespace
  18. )
  19. var (
  20. defaultSubstitutes = map[rune]rune{
  21. '{': '(',
  22. '}': ')',
  23. '[': '(',
  24. ']': ')',
  25. }
  26. // TDD Telecommunications Device for the Deaf standard
  27. TDD = CodeSet{
  28. Codes: [2][]rune{
  29. {'\b', 'E', '\n', 'A', ' ', 'S', 'I', 'U', '\r', 'D', 'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q', 'O', 'B', 'G', '\x0e', 'M', 'X', 'V', '\x0f'},
  30. {'\b', '3', '\n', '-', ' ', ',', '8', '7', '\r', '$', '4', '\'', ',', '!', ':', '(', '5', '"', ')', '2', '=', '6', '0', '1', '9', '?', '+', '\x0e', '.', '/', ';', '\x0f'},
  31. },
  32. Substitutes: defaultSubstitutes,
  33. Fallback: '\'',
  34. ShiftCode: 0x1b,
  35. UnshiftCode: 0x1f,
  36. }
  37. // USTTY US Teletype Corporation
  38. USTTY = CodeSet{
  39. Codes: [2][]rune{
  40. {'\x00', 'E', '\n', 'A', ' ', 'S', 'I', 'U', '\r', 'D', 'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q', 'O', 'B', 'G', '\x0e', 'M', 'X', 'V', '\x0f'},
  41. {'\x00', '3', '\n', '-', ' ', '\a', '8', '7', '\r', '$', '4', '\'', ',', '!', ':', '(', '5', '"', ')', '2', '#', '6', '0', '1', '9', '?', '&', '\x0e', '.', '/', ';', '\x0f'},
  42. },
  43. Substitutes: defaultSubstitutes,
  44. Fallback: '-',
  45. ShiftCode: 0x1b,
  46. UnshiftCode: 0x1f,
  47. }
  48. // USITA2 USITA2
  49. USITA2 = CodeSet{
  50. Codes: [2][]rune{
  51. {'\x00', 'E', '\n', 'A', ' ', 'S', 'I', 'U', '\r', 'D', 'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q', 'O', 'B', 'G', '\x0e', 'M', 'X', 'V', '\x0f'},
  52. {'\x00', '3', '\n', '-', ' ', '\'', '8', '7', '\r', '$', '4', '\a', ',', '!', ':', '(', '5', '"', ')', '2', '=', '6', '0', '1', '9', '?', '&', '\x0e', '.', '/', '=', '\x0f'},
  53. },
  54. Substitutes: defaultSubstitutes,
  55. Fallback: '-',
  56. ShiftCode: 0x1b,
  57. UnshiftCode: 0x1f,
  58. }
  59. // Weather US Weather
  60. Weather = CodeSet{
  61. Codes: [2][]rune{
  62. {'\x00', 'E', '\n', 'A', ' ', 'S', 'I', 'U', '\r', 'D', 'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q', 'O', 'B', 'G', '\x0e', 'M', 'X', 'V', '\x0f'},
  63. {'\x00', '3', '\n', '↑', ' ', '\a', '8', '7', '\r', '↗', '4', '↙', '⦷', '→', '○', '←', '5', '+', '↖', '2', '↓', '6', '0', '1', '9', '⊕', '↘', '\x0e', '.', '/', '⦶', '\x0f'},
  64. },
  65. Substitutes: defaultSubstitutes,
  66. Fallback: '-',
  67. ShiftCode: 0x1b,
  68. UnshiftCode: 0x1f,
  69. }
  70. // Fractions US Fractions
  71. Fractions = CodeSet{
  72. Codes: [2][]rune{
  73. {'\x00', 'E', '\n', 'A', ' ', 'S', 'I', 'U', '\r', 'D', 'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q', 'O', 'B', 'G', '\x0e', 'M', 'X', 'V', '\x0f'},
  74. {'\x00', '3', '\n', '↑', ' ', '\a', '8', '7', '\r', '$', '4', '\'', '⅞', '¼', '⅛', '½', '5', '"', '¾', '2', ' ', '6', '0', '1', '9', '⅝', '&', '\x0e', '.', '/', '⅜', '\x0f'},
  75. },
  76. Substitutes: defaultSubstitutes,
  77. Fallback: '-',
  78. ShiftCode: 0x1b,
  79. UnshiftCode: 0x1f,
  80. }
  81. )
  82. // CodeSet represents a teletype character set.
  83. type CodeSet struct {
  84. // Codes specifies a mapping of runes to codes. There are two tables, 0 for ltrs, 1 for figs
  85. Codes [2][]rune
  86. // Substitutes specifies what characters to re-map to existing table entries
  87. Substitutes map[rune]rune
  88. // Fallback specifies what rune to use when a table entry or substitution cant be found
  89. Fallback rune
  90. // ShiftRune is fun
  91. ShiftCode byte
  92. // UnshiftRune is fun
  93. UnshiftCode byte
  94. runeToCodeSet map[rune]code
  95. initialized bool
  96. }
  97. type code struct {
  98. shift int
  99. v byte
  100. }
  101. //LoadCharset is fun
  102. func LoadCharset(cs *CodeSet) *CodeSet {
  103. if !cs.initialized {
  104. cs.initialize()
  105. }
  106. return cs
  107. }
  108. func (cs *CodeSet) initialize() *CodeSet {
  109. cs.runeToCodeSet = make(map[rune]code)
  110. for i, runes := range cs.Codes {
  111. var shift int
  112. switch i {
  113. case 0:
  114. shift = shiftLetter
  115. case 1:
  116. shift = shiftFigure
  117. }
  118. for v, r := range runes {
  119. if c, exists := cs.runeToCodeSet[r]; exists {
  120. c.shift = shiftWhitespace
  121. cs.runeToCodeSet[r] = c
  122. } else {
  123. cs.runeToCodeSet[r] = code{
  124. shift: shift,
  125. v: byte(v),
  126. }
  127. }
  128. }
  129. }
  130. for in, out := range cs.Substitutes {
  131. if _, ok := cs.runeToCodeSet[in]; ok {
  132. // dont load a translation if it overlaps an existing table entry
  133. continue
  134. }
  135. if b, ok := cs.runeToCodeSet[out]; ok {
  136. // only set the translation if the output exists in table
  137. cs.runeToCodeSet[in] = b
  138. }
  139. }
  140. return cs
  141. }
  142. func (cs *CodeSet) toCode(r rune) code {
  143. if c, ok := cs.runeToCodeSet[unicode.ToUpper(r)]; ok {
  144. return c
  145. }
  146. return cs.runeToCodeSet[cs.Fallback]
  147. }
  148. func (cs *CodeSet) toByte(r rune) byte {
  149. if c, ok := cs.runeToCodeSet[unicode.ToUpper(r)]; ok {
  150. return c.v
  151. }
  152. return cs.runeToCodeSet[cs.Fallback].v
  153. }
  154. func (c code) toByte() byte {
  155. return c.v
  156. }
  157. func (cs *CodeSet) shift() byte {
  158. return cs.ShiftCode
  159. }
  160. func (cs *CodeSet) unshift() byte {
  161. return cs.UnshiftCode
  162. }
  163. func (cs *CodeSet) toRune(shift int, b byte) rune {
  164. var i int
  165. switch shift {
  166. case shiftLetter:
  167. i = 0
  168. case shiftFigure:
  169. i = 1
  170. }
  171. if int(b) < len(cs.Codes[i]) {
  172. return cs.Codes[i][int(b)]
  173. }
  174. return '�'
  175. }