decoder.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package binary
  2. import (
  3. "fmt"
  4. "io"
  5. "strings"
  6. "git.bobomao.top/joey/testwh/binary/token"
  7. "git.bobomao.top/joey/testwh/types"
  8. )
  9. type binaryDecoder struct {
  10. data []byte
  11. index int
  12. }
  13. func newDecoder(data []byte) *binaryDecoder {
  14. return &binaryDecoder{data, 0}
  15. }
  16. func (r *binaryDecoder) checkEOS(length int) error {
  17. if r.index+length > len(r.data) {
  18. return io.EOF
  19. }
  20. return nil
  21. }
  22. func (r *binaryDecoder) readByte() (byte, error) {
  23. if err := r.checkEOS(1); err != nil {
  24. return 0, err
  25. }
  26. b := r.data[r.index]
  27. r.index++
  28. return b, nil
  29. }
  30. func (r *binaryDecoder) readIntN(n int, littleEndian bool) (int, error) {
  31. if err := r.checkEOS(n); err != nil {
  32. return 0, err
  33. }
  34. var ret int
  35. for i := 0; i < n; i++ {
  36. var curShift int
  37. if littleEndian {
  38. curShift = i
  39. } else {
  40. curShift = n - i - 1
  41. }
  42. ret |= int(r.data[r.index+i]) << uint(curShift*8)
  43. }
  44. r.index += n
  45. return ret, nil
  46. }
  47. func (r *binaryDecoder) readInt8(littleEndian bool) (int, error) {
  48. return r.readIntN(1, littleEndian)
  49. }
  50. func (r *binaryDecoder) readInt16(littleEndian bool) (int, error) {
  51. return r.readIntN(2, littleEndian)
  52. }
  53. func (r *binaryDecoder) readInt20() (int, error) {
  54. if err := r.checkEOS(3); err != nil {
  55. return 0, err
  56. }
  57. ret := ((int(r.data[r.index]) & 15) << 16) + (int(r.data[r.index+1]) << 8) + int(r.data[r.index+2])
  58. r.index += 3
  59. return ret, nil
  60. }
  61. func (r *binaryDecoder) readInt32(littleEndian bool) (int, error) {
  62. return r.readIntN(4, littleEndian)
  63. }
  64. func (r *binaryDecoder) readPacked8(tag int) (string, error) {
  65. startByte, err := r.readByte()
  66. if err != nil {
  67. return "", err
  68. }
  69. var build strings.Builder
  70. for i := 0; i < int(startByte&127); i++ {
  71. currByte, err := r.readByte()
  72. if err != nil {
  73. return "", err
  74. }
  75. lower, err := unpackByte(tag, currByte&0xF0>>4)
  76. if err != nil {
  77. return "", err
  78. }
  79. upper, err := unpackByte(tag, currByte&0x0F)
  80. if err != nil {
  81. return "", err
  82. }
  83. build.WriteByte(lower)
  84. build.WriteByte(upper)
  85. }
  86. ret := build.String()
  87. if startByte>>7 != 0 {
  88. ret = ret[:len(ret)-1]
  89. }
  90. return ret, nil
  91. }
  92. func unpackByte(tag int, value byte) (byte, error) {
  93. switch tag {
  94. case token.Nibble8:
  95. return unpackNibble(value)
  96. case token.Hex8:
  97. return unpackHex(value)
  98. default:
  99. return 0, fmt.Errorf("unpackByte with unknown tag %d", tag)
  100. }
  101. }
  102. func unpackNibble(value byte) (byte, error) {
  103. switch {
  104. case value < 10:
  105. return '0' + value, nil
  106. case value == 10:
  107. return '-', nil
  108. case value == 11:
  109. return '.', nil
  110. case value == 15:
  111. return 0, nil
  112. default:
  113. return 0, fmt.Errorf("unpackNibble with value %d", value)
  114. }
  115. }
  116. func unpackHex(value byte) (byte, error) {
  117. switch {
  118. case value < 10:
  119. return '0' + value, nil
  120. case value < 16:
  121. return 'A' + value - 10, nil
  122. default:
  123. return 0, fmt.Errorf("unpackHex with value %d", value)
  124. }
  125. }
  126. func (r *binaryDecoder) readListSize(tag int) (int, error) {
  127. switch tag {
  128. case token.ListEmpty:
  129. return 0, nil
  130. case token.List8:
  131. return r.readInt8(false)
  132. case token.List16:
  133. return r.readInt16(false)
  134. default:
  135. return 0, fmt.Errorf("readListSize with unknown tag %d at position %d", tag, r.index)
  136. }
  137. }
  138. func (r *binaryDecoder) read(string bool) (interface{}, error) {
  139. tagByte, err := r.readByte()
  140. if err != nil {
  141. return nil, err
  142. }
  143. tag := int(tagByte)
  144. switch tag {
  145. case token.ListEmpty:
  146. return nil, nil
  147. case token.List8, token.List16:
  148. return r.readList(tag)
  149. case token.Binary8:
  150. size, err := r.readInt8(false)
  151. if err != nil {
  152. return nil, err
  153. }
  154. return r.readBytesOrString(size, string)
  155. case token.Binary20:
  156. size, err := r.readInt20()
  157. if err != nil {
  158. return nil, err
  159. }
  160. return r.readBytesOrString(size, string)
  161. case token.Binary32:
  162. size, err := r.readInt32(false)
  163. if err != nil {
  164. return nil, err
  165. }
  166. return r.readBytesOrString(size, string)
  167. case token.Dictionary0, token.Dictionary1, token.Dictionary2, token.Dictionary3:
  168. i, err := r.readInt8(false)
  169. if err != nil {
  170. return "", err
  171. }
  172. return token.GetDoubleToken(tag-token.Dictionary0, i)
  173. case token.FBJID:
  174. return r.readFBJID()
  175. case token.InteropJID:
  176. return r.readInteropJID()
  177. case token.JIDPair:
  178. return r.readJIDPair()
  179. case token.ADJID:
  180. return r.readADJID()
  181. case token.Nibble8, token.Hex8:
  182. return r.readPacked8(tag)
  183. default:
  184. if tag >= 1 && tag < len(token.SingleByteTokens) {
  185. return token.SingleByteTokens[tag], nil
  186. }
  187. return "", fmt.Errorf("%w %d at position %d", ErrInvalidToken, tag, r.index)
  188. }
  189. }
  190. func (r *binaryDecoder) readJIDPair() (interface{}, error) {
  191. user, err := r.read(true)
  192. if err != nil {
  193. return nil, err
  194. }
  195. server, err := r.read(true)
  196. if err != nil {
  197. return nil, err
  198. } else if server == nil {
  199. return nil, ErrInvalidJIDType
  200. } else if user == nil {
  201. return types.NewJID("", server.(string)), nil
  202. }
  203. return types.NewJID(user.(string), server.(string)), nil
  204. }
  205. func (r *binaryDecoder) readInteropJID() (interface{}, error) {
  206. user, err := r.read(true)
  207. if err != nil {
  208. return nil, err
  209. }
  210. device, err := r.readInt16(false)
  211. if err != nil {
  212. return nil, err
  213. }
  214. integrator, err := r.readInt16(false)
  215. if err != nil {
  216. return nil, err
  217. }
  218. server, err := r.read(true)
  219. if err != nil {
  220. return nil, err
  221. } else if server != types.InteropServer {
  222. return nil, fmt.Errorf("%w: expected %q, got %q", ErrInvalidJIDType, types.InteropServer, server)
  223. }
  224. return types.JID{
  225. User: user.(string),
  226. Device: uint16(device),
  227. Integrator: uint16(integrator),
  228. Server: types.InteropServer,
  229. }, nil
  230. }
  231. func (r *binaryDecoder) readFBJID() (interface{}, error) {
  232. user, err := r.read(true)
  233. if err != nil {
  234. return nil, err
  235. }
  236. device, err := r.readInt16(false)
  237. if err != nil {
  238. return nil, err
  239. }
  240. server, err := r.read(true)
  241. if err != nil {
  242. return nil, err
  243. } else if server != types.MessengerServer {
  244. return nil, fmt.Errorf("%w: expected %q, got %q", ErrInvalidJIDType, types.MessengerServer, server)
  245. }
  246. return types.JID{
  247. User: user.(string),
  248. Device: uint16(device),
  249. Server: server.(string),
  250. }, nil
  251. }
  252. func (r *binaryDecoder) readADJID() (interface{}, error) {
  253. agent, err := r.readByte()
  254. if err != nil {
  255. return nil, err
  256. }
  257. device, err := r.readByte()
  258. if err != nil {
  259. return nil, err
  260. }
  261. user, err := r.read(true)
  262. if err != nil {
  263. return nil, err
  264. }
  265. return types.NewADJID(user.(string), agent, device), nil
  266. }
  267. func (r *binaryDecoder) readAttributes(n int) (Attrs, error) {
  268. if n == 0 {
  269. return nil, nil
  270. }
  271. ret := make(Attrs)
  272. for i := 0; i < n; i++ {
  273. keyIfc, err := r.read(true)
  274. if err != nil {
  275. return nil, err
  276. }
  277. key, ok := keyIfc.(string)
  278. if !ok {
  279. return nil, fmt.Errorf("%[1]w at position %[3]d (%[2]T): %+[2]v", ErrNonStringKey, key, r.index)
  280. }
  281. ret[key], err = r.read(true)
  282. if err != nil {
  283. return nil, err
  284. }
  285. }
  286. return ret, nil
  287. }
  288. func (r *binaryDecoder) readList(tag int) ([]Node, error) {
  289. size, err := r.readListSize(tag)
  290. if err != nil {
  291. return nil, err
  292. }
  293. ret := make([]Node, size)
  294. for i := 0; i < size; i++ {
  295. n, err := r.readNode()
  296. if err != nil {
  297. return nil, err
  298. }
  299. ret[i] = *n
  300. }
  301. return ret, nil
  302. }
  303. func (r *binaryDecoder) readNode() (*Node, error) {
  304. ret := &Node{}
  305. size, err := r.readInt8(false)
  306. if err != nil {
  307. return nil, err
  308. }
  309. listSize, err := r.readListSize(size)
  310. if err != nil {
  311. return nil, err
  312. }
  313. rawDesc, err := r.read(true)
  314. if err != nil {
  315. return nil, err
  316. }
  317. ret.Tag = rawDesc.(string)
  318. if listSize == 0 || ret.Tag == "" {
  319. return nil, ErrInvalidNode
  320. }
  321. ret.Attrs, err = r.readAttributes((listSize - 1) >> 1)
  322. if err != nil {
  323. return nil, err
  324. }
  325. if listSize%2 == 1 {
  326. return ret, nil
  327. }
  328. ret.Content, err = r.read(false)
  329. return ret, err
  330. }
  331. func (r *binaryDecoder) readBytesOrString(length int, asString bool) (interface{}, error) {
  332. data, err := r.readRaw(length)
  333. if err != nil {
  334. return nil, err
  335. }
  336. if asString {
  337. return string(data), nil
  338. }
  339. return data, nil
  340. }
  341. func (r *binaryDecoder) readRaw(length int) ([]byte, error) {
  342. if err := r.checkEOS(length); err != nil {
  343. return nil, err
  344. }
  345. ret := r.data[r.index : r.index+length]
  346. r.index += length
  347. return ret, nil
  348. }