class PhusionPassenger::Utils::JSON

Usage:

JSON.parse(json_string) => Array/Hash
JSON.generate(object)   => json string

Run tests by executing this file directly. Pipe standard input to the script to have it parsed as JSON and to display the result in Ruby.

Constants

AEN
BOL
CODE
COL
ESC
HEN
KEY
NUL
NUM
OBJ
SPEC
STE
STR
UNI
WSP

Attributes

s[R]
scanner[R]

Public Class Methods

new(data) click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 57
def initialize data
  @scanner = StringScanner.new data.to_s
end
parse(data) click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 42
def self.parse(data) new(data).parse end

Public Instance Methods

parse() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 61
def parse
  space
  object
end

Private Instance Methods

array() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 91
def array
  ary = []
  space
  repeat_until(AEN) { ary << value; endkey }
  ary
end
endkey() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 70
def endkey() scan(KEY) or space end
error() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 122
def error
  raise "parse error at: #{scan(/.{1,10}/m).inspect}"
end
hash() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 84
def hash
  obj = {}
  space
  repeat_until(HEN) { k = string; scan(COL); obj[k] = value; endkey }
  obj
end
object() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 72
def object
  matched == '{' ? hash : array if scan(OBJ)
end
repeat_until(reg) { || ... } click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 126
def repeat_until reg
  until scan(reg)
    pos = s.pos
    yield
    error unless s.pos > pos
  end
end
space() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 68
def space() scan WSP end
string() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 103
def string
  if scan(STR)
    str, esc = '', false
    while c = s.getch
      if esc
        str << (c == UNI ? (s.scan(CODE) || error).to_i(16).chr : SPEC[c] || c)
        esc = false
      else
        case c
        when ESC then esc = true
        when STE then break
        else str << c
        end
      end
    end
    str
  end
end
value() click to toggle source
# File lib/phusion_passenger/utils/json.rb, line 76
def value
  object or string or
    scan(NUL) ? nil :
    scan(BOL) ? matched.size == 4:
    scan(NUM) ? eval(matched) :
    error
end