PageRenderTime 65ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/bundle/gems/rack-1.5.2/lib/rack/utils/okjson.rb

https://github.com/bahakz/first_app
Ruby | 599 lines | 454 code | 68 blank | 77 comment | 61 complexity | f17ace4c2356122013157e31b538f36a MD5 | raw file
Possible License(s): Apache-2.0, MIT, GPL-2.0, BSD-3-Clause
  1. # encoding: UTF-8
  2. #
  3. # Copyright 2011, 2012 Keith Rarick
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. # THE SOFTWARE.
  22. # See https://github.com/kr/okjson for updates.
  23. # Imported from the above repo @ d4e8643ad92e14b37d11326855499c7e4108ed17
  24. # Namespace modified for vendoring under Rack::Utils
  25. require 'stringio'
  26. # Some parts adapted from
  27. # http://golang.org/src/pkg/json/decode.go and
  28. # http://golang.org/src/pkg/utf8/utf8.go
  29. module Rack::Utils::OkJson
  30. Upstream = 'LTD7LBKLZWFF7OZK'
  31. extend self
  32. # Decodes a json document in string s and
  33. # returns the corresponding ruby value.
  34. # String s must be valid UTF-8. If you have
  35. # a string in some other encoding, convert
  36. # it first.
  37. #
  38. # String values in the resulting structure
  39. # will be UTF-8.
  40. def decode(s)
  41. ts = lex(s)
  42. v, ts = textparse(ts)
  43. if ts.length > 0
  44. raise Error, 'trailing garbage'
  45. end
  46. v
  47. end
  48. # Parses a "json text" in the sense of RFC 4627.
  49. # Returns the parsed value and any trailing tokens.
  50. # Note: this is almost the same as valparse,
  51. # except that it does not accept atomic values.
  52. def textparse(ts)
  53. if ts.length < 0
  54. raise Error, 'empty'
  55. end
  56. typ, _, val = ts[0]
  57. case typ
  58. when '{' then objparse(ts)
  59. when '[' then arrparse(ts)
  60. else
  61. raise Error, "unexpected #{val.inspect}"
  62. end
  63. end
  64. # Parses a "value" in the sense of RFC 4627.
  65. # Returns the parsed value and any trailing tokens.
  66. def valparse(ts)
  67. if ts.length < 0
  68. raise Error, 'empty'
  69. end
  70. typ, _, val = ts[0]
  71. case typ
  72. when '{' then objparse(ts)
  73. when '[' then arrparse(ts)
  74. when :val,:str then [val, ts[1..-1]]
  75. else
  76. raise Error, "unexpected #{val.inspect}"
  77. end
  78. end
  79. # Parses an "object" in the sense of RFC 4627.
  80. # Returns the parsed value and any trailing tokens.
  81. def objparse(ts)
  82. ts = eat('{', ts)
  83. obj = {}
  84. if ts[0][0] == '}'
  85. return obj, ts[1..-1]
  86. end
  87. k, v, ts = pairparse(ts)
  88. obj[k] = v
  89. if ts[0][0] == '}'
  90. return obj, ts[1..-1]
  91. end
  92. loop do
  93. ts = eat(',', ts)
  94. k, v, ts = pairparse(ts)
  95. obj[k] = v
  96. if ts[0][0] == '}'
  97. return obj, ts[1..-1]
  98. end
  99. end
  100. end
  101. # Parses a "member" in the sense of RFC 4627.
  102. # Returns the parsed values and any trailing tokens.
  103. def pairparse(ts)
  104. (typ, _, k), ts = ts[0], ts[1..-1]
  105. if typ != :str
  106. raise Error, "unexpected #{k.inspect}"
  107. end
  108. ts = eat(':', ts)
  109. v, ts = valparse(ts)
  110. [k, v, ts]
  111. end
  112. # Parses an "array" in the sense of RFC 4627.
  113. # Returns the parsed value and any trailing tokens.
  114. def arrparse(ts)
  115. ts = eat('[', ts)
  116. arr = []
  117. if ts[0][0] == ']'
  118. return arr, ts[1..-1]
  119. end
  120. v, ts = valparse(ts)
  121. arr << v
  122. if ts[0][0] == ']'
  123. return arr, ts[1..-1]
  124. end
  125. loop do
  126. ts = eat(',', ts)
  127. v, ts = valparse(ts)
  128. arr << v
  129. if ts[0][0] == ']'
  130. return arr, ts[1..-1]
  131. end
  132. end
  133. end
  134. def eat(typ, ts)
  135. if ts[0][0] != typ
  136. raise Error, "expected #{typ} (got #{ts[0].inspect})"
  137. end
  138. ts[1..-1]
  139. end
  140. # Scans s and returns a list of json tokens,
  141. # excluding white space (as defined in RFC 4627).
  142. def lex(s)
  143. ts = []
  144. while s.length > 0
  145. typ, lexeme, val = tok(s)
  146. if typ == nil
  147. raise Error, "invalid character at #{s[0,10].inspect}"
  148. end
  149. if typ != :space
  150. ts << [typ, lexeme, val]
  151. end
  152. s = s[lexeme.length..-1]
  153. end
  154. ts
  155. end
  156. # Scans the first token in s and
  157. # returns a 3-element list, or nil
  158. # if s does not begin with a valid token.
  159. #
  160. # The first list element is one of
  161. # '{', '}', ':', ',', '[', ']',
  162. # :val, :str, and :space.
  163. #
  164. # The second element is the lexeme.
  165. #
  166. # The third element is the value of the
  167. # token for :val and :str, otherwise
  168. # it is the lexeme.
  169. def tok(s)
  170. case s[0]
  171. when ?{ then ['{', s[0,1], s[0,1]]
  172. when ?} then ['}', s[0,1], s[0,1]]
  173. when ?: then [':', s[0,1], s[0,1]]
  174. when ?, then [',', s[0,1], s[0,1]]
  175. when ?[ then ['[', s[0,1], s[0,1]]
  176. when ?] then [']', s[0,1], s[0,1]]
  177. when ?n then nulltok(s)
  178. when ?t then truetok(s)
  179. when ?f then falsetok(s)
  180. when ?" then strtok(s)
  181. when Spc then [:space, s[0,1], s[0,1]]
  182. when ?\t then [:space, s[0,1], s[0,1]]
  183. when ?\n then [:space, s[0,1], s[0,1]]
  184. when ?\r then [:space, s[0,1], s[0,1]]
  185. else numtok(s)
  186. end
  187. end
  188. def nulltok(s); s[0,4] == 'null' ? [:val, 'null', nil] : [] end
  189. def truetok(s); s[0,4] == 'true' ? [:val, 'true', true] : [] end
  190. def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end
  191. def numtok(s)
  192. m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
  193. if m && m.begin(0) == 0
  194. if m[3] && !m[2]
  195. [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
  196. elsif m[2]
  197. [:val, m[0], Float(m[0])]
  198. else
  199. [:val, m[0], Integer(m[0])]
  200. end
  201. else
  202. []
  203. end
  204. end
  205. def strtok(s)
  206. m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
  207. if ! m
  208. raise Error, "invalid string literal at #{abbrev(s)}"
  209. end
  210. [:str, m[0], unquote(m[0])]
  211. end
  212. def abbrev(s)
  213. t = s[0,10]
  214. p = t['`']
  215. t = t[0,p] if p
  216. t = t + '...' if t.length < s.length
  217. '`' + t + '`'
  218. end
  219. # Converts a quoted json string literal q into a UTF-8-encoded string.
  220. # The rules are different than for Ruby, so we cannot use eval.
  221. # Unquote will raise an error if q contains control characters.
  222. def unquote(q)
  223. q = q[1...-1]
  224. a = q.dup # allocate a big enough string
  225. rubydoesenc = false
  226. # In ruby >= 1.9, a[w] is a codepoint, not a byte.
  227. if a.class.method_defined?(:force_encoding)
  228. a.force_encoding('UTF-8')
  229. rubydoesenc = true
  230. end
  231. r, w = 0, 0
  232. while r < q.length
  233. c = q[r]
  234. case true
  235. when c == ?\\
  236. r += 1
  237. if r >= q.length
  238. raise Error, "string literal ends with a \"\\\": \"#{q}\""
  239. end
  240. case q[r]
  241. when ?",?\\,?/,?'
  242. a[w] = q[r]
  243. r += 1
  244. w += 1
  245. when ?b,?f,?n,?r,?t
  246. a[w] = Unesc[q[r]]
  247. r += 1
  248. w += 1
  249. when ?u
  250. r += 1
  251. uchar = begin
  252. hexdec4(q[r,4])
  253. rescue RuntimeError => e
  254. raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
  255. end
  256. r += 4
  257. if surrogate? uchar
  258. if q.length >= r+6
  259. uchar1 = hexdec4(q[r+2,4])
  260. uchar = subst(uchar, uchar1)
  261. if uchar != Ucharerr
  262. # A valid pair; consume.
  263. r += 6
  264. end
  265. end
  266. end
  267. if rubydoesenc
  268. a[w] = '' << uchar
  269. w += 1
  270. else
  271. w += ucharenc(a, w, uchar)
  272. end
  273. else
  274. raise Error, "invalid escape char #{q[r]} in \"#{q}\""
  275. end
  276. when c == ?", c < Spc
  277. raise Error, "invalid character in string literal \"#{q}\""
  278. else
  279. # Copy anything else byte-for-byte.
  280. # Valid UTF-8 will remain valid UTF-8.
  281. # Invalid UTF-8 will remain invalid UTF-8.
  282. # In ruby >= 1.9, c is a codepoint, not a byte,
  283. # in which case this is still what we want.
  284. a[w] = c
  285. r += 1
  286. w += 1
  287. end
  288. end
  289. a[0,w]
  290. end
  291. # Encodes unicode character u as UTF-8
  292. # bytes in string a at position i.
  293. # Returns the number of bytes written.
  294. def ucharenc(a, i, u)
  295. case true
  296. when u <= Uchar1max
  297. a[i] = (u & 0xff).chr
  298. 1
  299. when u <= Uchar2max
  300. a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
  301. a[i+1] = (Utagx | (u&Umaskx)).chr
  302. 2
  303. when u <= Uchar3max
  304. a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
  305. a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
  306. a[i+2] = (Utagx | (u&Umaskx)).chr
  307. 3
  308. else
  309. a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
  310. a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
  311. a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
  312. a[i+3] = (Utagx | (u&Umaskx)).chr
  313. 4
  314. end
  315. end
  316. def hexdec4(s)
  317. if s.length != 4
  318. raise Error, 'short'
  319. end
  320. (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
  321. end
  322. def subst(u1, u2)
  323. if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
  324. return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
  325. end
  326. return Ucharerr
  327. end
  328. def surrogate?(u)
  329. Usurr1 <= u && u < Usurr3
  330. end
  331. def nibble(c)
  332. case true
  333. when ?0 <= c && c <= ?9 then c.ord - ?0.ord
  334. when ?a <= c && c <= ?z then c.ord - ?a.ord + 10
  335. when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
  336. else
  337. raise Error, "invalid hex code #{c}"
  338. end
  339. end
  340. # Encodes x into a json text. It may contain only
  341. # Array, Hash, String, Numeric, true, false, nil.
  342. # (Note, this list excludes Symbol.)
  343. # X itself must be an Array or a Hash.
  344. # No other value can be encoded, and an error will
  345. # be raised if x contains any other value, such as
  346. # Nan, Infinity, Symbol, and Proc, or if a Hash key
  347. # is not a String.
  348. # Strings contained in x must be valid UTF-8.
  349. def encode(x)
  350. case x
  351. when Hash then objenc(x)
  352. when Array then arrenc(x)
  353. else
  354. raise Error, 'root value must be an Array or a Hash'
  355. end
  356. end
  357. def valenc(x)
  358. case x
  359. when Hash then objenc(x)
  360. when Array then arrenc(x)
  361. when String then strenc(x)
  362. when Numeric then numenc(x)
  363. when true then "true"
  364. when false then "false"
  365. when nil then "null"
  366. else
  367. raise Error, "cannot encode #{x.class}: #{x.inspect}"
  368. end
  369. end
  370. def objenc(x)
  371. '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
  372. end
  373. def arrenc(a)
  374. '[' + a.map{|x| valenc(x)}.join(',') + ']'
  375. end
  376. def keyenc(k)
  377. case k
  378. when String then strenc(k)
  379. else
  380. raise Error, "Hash key is not a string: #{k.inspect}"
  381. end
  382. end
  383. def strenc(s)
  384. t = StringIO.new
  385. t.putc(?")
  386. r = 0
  387. # In ruby >= 1.9, s[r] is a codepoint, not a byte.
  388. rubydoesenc = s.class.method_defined?(:encoding)
  389. while r < s.length
  390. case s[r]
  391. when ?" then t.print('\\"')
  392. when ?\\ then t.print('\\\\')
  393. when ?\b then t.print('\\b')
  394. when ?\f then t.print('\\f')
  395. when ?\n then t.print('\\n')
  396. when ?\r then t.print('\\r')
  397. when ?\t then t.print('\\t')
  398. else
  399. c = s[r]
  400. case true
  401. when rubydoesenc
  402. begin
  403. c.ord # will raise an error if c is invalid UTF-8
  404. t.write(c)
  405. rescue
  406. t.write(Ustrerr)
  407. end
  408. when Spc <= c && c <= ?~
  409. t.putc(c)
  410. else
  411. n = ucharcopy(t, s, r) # ensure valid UTF-8 output
  412. r += n - 1 # r is incremented below
  413. end
  414. end
  415. r += 1
  416. end
  417. t.putc(?")
  418. t.string
  419. end
  420. def numenc(x)
  421. if ((x.nan? || x.infinite?) rescue false)
  422. raise Error, "Numeric cannot be represented: #{x}"
  423. end
  424. "#{x}"
  425. end
  426. # Copies the valid UTF-8 bytes of a single character
  427. # from string s at position i to I/O object t, and
  428. # returns the number of bytes copied.
  429. # If no valid UTF-8 char exists at position i,
  430. # ucharcopy writes Ustrerr and returns 1.
  431. def ucharcopy(t, s, i)
  432. n = s.length - i
  433. raise Utf8Error if n < 1
  434. c0 = s[i].ord
  435. # 1-byte, 7-bit sequence?
  436. if c0 < Utagx
  437. t.putc(c0)
  438. return 1
  439. end
  440. raise Utf8Error if c0 < Utag2 # unexpected continuation byte?
  441. raise Utf8Error if n < 2 # need continuation byte
  442. c1 = s[i+1].ord
  443. raise Utf8Error if c1 < Utagx || Utag2 <= c1
  444. # 2-byte, 11-bit sequence?
  445. if c0 < Utag3
  446. raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
  447. t.putc(c0)
  448. t.putc(c1)
  449. return 2
  450. end
  451. # need second continuation byte
  452. raise Utf8Error if n < 3
  453. c2 = s[i+2].ord
  454. raise Utf8Error if c2 < Utagx || Utag2 <= c2
  455. # 3-byte, 16-bit sequence?
  456. if c0 < Utag4
  457. u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
  458. raise Utf8Error if u <= Uchar2max
  459. t.putc(c0)
  460. t.putc(c1)
  461. t.putc(c2)
  462. return 3
  463. end
  464. # need third continuation byte
  465. raise Utf8Error if n < 4
  466. c3 = s[i+3].ord
  467. raise Utf8Error if c3 < Utagx || Utag2 <= c3
  468. # 4-byte, 21-bit sequence?
  469. if c0 < Utag5
  470. u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
  471. raise Utf8Error if u <= Uchar3max
  472. t.putc(c0)
  473. t.putc(c1)
  474. t.putc(c2)
  475. t.putc(c3)
  476. return 4
  477. end
  478. raise Utf8Error
  479. rescue Utf8Error
  480. t.write(Ustrerr)
  481. return 1
  482. end
  483. class Utf8Error < ::StandardError
  484. end
  485. class Error < ::StandardError
  486. end
  487. Utagx = 0x80 # 1000 0000
  488. Utag2 = 0xc0 # 1100 0000
  489. Utag3 = 0xe0 # 1110 0000
  490. Utag4 = 0xf0 # 1111 0000
  491. Utag5 = 0xF8 # 1111 1000
  492. Umaskx = 0x3f # 0011 1111
  493. Umask2 = 0x1f # 0001 1111
  494. Umask3 = 0x0f # 0000 1111
  495. Umask4 = 0x07 # 0000 0111
  496. Uchar1max = (1<<7) - 1
  497. Uchar2max = (1<<11) - 1
  498. Uchar3max = (1<<16) - 1
  499. Ucharerr = 0xFFFD # unicode "replacement char"
  500. Ustrerr = "\xef\xbf\xbd" # unicode "replacement char"
  501. Usurrself = 0x10000
  502. Usurr1 = 0xd800
  503. Usurr2 = 0xdc00
  504. Usurr3 = 0xe000
  505. Spc = ' '[0]
  506. Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
  507. end