Nav apraksta

code.go 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package openbaudot
  2. import "unicode"
  3. /*
  4. * OBL openbaudot Library
  5. *
  6. * Copyright (C) 2017 Keelan Lightfoot
  7. * Copyright (C) 2007-2008 Board of Regents of the University of Wisconsin
  8. * System (Univ. of Wisconsin-Madison, Trace R&D Center)
  9. * Copyright (C) 2007-2008 Omnitor AB
  10. * Copyright (C) 2007-2008 Voiceriver Inc
  11. *
  12. * This software was developed with support from the National Institute on
  13. * Disability and Rehabilitation Research, US Dept of Education under Grant
  14. * # H133E990006 and H133E040014
  15. *
  16. * This library is free software; you can redistribute it and/or modify it
  17. * under the terms of the GNU Lesser General Public License as published by
  18. * the Free Software Foundation; either version 2.1 of the License, or (at
  19. * your option) any later version.
  20. *
  21. * This library is distributed in the hope that it will be useful, but
  22. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  23. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  24. * License for more details.
  25. *
  26. * You should have received a copy of the GNU Lesser General Public License
  27. * along with this library; if not, write to the Free Software Foundation,
  28. * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  29. *
  30. * Please send a copy of any improved versions of the library to:
  31. * Jeff Knighton, Voiceriver Inc, jeff.knighton@voiceriver.com
  32. * Gunnar Hellstrom, Omnitor AB, Box 92054, 12006 Stockholm, SWEDEN
  33. * Gregg Vanderheiden, Trace Center, U of Wisconsin, Madison, Wi 53706
  34. *
  35. * file...: obl.go
  36. * original author.: Keelan Lightfoot
  37. * Created: 20 May 2017
  38. *
  39. */
  40. const (
  41. shiftUnknown = iota
  42. shiftLetter
  43. shiftFigure
  44. shiftWhitespace
  45. )
  46. var (
  47. defaultSubstitutes = map[rune]rune{
  48. '{': '(',
  49. '}': ')',
  50. '[': '(',
  51. ']': ')',
  52. }
  53. // TDD Telecommunications Device for the Deaf standard
  54. TDD = CodeSet{
  55. Codes: [2][]rune{
  56. {'\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'},
  57. {'\b', '3', '\n', '-', ' ', ',', '8', '7', '\r', '$', '4', '\'', ',', '!', ':', '(', '5', '"', ')', '2', '=', '6', '0', '1', '9', '?', '+', '\x0e', '.', '/', ';', '\x0f'},
  58. },
  59. Substitutes: defaultSubstitutes,
  60. Fallback: '\'',
  61. ShiftCode: 0x1b,
  62. UnshiftCode: 0x1f,
  63. }
  64. // USTTY US Teletype Corporation
  65. USTTY = CodeSet{
  66. Codes: [2][]rune{
  67. {'\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'},
  68. {'\x00', '3', '\n', '-', ' ', '\a', '8', '7', '\r', '$', '4', '\'', ',', '!', ':', '(', '5', '"', ')', '2', '#', '6', '0', '1', '9', '?', '&', '\x0e', '.', '/', ';', '\x0f'},
  69. },
  70. Substitutes: defaultSubstitutes,
  71. Fallback: '-',
  72. ShiftCode: 0x1b,
  73. UnshiftCode: 0x1f,
  74. }
  75. // USITA2 USITA2
  76. USITA2 = CodeSet{
  77. Codes: [2][]rune{
  78. {'\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'},
  79. {'\x00', '3', '\n', '-', ' ', '\'', '8', '7', '\r', '$', '4', '\a', ',', '!', ':', '(', '5', '"', ')', '2', '=', '6', '0', '1', '9', '?', '&', '\x0e', '.', '/', '=', '\x0f'},
  80. },
  81. Substitutes: defaultSubstitutes,
  82. Fallback: '-',
  83. ShiftCode: 0x1b,
  84. UnshiftCode: 0x1f,
  85. }
  86. // Weather US Weather
  87. Weather = CodeSet{
  88. Codes: [2][]rune{
  89. {'\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'},
  90. {'\x00', '3', '\n', '↑', ' ', '\a', '8', '7', '\r', '↗', '4', '↙', '⦷', '→', '○', '←', '5', '+', '↖', '2', '↓', '6', '0', '1', '9', '⊕', '↘', '\x0e', '.', '/', '⦶', '\x0f'},
  91. },
  92. Substitutes: defaultSubstitutes,
  93. Fallback: '-',
  94. ShiftCode: 0x1b,
  95. UnshiftCode: 0x1f,
  96. }
  97. // Fractions US Fractions
  98. Fractions = CodeSet{
  99. Codes: [2][]rune{
  100. {'\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'},
  101. {'\x00', '3', '\n', '↑', ' ', '\a', '8', '7', '\r', '$', '4', '\'', '⅞', '¼', '⅛', '½', '5', '"', '¾', '2', ' ', '6', '0', '1', '9', '⅝', '&', '\x0e', '.', '/', '⅜', '\x0f'},
  102. },
  103. Substitutes: defaultSubstitutes,
  104. Fallback: '-',
  105. ShiftCode: 0x1b,
  106. UnshiftCode: 0x1f,
  107. }
  108. )
  109. // CodeSet represents a teletype character set.
  110. type CodeSet struct {
  111. // Codes specifies a mapping of runes to codes. There are two tables, 0 for ltrs, 1 for figs
  112. Codes [2][]rune
  113. // Substitutes specifies what characters to re-map to existing table entries
  114. Substitutes map[rune]rune
  115. // Fallback specifies what rune to use when a table entry or substitution cant be found
  116. Fallback rune
  117. // ShiftRune is fun
  118. ShiftCode byte
  119. // UnshiftRune is fun
  120. UnshiftCode byte
  121. runeToCodeSet map[rune]code
  122. }
  123. type code struct {
  124. shift int
  125. v byte
  126. }
  127. //Initialize is fun
  128. func (cs *CodeSet) Initialize() *CodeSet {
  129. cs.runeToCodeSet = make(map[rune]code)
  130. for i, runes := range cs.Codes {
  131. var shift int
  132. switch i {
  133. case 0:
  134. shift = shiftLetter
  135. case 1:
  136. shift = shiftFigure
  137. }
  138. for v, r := range runes {
  139. if c, exists := cs.runeToCodeSet[r]; exists {
  140. c.shift = shiftWhitespace
  141. cs.runeToCodeSet[r] = c
  142. } else {
  143. cs.runeToCodeSet[r] = code{
  144. shift: shift,
  145. v: byte(v),
  146. }
  147. }
  148. }
  149. }
  150. for in, out := range cs.Substitutes {
  151. if _, ok := cs.runeToCodeSet[in]; ok {
  152. // dont load a translation if it overlaps an existing table entry
  153. continue
  154. }
  155. if b, ok := cs.runeToCodeSet[out]; ok {
  156. // only set the translation if the output exists in table
  157. cs.runeToCodeSet[in] = b
  158. }
  159. }
  160. return cs
  161. }
  162. func (cs *CodeSet) toCode(r rune) code {
  163. if c, ok := cs.runeToCodeSet[unicode.ToUpper(r)]; ok {
  164. return c
  165. }
  166. return cs.runeToCodeSet[cs.Fallback]
  167. }
  168. func (cs *CodeSet) toByte(r rune) byte {
  169. if c, ok := cs.runeToCodeSet[unicode.ToUpper(r)]; ok {
  170. return c.v
  171. }
  172. return cs.runeToCodeSet[cs.Fallback].v
  173. }
  174. func (c code) toByte() byte {
  175. return c.v
  176. }
  177. func (cs *CodeSet) shift() byte {
  178. return cs.ShiftCode
  179. }
  180. func (cs *CodeSet) unshift() byte {
  181. return cs.UnshiftCode
  182. }
  183. func (cs *CodeSet) toRune(shift int, b byte) rune {
  184. var i int
  185. switch shift {
  186. case shiftLetter:
  187. i = 0
  188. case shiftFigure:
  189. i = 1
  190. }
  191. if int(b) < len(cs.Codes[i]) {
  192. return cs.Codes[i][int(b)]
  193. }
  194. return '�'
  195. }