msgpack.vim 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  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 VimL code contains “reference” implementation which does not
  99. " 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(''): 'binary',
  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. let ret = [a:0 ? '"' : '="']
  391. for v in a:v._VAL
  392. call add(
  393. \ret,
  394. \substitute(
  395. \substitute(v, '["\\]', '\\\0', 'g'),
  396. \'\n', '\\0', 'g'))
  397. call add(ret, '\n')
  398. endfor
  399. let ret[-1] = '"'
  400. return join(ret, '')
  401. endfunction
  402. ""
  403. " Dump binary string.
  404. function s:msgpack_dump_binary(v) abort
  405. if type(a:v) == type({})
  406. return s:msgpack_dump_string(a:v, 1)
  407. else
  408. return s:msgpack_dump_string({'_VAL': split(a:v, "\n", 1)}, 1)
  409. endif
  410. endfunction
  411. ""
  412. " Dump array value.
  413. function s:msgpack_dump_array(v) abort
  414. let val = type(a:v) == type({}) ? a:v._VAL : a:v
  415. return '[' . join(map(val[:], 'msgpack#string(v:val)'), ', ') . ']'
  416. endfunction
  417. ""
  418. " Dump dictionary value.
  419. function s:msgpack_dump_map(v) abort
  420. let ret = ['{']
  421. if msgpack#special_type(a:v) is 0
  422. for [k, v] in items(a:v)
  423. let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n", 1)}),
  424. \': ',
  425. \msgpack#string(v),
  426. \', ']
  427. unlet v
  428. endfor
  429. if !empty(a:v)
  430. call remove(ret, -1)
  431. endif
  432. else
  433. for [k, v] in sort(copy(a:v._VAL))
  434. let ret += [msgpack#string(k),
  435. \': ',
  436. \msgpack#string(v),
  437. \', ']
  438. unlet k
  439. unlet v
  440. endfor
  441. if !empty(a:v._VAL)
  442. call remove(ret, -1)
  443. endif
  444. endif
  445. let ret += ['}']
  446. return join(ret, '')
  447. endfunction
  448. ""
  449. " Dump extension value.
  450. function s:msgpack_dump_ext(v) abort
  451. return printf('+(%i)%s', a:v._VAL[0],
  452. \s:msgpack_dump_string({'_VAL': a:v._VAL[1]}, 1))
  453. endfunction
  454. ""
  455. " Convert msgpack object to a string, like string() function does. Result of the
  456. " conversion may be passed to msgpack#eval().
  457. function msgpack#string(v) abort
  458. if type(a:v) == type({})
  459. let type = msgpack#special_type(a:v)
  460. if type is 0
  461. let type = 'map'
  462. endif
  463. else
  464. let type = get(s:MSGPACK_STANDARD_TYPES, type(a:v), 0)
  465. if type is 0
  466. throw printf('msgpack:invtype: Unable to convert value %s', string(a:v))
  467. endif
  468. endif
  469. return s:msgpack_dump_{type}(a:v)
  470. endfunction
  471. ""
  472. " Copy msgpack object like deepcopy() does, but leave types intact
  473. function msgpack#deepcopy(obj) abort
  474. if type(a:obj) == type([])
  475. return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
  476. elseif type(a:obj) == type({})
  477. let special_type = msgpack#special_type(a:obj)
  478. if special_type is 0
  479. return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
  480. else
  481. return {
  482. \'_TYPE': v:msgpack_types[special_type],
  483. \'_VAL': msgpack#deepcopy(a:obj._VAL)
  484. \}
  485. endif
  486. else
  487. return copy(a:obj)
  488. endif
  489. endfunction
  490. ""
  491. " Convert an escaped character to needed value
  492. function s:msgpack_eval_str_sub(ch) abort
  493. if a:ch is# 'n'
  494. return '", "'
  495. elseif a:ch is# '0'
  496. return '\n'
  497. else
  498. return '\' . a:ch
  499. endif
  500. endfunction
  501. let s:MSGPACK_SPECIAL_OBJECTS = {
  502. \'NIL': '{''_TYPE'': v:msgpack_types.nil, ''_VAL'': 0}',
  503. \'TRUE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 1}',
  504. \'FALSE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 0}',
  505. \'nan': '(-(1.0/0.0-1.0/0.0))',
  506. \'inf': '(1.0/0.0)',
  507. \}
  508. ""
  509. " Convert msgpack object dumped by msgpack#string() to a VimL object suitable
  510. " for msgpackdump().
  511. "
  512. " @param[in] s String to evaluate.
  513. " @param[in] special_objs Additional special objects, in the same format as
  514. " s:MSGPACK_SPECIAL_OBJECTS.
  515. "
  516. " @return Any value that msgpackparse() may return.
  517. function msgpack#eval(s, special_objs) abort
  518. let s = a:s
  519. let expr = []
  520. let context = []
  521. while !empty(s)
  522. let s = substitute(s, '^\s*', '', '')
  523. if s[0] =~# '\v^\h$'
  524. let name = matchstr(s, '\v\C^\w+')
  525. if has_key(s:MSGPACK_SPECIAL_OBJECTS, name)
  526. call add(expr, s:MSGPACK_SPECIAL_OBJECTS[name])
  527. elseif has_key(a:special_objs, name)
  528. call add(expr, a:special_objs[name])
  529. else
  530. throw 'name-unknown:Unknown name ' . name . ': ' . s
  531. endif
  532. let s = s[len(name):]
  533. elseif (s[0] is# '-' && s[1] =~# '\v^\d$') || s[0] =~# '\v^\d$'
  534. let sign = 1
  535. if s[0] is# '-'
  536. let s = s[1:]
  537. let sign = -1
  538. endif
  539. if s[0:1] is# '0x'
  540. " See comment in msgpack#int_dict_to_str().
  541. let s = s[2:]
  542. let hexnum = matchstr(s, '\v\C^\x+')
  543. if empty(hexnum)
  544. throw '0x-empty:Must have number after 0x: ' . s
  545. elseif len(hexnum) > 16
  546. throw '0x-long:Must have at most 16 hex digits: ' . s
  547. endif
  548. let s = s[len(hexnum):]
  549. let hexnum = repeat('0', 16 - len(hexnum)) . hexnum
  550. let g1 = str2nr(hexnum[0], 16)
  551. let g2 = str2nr(hexnum[1:7], 16)
  552. let g3 = str2nr(hexnum[8], 16)
  553. let g4 = str2nr(hexnum[9:15], 16)
  554. let v1 = s:shift(g1, -2)
  555. let v2 = or(or(s:shift(s:mask1(g1, 2), 29), s:shift(g2, 1)),
  556. \s:mask1(s:shift(g3, -3), 1))
  557. let v3 = or(s:shift(s:mask1(g3, 3), 28), g4)
  558. call add(expr, printf('{''_TYPE'': v:msgpack_types.integer, '.
  559. \'''_VAL'': [%i, %u, %u, %u]}',
  560. \sign, v1, v2, v3))
  561. else
  562. let num = matchstr(s, '\v\C^\d+')
  563. let s = s[len(num):]
  564. if sign == -1
  565. call add(expr, '-')
  566. endif
  567. call add(expr, num)
  568. if s[0] is# '.'
  569. let dec = matchstr(s, '\v\C^\.\d+%(e[+-]?\d+)?')
  570. if empty(dec)
  571. throw '0.-nodigits:Decimal dot must be followed by digit(s): ' . s
  572. endif
  573. let s = s[len(dec):]
  574. call add(expr, dec)
  575. endif
  576. endif
  577. elseif s =~# '\v^\-%(inf|nan)'
  578. call add(expr, '-')
  579. call add(expr, s:MSGPACK_SPECIAL_OBJECTS[s[1:3]])
  580. let s = s[4:]
  581. elseif stridx('="+', s[0]) != -1
  582. let match = matchlist(s, '\v\C^(\=|\+\((\-?\d+)\)|)(\"%(\\.|[^\\"]+)*\")')
  583. if empty(match)
  584. throw '"-invalid:Invalid string: ' . s
  585. endif
  586. call add(expr, '{''_TYPE'': v:msgpack_types.')
  587. if empty(match[1])
  588. call add(expr, 'binary')
  589. elseif match[1] is# '='
  590. call add(expr, 'string')
  591. else
  592. call add(expr, 'ext')
  593. endif
  594. call add(expr, ', ''_VAL'': [')
  595. if match[1][0] is# '+'
  596. call add(expr, match[2] . ', [')
  597. endif
  598. call add(expr, substitute(match[3], '\v\C\\(.)',
  599. \'\=s:msgpack_eval_str_sub(submatch(1))', 'g'))
  600. if match[1][0] is# '+'
  601. call add(expr, ']')
  602. endif
  603. call add(expr, ']}')
  604. let s = s[len(match[0]):]
  605. elseif s[0] is# '{'
  606. call add(context, 'map')
  607. call add(expr, '{''_TYPE'': v:msgpack_types.map, ''_VAL'': [')
  608. call add(expr, '[')
  609. let s = s[1:]
  610. elseif s[0] is# '['
  611. call add(context, 'array')
  612. call add(expr, '[')
  613. let s = s[1:]
  614. elseif s[0] is# ':'
  615. call add(expr, ',')
  616. let s = s[1:]
  617. elseif s[0] is# ','
  618. if context[-1] is# 'array'
  619. call add(expr, ',')
  620. else
  621. call add(expr, '], [')
  622. endif
  623. let s = s[1:]
  624. elseif s[0] is# ']'
  625. call remove(context, -1)
  626. call add(expr, ']')
  627. let s = s[1:]
  628. elseif s[0] is# '}'
  629. call remove(context, -1)
  630. if expr[-1] is# "\x5B"
  631. call remove(expr, -1)
  632. else
  633. call add(expr, ']')
  634. endif
  635. call add(expr, ']}')
  636. let s = s[1:]
  637. elseif s[0] is# ''''
  638. let char = matchstr(s, '\v\C^\''\zs%(\\\d+|.)\ze\''')
  639. if empty(char)
  640. throw 'char-invalid:Invalid integer character literal format: ' . s
  641. endif
  642. if char[0] is# '\'
  643. call add(expr, +char[1:])
  644. else
  645. call add(expr, char2nr(char))
  646. endif
  647. let s = s[len(char) + 2:]
  648. else
  649. throw 'unknown:Invalid non-space character: ' . s
  650. endif
  651. endwhile
  652. if empty(expr)
  653. throw 'empty:Parsed string is empty'
  654. endif
  655. return eval(join(expr, ''))
  656. endfunction
  657. ""
  658. " Check whether two msgpack values are equal
  659. function msgpack#equal(a, b)
  660. let atype = msgpack#type(a:a)
  661. let btype = msgpack#type(a:b)
  662. if atype isnot# btype
  663. return 0
  664. endif
  665. let aspecial = msgpack#special_type(a:a)
  666. let bspecial = msgpack#special_type(a:b)
  667. if aspecial is# bspecial
  668. if aspecial is# 0
  669. if type(a:a) == type({})
  670. if len(a:a) != len(a:b)
  671. return 0
  672. endif
  673. if !empty(filter(keys(a:a), '!has_key(a:b, v:val)'))
  674. return 0
  675. endif
  676. for [k, v] in items(a:a)
  677. if !msgpack#equal(v, a:b[k])
  678. return 0
  679. endif
  680. unlet v
  681. endfor
  682. return 1
  683. elseif type(a:a) == type([])
  684. if len(a:a) != len(a:b)
  685. return 0
  686. endif
  687. let i = 0
  688. for asubval in a:a
  689. if !msgpack#equal(asubval, a:b[i])
  690. return 0
  691. endif
  692. let i += 1
  693. unlet asubval
  694. endfor
  695. return 1
  696. elseif type(a:a) == type(0.0)
  697. return (a:a == a:a ? a:a == a:b : string(a:a) ==# string(a:b))
  698. else
  699. return a:a ==# a:b
  700. endif
  701. elseif aspecial is# 'map' || aspecial is# 'array'
  702. if len(a:a._VAL) != len(a:b._VAL)
  703. return 0
  704. endif
  705. let alist = aspecial is# 'map' ? sort(copy(a:a._VAL)) : a:a._VAL
  706. let blist = bspecial is# 'map' ? sort(copy(a:b._VAL)) : a:b._VAL
  707. let i = 0
  708. for asubval in alist
  709. let bsubval = blist[i]
  710. if aspecial is# 'map'
  711. if !(msgpack#equal(asubval[0], bsubval[0])
  712. \&& msgpack#equal(asubval[1], bsubval[1]))
  713. return 0
  714. endif
  715. else
  716. if !msgpack#equal(asubval, bsubval)
  717. return 0
  718. endif
  719. endif
  720. let i += 1
  721. unlet asubval
  722. unlet bsubval
  723. endfor
  724. return 1
  725. elseif aspecial is# 'nil'
  726. return 1
  727. elseif aspecial is# 'float'
  728. return (a:a._VAL == a:a._VAL
  729. \? (a:a._VAL == a:b._VAL)
  730. \: (string(a:a._VAL) ==# string(a:b._VAL)))
  731. else
  732. return a:a._VAL ==# a:b._VAL
  733. endif
  734. else
  735. if atype is# 'array'
  736. let a = aspecial is 0 ? a:a : a:a._VAL
  737. let b = bspecial is 0 ? a:b : a:b._VAL
  738. return msgpack#equal(a, b)
  739. elseif atype is# 'binary'
  740. let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL)
  741. let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL)
  742. return a ==# b
  743. elseif atype is# 'map'
  744. if aspecial is 0
  745. let akeys = copy(a:a)
  746. if len(a:b._VAL) != len(akeys)
  747. return 0
  748. endif
  749. for [k, v] in a:b._VAL
  750. if msgpack#type(k) isnot# 'string'
  751. " Non-special mapping cannot have non-string keys
  752. return 0
  753. endif
  754. if (empty(k._VAL)
  755. \|| k._VAL ==# [""]
  756. \|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
  757. " Non-special mapping cannot have zero byte in key or an empty key
  758. return 0
  759. endif
  760. let kstr = join(k._VAL, "\n")
  761. if !has_key(akeys, kstr)
  762. " Protects from both missing and duplicate keys
  763. return 0
  764. endif
  765. if !msgpack#equal(akeys[kstr], v)
  766. return 0
  767. endif
  768. call remove(akeys, kstr)
  769. unlet k
  770. unlet v
  771. endfor
  772. return 1
  773. else
  774. return msgpack#equal(a:b, a:a)
  775. endif
  776. elseif atype is# 'float'
  777. let a = aspecial is 0 ? a:a : a:a._VAL
  778. let b = bspecial is 0 ? a:b : a:b._VAL
  779. return (a == a ? a == b : string(a) ==# string(b))
  780. elseif atype is# 'integer'
  781. if aspecial is 0
  782. let sign = a:a >= 0 ? 1 : -1
  783. let a = sign * a:a
  784. let v1 = s:mask1(s:shift(a, -62), 2)
  785. let v2 = s:mask1(s:shift(a, -31), 31)
  786. let v3 = s:mask1(a, 31)
  787. return [sign, v1, v2, v3] == a:b._VAL
  788. else
  789. return msgpack#equal(a:b, a:a)
  790. endif
  791. else
  792. throw printf('internal-invalid-type: %s == %s, but special %s /= %s',
  793. \atype, btype, aspecial, bspecial)
  794. endif
  795. endif
  796. endfunction