msgpack.vim 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. if exists('g:loaded_msgpack_autoload')
  2. finish
  3. endif
  4. let g:loaded_msgpack_autoload = 1
  5. ""
  6. " Check that given value is an integer. Respects |msgpack-special-dict|.
  7. function msgpack#is_int(v) abort
  8. return type(a:v) == type(0) || (
  9. \type(a:v) == type({}) && get(a:v, '_TYPE') is# v:msgpack_types.integer)
  10. endfunction
  11. ""
  12. " Check that given value is an unsigned integer. Respects
  13. " |msgpack-special-dict|.
  14. function msgpack#is_uint(v) abort
  15. return msgpack#is_int(a:v) && (type(a:v) == type(0)
  16. \? a:v >= 0
  17. \: a:v._VAL[0] > 0)
  18. endfunction
  19. ""
  20. " True if s:msgpack_init_python() function was already run.
  21. let s:msgpack_python_initialized = 0
  22. ""
  23. " Cached return of s:msgpack_init_python() used when
  24. " s:msgpack_python_initialized is true.
  25. let s:msgpack_python_type = 0
  26. ""
  27. " Create Python functions that are necessary for work. Also defines functions
  28. " s:msgpack_dict_strftime(format, timestamp) and s:msgpack_dict_strptime(format,
  29. " string).
  30. "
  31. " @return Zero in case no Python is available, empty string if Python-2 is
  32. " available and string `"3"` if Python-3 is available.
  33. function s:msgpack_init_python() abort
  34. if s:msgpack_python_initialized
  35. return s:msgpack_python_type
  36. endif
  37. let s:msgpack_python_initialized = 1
  38. for suf in (has('win32') ? ['3'] : ['', '3'])
  39. try
  40. execute 'python' . suf
  41. \. "\n"
  42. \. "def shada_dict_strftime():\n"
  43. \. " import datetime\n"
  44. \. " import vim\n"
  45. \. " fmt = vim.eval('a:format')\n"
  46. \. " timestamp = vim.eval('a:timestamp')\n"
  47. \. " timestamp = [int(v) for v in timestamp['_VAL']]\n"
  48. \. " timestamp = timestamp[0] * (timestamp[1] << 62\n"
  49. \. " | timestamp[2] << 31\n"
  50. \. " | timestamp[3])\n"
  51. \. " time = datetime.datetime.fromtimestamp(timestamp)\n"
  52. \. " return time.strftime(fmt)\n"
  53. \. "def shada_dict_strptime():\n"
  54. \. " import calendar\n"
  55. \. " import datetime\n"
  56. \. " import vim\n"
  57. \. " fmt = vim.eval('a:format')\n"
  58. \. " timestr = vim.eval('a:string')\n"
  59. \. " timestamp = datetime.datetime.strptime(timestr, fmt)\n"
  60. \. " try:\n"
  61. \. " timestamp = int(timestamp.timestamp())\n"
  62. \. " except:\n"
  63. \. " try:\n"
  64. \. " timestamp = int(timestamp.strftime('%s'))\n"
  65. \. " except:\n"
  66. \. " timestamp = calendar.timegm(timestamp.utctimetuple())\n"
  67. \. " if timestamp > 2 ** 31:\n"
  68. \. " tsabs = abs(timestamp)\n"
  69. \. " return ('{\"_TYPE\": v:msgpack_types.integer,'\n"
  70. \. " + '\"_VAL\": [{sign},{v1},{v2},{v3}]}').format(\n"
  71. \. " sign=(1 if timestamp >= 0 else -1),\n"
  72. \. " v1=((tsabs >> 62) & 0x3),\n"
  73. \. " v2=((tsabs >> 31) & (2 ** 31 - 1)),\n"
  74. \. " v3=(tsabs & (2 ** 31 - 1)))\n"
  75. \. " else:\n"
  76. \. " return str(timestamp)\n"
  77. execute "function s:msgpack_dict_strftime(format, timestamp) abort\n"
  78. \. " return py" . suf . "eval('shada_dict_strftime()')\n"
  79. \. "endfunction\n"
  80. \. "function s:msgpack_dict_strptime(format, string)\n"
  81. \. " return eval(py" . suf . "eval('shada_dict_strptime()'))\n"
  82. \. "endfunction\n"
  83. let s:msgpack_python_type = suf
  84. return suf
  85. catch
  86. continue
  87. endtry
  88. endfor
  89. ""
  90. " strftime() function for |msgpack-special-dict| values.
  91. "
  92. " @param[in] format String according to which time should be formatted.
  93. " @param[in] timestamp Timestamp (seconds since epoch) to format.
  94. "
  95. " @return Formatted timestamp.
  96. "
  97. " @warning Without +python or +python3 this function does not work correctly.
  98. " The Vimscript code contains “reference” implementation which does
  99. " not really work because of precision loss.
  100. function s:msgpack_dict_strftime(format, timestamp)
  101. return msgpack#strftime(a:format, +msgpack#int_dict_to_str(a:timestamp))
  102. endfunction
  103. ""
  104. " Function that parses given string according to given format.
  105. "
  106. " @param[in] format String according to which string was formatted.
  107. " @param[in] string Time formatted according to format.
  108. "
  109. " @return Timestamp.
  110. "
  111. " @warning Without +python or +python3 this function is able to work only with
  112. " 31-bit (32-bit signed) timestamps that have format
  113. " `%Y-%m-%dT%H:%M:%S`.
  114. function s:msgpack_dict_strptime(format, string)
  115. let fmt = '%Y-%m-%dT%H:%M:%S'
  116. if a:format isnot# fmt
  117. throw 'notimplemented-format:Only ' . fmt . ' format is supported'
  118. endif
  119. let match = matchlist(a:string,
  120. \'\v\C^(\d+)\-(\d+)\-(\d+)T(\d+)\:(\d+)\:(\d+)$')
  121. if empty(match)
  122. throw 'invalid-string:Given string does not match format ' . a:format
  123. endif
  124. call map(match, 'str2nr(v:val, 10)')
  125. let [year, month, day, hour, minute, second] = match[1:6]
  126. " Bisection start and end:
  127. "
  128. " Start: 365 days in year, 28 days in month, -12 hours tz offset.
  129. let bisect_ts_start = (((((year - 1970) * 365
  130. \+ (month - 1) * 28
  131. \+ (day - 1)) * 24
  132. \+ hour - 12) * 60
  133. \+ minute) * 60
  134. \+ second)
  135. if bisect_ts_start < 0
  136. let bisect_ts_start = 0
  137. endif
  138. let start_string = strftime(fmt, bisect_ts_start)
  139. if start_string is# a:string
  140. return bisect_ts_start
  141. endif
  142. " End: 366 days in year, 31 day in month, +14 hours tz offset.
  143. let bisect_ts_end = (((((year - 1970) * 366
  144. \+ (month - 1) * 31
  145. \+ (day - 1)) * 24
  146. \+ hour + 14) * 60
  147. \+ minute) * 60
  148. \+ second)
  149. let end_string = strftime(fmt, bisect_ts_end)
  150. if end_string is# a:string
  151. return bisect_ts_end
  152. endif
  153. if start_string ># end_string
  154. throw 'internal-start-gt:Internal error: start > end'
  155. endif
  156. if start_string is# end_string
  157. throw printf('internal-start-eq:Internal error: '
  158. \. 'start(%u)==end(%u), but start(%s)!=string(%s)',
  159. \bisect_ts_start, bisect_ts_end,
  160. \string(start_string), string(a:string))
  161. endif
  162. if start_string ># a:string
  163. throw 'internal-start-string:Internal error: start > string'
  164. endif
  165. if end_string <# a:string
  166. throw 'internal-end-string:Internal error: end < string'
  167. endif
  168. while 1
  169. let bisect_ts_middle = (bisect_ts_start/2) + (bisect_ts_end/2)
  170. let middle_string = strftime(fmt, bisect_ts_middle)
  171. if a:string is# middle_string
  172. return bisect_ts_middle
  173. elseif a:string ># middle_string
  174. if bisect_ts_middle == bisect_ts_start
  175. let bisect_ts_start += 1
  176. else
  177. let bisect_ts_start = bisect_ts_middle
  178. endif
  179. else
  180. if bisect_ts_middle == bisect_ts_end
  181. let bisect_ts_end -= 1
  182. else
  183. let bisect_ts_end = bisect_ts_middle
  184. endif
  185. endif
  186. if bisect_ts_start >= bisect_ts_end
  187. throw 'not-found:Unable to find timestamp'
  188. endif
  189. endwhile
  190. endfunction
  191. return 0
  192. endfunction
  193. ""
  194. " Wrapper for strftime() that respects |msgpack-special-dict|. May actually use
  195. " non-standard strftime() implementations for |msgpack-special-dict| values.
  196. "
  197. " @param[in] format Format string.
  198. " @param[in] timestamp Formatted timestamp.
  199. function msgpack#strftime(format, timestamp) abort
  200. if type(a:timestamp) == type({})
  201. call s:msgpack_init_python()
  202. return s:msgpack_dict_strftime(a:format, a:timestamp)
  203. else
  204. return strftime(a:format, a:timestamp)
  205. endif
  206. endfunction
  207. ""
  208. " Parse string according to the format.
  209. "
  210. " Requires +python available. If it is not then only supported format is
  211. " `%Y-%m-%dT%H:%M:%S` because this is the format used by ShaDa plugin. Also in
  212. " this case bisection will be used (timestamps tried with strftime() up until
  213. " result matches the string) and only 31-bit (signed 32-bit: with negative
  214. " timestamps being useless this leaves 31 bits) timestamps will be supported.
  215. "
  216. " @param[in] format Time format.
  217. " @param[in] string Parsed time string. Must match given format.
  218. "
  219. " @return Timestamp. Possibly as |msgpack-special-dict|.
  220. function msgpack#strptime(format, string) abort
  221. call s:msgpack_init_python()
  222. return s:msgpack_dict_strptime(a:format, a:string)
  223. endfunction
  224. let s:MSGPACK_HIGHEST_BIT = 1
  225. let s:MSGPACK_HIGHEST_BIT_NR = 0
  226. while s:MSGPACK_HIGHEST_BIT * 2 > 0
  227. let s:MSGPACK_HIGHEST_BIT = s:MSGPACK_HIGHEST_BIT * 2
  228. let s:MSGPACK_HIGHEST_BIT_NR += 1
  229. endwhile
  230. ""
  231. " Shift given number by given amount of bits
  232. function s:shift(n, s) abort
  233. if a:s == 0
  234. return a:n
  235. elseif a:s < 0
  236. let ret = a:n
  237. for _ in range(-a:s)
  238. let ret = ret / 2
  239. endfor
  240. return ret
  241. else
  242. let ret = a:n
  243. for i in range(a:s)
  244. let new_ret = ret * 2
  245. if new_ret < ret
  246. " Overflow: remove highest bit
  247. let ret = xor(s:MSGPACK_HIGHEST_BIT, ret) * 2
  248. endif
  249. let ret = new_ret
  250. endfor
  251. return ret
  252. endif
  253. endfunction
  254. let s:msgpack_mask_cache = {
  255. \s:MSGPACK_HIGHEST_BIT_NR : s:MSGPACK_HIGHEST_BIT - 1}
  256. ""
  257. " Apply a mask where first m bits are ones and other are zeroes to a given
  258. " number
  259. function s:mask1(n, m) abort
  260. if a:m > s:MSGPACK_HIGHEST_BIT_NR + 1
  261. let m = s:MSGPACK_HIGHEST_BIT_NR + 1
  262. else
  263. let m = a:m
  264. endif
  265. if !has_key(s:msgpack_mask_cache, m)
  266. let p = 0
  267. for _ in range(m)
  268. let p = p * 2 + 1
  269. endfor
  270. let s:msgpack_mask_cache[m] = p
  271. endif
  272. return and(a:n, s:msgpack_mask_cache[m])
  273. endfunction
  274. ""
  275. " Convert |msgpack-special-dict| that represents integer value to a string. Uses
  276. " hexadecimal representation starting with 0x because it is the easiest to
  277. " convert to.
  278. function msgpack#int_dict_to_str(v) abort
  279. let v = a:v._VAL
  280. " 64-bit number:
  281. " 0000000001111111111222222222233333333334444444444555555555566666
  282. " 1234567890123456789012345678901234567890123456789012345678901234
  283. " Split in _VAL:
  284. " 0000000001111111111222222222233 3333333344444444445555555555666 66
  285. " 1234567890123456789012345678901 2345678901234567890123456789012 34
  286. " Split by hex digits:
  287. " 0000 0000 0111 1111 1112 2222 2222 2333 3333 3334 4444 4444 4555 5555 5556 6666
  288. " 1234 5678 9012 3456 7890 1234 5678 9012 3456 7890 1234 5678 9012 3456 7890 1234
  289. "
  290. " Total split:
  291. " _VAL[3] _VAL[2] _VAL[1]
  292. " ______________________________________ _______________________________________ __
  293. " 0000 0000 0111 1111 1112 2222 2222 233 3 3333 3334 4444 4444 4555 5555 5556 66 66
  294. " 1234 5678 9012 3456 7890 1234 5678 901 2 3456 7890 1234 5678 9012 3456 7890 12 34
  295. " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^
  296. " g4 g3 g2 g1
  297. " ********************************** *** * ********************************** ** **
  298. " 1 2 3 4 5 6
  299. " 1: s:mask1(v[3], 28): first 28 bits of _VAL[3]
  300. " 2: s:shift(v[3], -28): last 3 bits of _VAL[3]
  301. " 3: s:mask1(v[2], 1): first bit of _VAL[2]
  302. " 4: s:mask1(s:shift(v[2], -1), 28): bits 2 .. 29 of _VAL[2]
  303. " 5: s:shift(v[2], -29): last 2 bits of _VAL[2]
  304. " 6: s:shift(v[1], 2): _VAL[1]
  305. let g4 = printf('%07x', s:mask1(v[3], 28))
  306. let g3 = printf('%01x', or(s:shift(v[3], -28), s:shift(s:mask1(v[2], 1), 3)))
  307. let g2 = printf('%07x', s:mask1(s:shift(v[2], -1), 28))
  308. let g1 = printf('%01x', or(s:shift(v[2], -29), s:shift(v[1], 2)))
  309. return ((v[0] < 0 ? '-' : '') . '0x' . g1 . g2 . g3 . g4)
  310. endfunction
  311. ""
  312. " True boolean value.
  313. let g:msgpack#true = {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}
  314. lockvar! g:msgpack#true
  315. ""
  316. " False boolean value.
  317. let g:msgpack#false = {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}
  318. lockvar! g:msgpack#false
  319. ""
  320. " NIL value.
  321. let g:msgpack#nil = {'_TYPE': v:msgpack_types.nil, '_VAL': 0}
  322. lockvar! g:msgpack#nil
  323. ""
  324. " Deduce type of |msgpack-special-dict|.
  325. "
  326. " @return zero if given dictionary is not special or name of the key in
  327. " v:msgpack_types dictionary.
  328. function msgpack#special_type(v) abort
  329. if type(a:v) != type({}) || !has_key(a:v, '_TYPE')
  330. return 0
  331. endif
  332. for [k, v] in items(v:msgpack_types)
  333. if a:v._TYPE is v
  334. return k
  335. endif
  336. endfor
  337. return 0
  338. endfunction
  339. ""
  340. " Mapping that maps type() output to type names.
  341. let s:MSGPACK_STANDARD_TYPES = {
  342. \type(0): 'integer',
  343. \type(0.0): 'float',
  344. \type(''): 'string',
  345. \type([]): 'array',
  346. \type({}): 'map',
  347. \type(v:true): 'boolean',
  348. \type(v:null): 'nil',
  349. \}
  350. ""
  351. " Deduce type of one of items returned by msgpackparse().
  352. "
  353. " @return Name of a key in v:msgpack_types.
  354. function msgpack#type(v) abort
  355. let special_type = msgpack#special_type(a:v)
  356. if special_type is 0
  357. return s:MSGPACK_STANDARD_TYPES[type(a:v)]
  358. endif
  359. return special_type
  360. endfunction
  361. ""
  362. " Dump nil value.
  363. function s:msgpack_dump_nil(v) abort
  364. return 'NIL'
  365. endfunction
  366. ""
  367. " Dump boolean value.
  368. function s:msgpack_dump_boolean(v) abort
  369. return (a:v is v:true || (a:v isnot v:false && a:v._VAL)) ? 'TRUE' : 'FALSE'
  370. endfunction
  371. ""
  372. " Dump integer msgpack value.
  373. function s:msgpack_dump_integer(v) abort
  374. if type(a:v) == type({})
  375. return msgpack#int_dict_to_str(a:v)
  376. else
  377. return string(a:v)
  378. endif
  379. endfunction
  380. ""
  381. " Dump floating-point value.
  382. function s:msgpack_dump_float(v) abort
  383. return substitute(string(type(a:v) == type({}) ? a:v._VAL : a:v),
  384. \'\V\^\(-\)\?str2float(''\(inf\|nan\)'')\$', '\1\2', '')
  385. endfunction
  386. ""
  387. " Dump |msgpack-special-dict| that represents a string. If any additional
  388. " parameter is given then it dumps binary string.
  389. function s:msgpack_dump_string(v) abort
  390. if type(a:v) == type({})
  391. let val = a:v
  392. else
  393. let val = {'_VAL': split(a:v, "\n", 1)}
  394. end
  395. let ret = ['"']
  396. for v in val._VAL
  397. call add(
  398. \ret,
  399. \substitute(
  400. \substitute(v, '["\\]', '\\\0', 'g'),
  401. \'\n', '\\0', 'g'))
  402. call add(ret, '\n')
  403. endfor
  404. let ret[-1] = '"'
  405. return join(ret, '')
  406. endfunction
  407. ""
  408. " Dump array value.
  409. function s:msgpack_dump_array(v) abort
  410. let val = type(a:v) == type({}) ? a:v._VAL : a:v
  411. return '[' . join(map(val[:], 'msgpack#string(v:val)'), ', ') . ']'
  412. endfunction
  413. ""
  414. " Dump dictionary value.
  415. function s:msgpack_dump_map(v) abort
  416. let ret = ['{']
  417. if msgpack#special_type(a:v) is 0
  418. for [k, v] in items(a:v)
  419. let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n")}),
  420. \': ',
  421. \msgpack#string(v),
  422. \', ']
  423. unlet v
  424. endfor
  425. if !empty(a:v)
  426. call remove(ret, -1)
  427. endif
  428. else
  429. for [k, v] in sort(copy(a:v._VAL))
  430. let ret += [msgpack#string(k),
  431. \': ',
  432. \msgpack#string(v),
  433. \', ']
  434. unlet k
  435. unlet v
  436. endfor
  437. if !empty(a:v._VAL)
  438. call remove(ret, -1)
  439. endif
  440. endif
  441. let ret += ['}']
  442. return join(ret, '')
  443. endfunction
  444. ""
  445. " Dump extension value.
  446. function s:msgpack_dump_ext(v) abort
  447. return printf('+(%i)%s', a:v._VAL[0],
  448. \s:msgpack_dump_string({'_VAL': a:v._VAL[1]}))
  449. endfunction
  450. ""
  451. " Convert msgpack object to a string, like string() function does. Result of the
  452. " conversion may be passed to msgpack#eval().
  453. function msgpack#string(v) abort
  454. if type(a:v) == type({})
  455. let type = msgpack#special_type(a:v)
  456. if type is 0
  457. let type = 'map'
  458. endif
  459. else
  460. let type = get(s:MSGPACK_STANDARD_TYPES, type(a:v), 0)
  461. if type is 0
  462. throw printf('msgpack:invtype: Unable to convert value %s', string(a:v))
  463. endif
  464. endif
  465. return s:msgpack_dump_{type}(a:v)
  466. endfunction
  467. ""
  468. " Copy msgpack object like deepcopy() does, but leave types intact
  469. function msgpack#deepcopy(obj) abort
  470. if type(a:obj) == type([])
  471. return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
  472. elseif type(a:obj) == type({})
  473. let special_type = msgpack#special_type(a:obj)
  474. if special_type is 0
  475. return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
  476. else
  477. return {
  478. \'_TYPE': v:msgpack_types[special_type],
  479. \'_VAL': msgpack#deepcopy(a:obj._VAL)
  480. \}
  481. endif
  482. else
  483. return copy(a:obj)
  484. endif
  485. endfunction
  486. ""
  487. " Convert an escaped character to needed value
  488. function s:msgpack_eval_str_sub(ch) abort
  489. if a:ch is# 'n'
  490. return '", "'
  491. elseif a:ch is# '0'
  492. return '\n'
  493. else
  494. return '\' . a:ch
  495. endif
  496. endfunction
  497. let s:MSGPACK_SPECIAL_OBJECTS = {
  498. \'NIL': '{''_TYPE'': v:msgpack_types.nil, ''_VAL'': 0}',
  499. \'TRUE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 1}',
  500. \'FALSE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 0}',
  501. \'nan': '(-(1.0/0.0-1.0/0.0))',
  502. \'inf': '(1.0/0.0)',
  503. \}
  504. ""
  505. " Convert msgpack object dumped by msgpack#string() to a Vimscript object
  506. " suitable for msgpackdump().
  507. "
  508. " @param[in] s String to evaluate.
  509. " @param[in] special_objs Additional special objects, in the same format as
  510. " s:MSGPACK_SPECIAL_OBJECTS.
  511. "
  512. " @return Any value that msgpackparse() may return.
  513. function msgpack#eval(s, special_objs) abort
  514. let s = a:s
  515. let expr = []
  516. let context = []
  517. while !empty(s)
  518. let s = substitute(s, '^\s*', '', '')
  519. if s[0] =~# '\v^\h$'
  520. let name = matchstr(s, '\v\C^\w+')
  521. if has_key(s:MSGPACK_SPECIAL_OBJECTS, name)
  522. call add(expr, s:MSGPACK_SPECIAL_OBJECTS[name])
  523. elseif has_key(a:special_objs, name)
  524. call add(expr, a:special_objs[name])
  525. else
  526. throw 'name-unknown:Unknown name ' . name . ': ' . s
  527. endif
  528. let s = s[len(name):]
  529. elseif (s[0] is# '-' && s[1] =~# '\v^\d$') || s[0] =~# '\v^\d$'
  530. let sign = 1
  531. if s[0] is# '-'
  532. let s = s[1:]
  533. let sign = -1
  534. endif
  535. if s[0:1] is# '0x'
  536. " See comment in msgpack#int_dict_to_str().
  537. let s = s[2:]
  538. let hexnum = matchstr(s, '\v\C^\x+')
  539. if empty(hexnum)
  540. throw '0x-empty:Must have number after 0x: ' . s
  541. elseif len(hexnum) > 16
  542. throw '0x-long:Must have at most 16 hex digits: ' . s
  543. endif
  544. let s = s[len(hexnum):]
  545. let hexnum = repeat('0', 16 - len(hexnum)) . hexnum
  546. let g1 = str2nr(hexnum[0], 16)
  547. let g2 = str2nr(hexnum[1:7], 16)
  548. let g3 = str2nr(hexnum[8], 16)
  549. let g4 = str2nr(hexnum[9:15], 16)
  550. let v1 = s:shift(g1, -2)
  551. let v2 = or(or(s:shift(s:mask1(g1, 2), 29), s:shift(g2, 1)),
  552. \s:mask1(s:shift(g3, -3), 1))
  553. let v3 = or(s:shift(s:mask1(g3, 3), 28), g4)
  554. call add(expr, printf('{''_TYPE'': v:msgpack_types.integer, '.
  555. \'''_VAL'': [%i, %u, %u, %u]}',
  556. \sign, v1, v2, v3))
  557. else
  558. let num = matchstr(s, '\v\C^\d+')
  559. let s = s[len(num):]
  560. if sign == -1
  561. call add(expr, '-')
  562. endif
  563. call add(expr, num)
  564. if s[0] is# '.'
  565. let dec = matchstr(s, '\v\C^\.\d+%(e[+-]?\d+)?')
  566. if empty(dec)
  567. throw '0.-nodigits:Decimal dot must be followed by digit(s): ' . s
  568. endif
  569. let s = s[len(dec):]
  570. call add(expr, dec)
  571. endif
  572. endif
  573. elseif s =~# '\v^\-%(inf|nan)'
  574. call add(expr, '-')
  575. call add(expr, s:MSGPACK_SPECIAL_OBJECTS[s[1:3]])
  576. let s = s[4:]
  577. elseif stridx('="+', s[0]) != -1
  578. let match = matchlist(s, '\v\C^(\=|\+\((\-?\d+)\)|)(\"%(\\.|[^\\"]+)*\")')
  579. if empty(match)
  580. throw '"-invalid:Invalid string: ' . s
  581. endif
  582. call add(expr, '{''_TYPE'': v:msgpack_types.')
  583. if empty(match[1]) || match[1] is# '='
  584. call add(expr, 'string')
  585. else
  586. call add(expr, 'ext')
  587. endif
  588. call add(expr, ', ''_VAL'': [')
  589. if match[1][0] is# '+'
  590. call add(expr, match[2] . ', [')
  591. endif
  592. call add(expr, substitute(match[3], '\v\C\\(.)',
  593. \'\=s:msgpack_eval_str_sub(submatch(1))', 'g'))
  594. if match[1][0] is# '+'
  595. call add(expr, ']')
  596. endif
  597. call add(expr, ']}')
  598. let s = s[len(match[0]):]
  599. elseif s[0] is# '{'
  600. call add(context, 'map')
  601. call add(expr, '{''_TYPE'': v:msgpack_types.map, ''_VAL'': [')
  602. call add(expr, '[')
  603. let s = s[1:]
  604. elseif s[0] is# '['
  605. call add(context, 'array')
  606. call add(expr, '[')
  607. let s = s[1:]
  608. elseif s[0] is# ':'
  609. call add(expr, ',')
  610. let s = s[1:]
  611. elseif s[0] is# ','
  612. if context[-1] is# 'array'
  613. call add(expr, ',')
  614. else
  615. call add(expr, '], [')
  616. endif
  617. let s = s[1:]
  618. elseif s[0] is# ']'
  619. call remove(context, -1)
  620. call add(expr, ']')
  621. let s = s[1:]
  622. elseif s[0] is# '}'
  623. call remove(context, -1)
  624. if expr[-1] is# "\x5B"
  625. call remove(expr, -1)
  626. else
  627. call add(expr, ']')
  628. endif
  629. call add(expr, ']}')
  630. let s = s[1:]
  631. elseif s[0] is# ''''
  632. let char = matchstr(s, '\v\C^\''\zs%(\\\d+|.)\ze\''')
  633. if empty(char)
  634. throw 'char-invalid:Invalid integer character literal format: ' . s
  635. endif
  636. if char[0] is# '\'
  637. call add(expr, +char[1:])
  638. else
  639. call add(expr, char2nr(char))
  640. endif
  641. let s = s[len(char) + 2:]
  642. else
  643. throw 'unknown:Invalid non-space character: ' . s
  644. endif
  645. endwhile
  646. if empty(expr)
  647. throw 'empty:Parsed string is empty'
  648. endif
  649. return eval(join(expr, ''))
  650. endfunction
  651. ""
  652. " Check whether two msgpack values are equal
  653. function msgpack#equal(a, b)
  654. let atype = msgpack#type(a:a)
  655. let btype = msgpack#type(a:b)
  656. if atype isnot# btype
  657. return 0
  658. endif
  659. let aspecial = msgpack#special_type(a:a)
  660. let bspecial = msgpack#special_type(a:b)
  661. if aspecial is# bspecial
  662. if aspecial is# 0
  663. if type(a:a) == type({})
  664. if len(a:a) != len(a:b)
  665. return 0
  666. endif
  667. if !empty(filter(keys(a:a), '!has_key(a:b, v:val)'))
  668. return 0
  669. endif
  670. for [k, v] in items(a:a)
  671. if !msgpack#equal(v, a:b[k])
  672. return 0
  673. endif
  674. unlet v
  675. endfor
  676. return 1
  677. elseif type(a:a) == type([])
  678. if len(a:a) != len(a:b)
  679. return 0
  680. endif
  681. let i = 0
  682. for asubval in a:a
  683. if !msgpack#equal(asubval, a:b[i])
  684. return 0
  685. endif
  686. let i += 1
  687. unlet asubval
  688. endfor
  689. return 1
  690. elseif type(a:a) == type(0.0)
  691. return (a:a == a:a ? a:a == a:b : string(a:a) ==# string(a:b))
  692. else
  693. return a:a ==# a:b
  694. endif
  695. elseif aspecial is# 'map' || aspecial is# 'array'
  696. if len(a:a._VAL) != len(a:b._VAL)
  697. return 0
  698. endif
  699. let alist = aspecial is# 'map' ? sort(copy(a:a._VAL)) : a:a._VAL
  700. let blist = bspecial is# 'map' ? sort(copy(a:b._VAL)) : a:b._VAL
  701. let i = 0
  702. for asubval in alist
  703. let bsubval = blist[i]
  704. if aspecial is# 'map'
  705. if !(msgpack#equal(asubval[0], bsubval[0])
  706. \&& msgpack#equal(asubval[1], bsubval[1]))
  707. return 0
  708. endif
  709. else
  710. if !msgpack#equal(asubval, bsubval)
  711. return 0
  712. endif
  713. endif
  714. let i += 1
  715. unlet asubval
  716. unlet bsubval
  717. endfor
  718. return 1
  719. elseif aspecial is# 'nil'
  720. return 1
  721. elseif aspecial is# 'float'
  722. return (a:a._VAL == a:a._VAL
  723. \? (a:a._VAL == a:b._VAL)
  724. \: (string(a:a._VAL) ==# string(a:b._VAL)))
  725. else
  726. return a:a._VAL ==# a:b._VAL
  727. endif
  728. else
  729. if atype is# 'array'
  730. let a = aspecial is 0 ? a:a : a:a._VAL
  731. let b = bspecial is 0 ? a:b : a:b._VAL
  732. return msgpack#equal(a, b)
  733. elseif atype is# 'string'
  734. let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL)
  735. let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL)
  736. return a ==# b
  737. elseif atype is# 'map'
  738. if aspecial is 0
  739. let akeys = copy(a:a)
  740. if len(a:b._VAL) != len(akeys)
  741. return 0
  742. endif
  743. for [k, v] in a:b._VAL
  744. if msgpack#type(k) isnot# 'string'
  745. " Non-special mapping cannot have non-string keys
  746. return 0
  747. endif
  748. if type(k) == type({})
  749. if (empty(k._VAL)
  750. \|| k._VAL ==# [""]
  751. \|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
  752. " Non-special mapping cannot have zero byte in key or an empty key
  753. return 0
  754. endif
  755. let kstr = join(k._VAL, "\n")
  756. else
  757. let kstr = k
  758. endif
  759. if !has_key(akeys, kstr)
  760. " Protects from both missing and duplicate keys
  761. return 0
  762. endif
  763. if !msgpack#equal(akeys[kstr], v)
  764. return 0
  765. endif
  766. call remove(akeys, kstr)
  767. unlet k
  768. unlet v
  769. endfor
  770. return 1
  771. else
  772. return msgpack#equal(a:b, a:a)
  773. endif
  774. elseif atype is# 'float'
  775. let a = aspecial is 0 ? a:a : a:a._VAL
  776. let b = bspecial is 0 ? a:b : a:b._VAL
  777. return (a == a ? a == b : string(a) ==# string(b))
  778. elseif atype is# 'integer'
  779. if aspecial is 0
  780. let sign = a:a >= 0 ? 1 : -1
  781. let a = sign * a:a
  782. let v1 = s:mask1(s:shift(a, -62), 2)
  783. let v2 = s:mask1(s:shift(a, -31), 31)
  784. let v3 = s:mask1(a, 31)
  785. return [sign, v1, v2, v3] == a:b._VAL
  786. else
  787. return msgpack#equal(a:b, a:a)
  788. endif
  789. else
  790. throw printf('internal-invalid-type: %s == %s, but special %s /= %s',
  791. \atype, btype, aspecial, bspecial)
  792. endif
  793. endif
  794. endfunction