class Hub::JSON

Stupid pure Ruby JSON parser.

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/hub/json.rb, line 21
def initialize data
  @scanner = StringScanner.new data.to_s
end
parse(data) click to toggle source
# File lib/hub/json.rb, line 6
def self.parse(data) new(data).parse end

Public Instance Methods

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

Private Instance Methods

array() click to toggle source
# File lib/hub/json.rb, line 55
def array
  ary = []
  space
  repeat_until(AEN) { ary << value; endkey }
  ary
end
endkey() click to toggle source
# File lib/hub/json.rb, line 34
def endkey() scan(KEY) or space end
error() click to toggle source
# File lib/hub/json.rb, line 86
def error
  raise "parse error at: #{scan(/.{1,10}/m).inspect}"
end
hash() click to toggle source
# File lib/hub/json.rb, line 48
def hash
  obj = {}
  space
  repeat_until(HEN) { k = string; scan(COL); obj[k] = value; endkey }
  obj
end
object() click to toggle source
# File lib/hub/json.rb, line 36
def object
  matched == '{' ? hash : array if scan(OBJ)
end
repeat_until(reg) { || ... } click to toggle source
# File lib/hub/json.rb, line 90
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/hub/json.rb, line 32
def space() scan WSP end
string() click to toggle source
# File lib/hub/json.rb, line 67
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/hub/json.rb, line 40
def value
  object or string or
    scan(NUL) ? nil :
    scan(BOL) ? matched.size == 4:
    scan(NUM) ? eval(matched) :
    error
end