#===============================================================================
# JSON Encoder/Decoder
# Version 1.1
# Author: game_guy
#-------------------------------------------------------------------------------
# Intro:
# JSON (JavaScript Object Notation) is a lightweight data-interchange
# format. It is easy for humans to read and write. It is easy for machines to
# parse and generate.
# This is a simple JSON Parser or Decoder. It'll take JSON thats been
# formatted into a string and decode it into the proper object.
# This script can also encode certain ruby objects into JSON.
#
# Features:
# Decodes JSON format into ruby strings, arrays, hashes, integers, booleans.
#
# Instructions:
# This is a scripters utility. To decode JSON data, call
# JSON.decode("json string")
# -Depending on "json string", this method can return any of the values:
# -Integer
# -String
# -Boolean
# -Hash
# -Array
# -Nil
#
# To Encode objects, use
# JSON.encode(object)
# -This will return a string with JSON. Object can be any one of the following
# -Integer
# -String
# -Boolean
# -Hash
# -Array
# -Nil
#
# Credits:
# game_guy ~ Creating it.
#===============================================================================
module JSON
TOKEN_NONE = 0;
TOKEN_CURLY_OPEN = 1;
TOKEN_CURLY_CLOSED = 2;
TOKEN_SQUARED_OPEN = 3;
TOKEN_SQUARED_CLOSED = 4;
TOKEN_COLON = 5;
TOKEN_COMMA = 6;
TOKEN_STRING = 7;
TOKEN_NUMBER = 8;
TOKEN_TRUE = 9;
TOKEN_FALSE = 10;
TOKEN_NULL = 11;
@index = 0
@json = ""
@length = 0
def self.decode(json)
@json = json
@index = 0
@length = @json.length
return self.parse
end
def self.encode(obj)
if obj.is_a?(Hash)
return self.encode_hash(obj)
elsif obj.is_a?(Array)
return self.encode_array(obj)
elsif obj.is_a?(Fixnum) || obj.is_a?(Float)
return self.encode_integer(obj)
elsif obj.is_a?(String)
return self.encode_string(obj)
elsif obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
return self.encode_bool(obj)
elsif obj.is_a?(NilClass)
return "null"
end
return nil
end
def self.encode_hash(hash)
string = "{"
hash.each_key {|key|
string += "\"#{key}\":" + self.encode(hash[key]).to_s + ","
}
string[string.size - 1, 1] = "}"
return string
end
def self.encode_array(array)
string = "["
array.each {|i|
string += self.encode(i).to_s + ","
}
string[string.size - 1, 1] = "]"
return string
end
def self.encode_string(string)
return "\"#{string}\""
end
def self.encode_integer(int)
return int.to_s
end
def self.encode_bool(bool)
return (bool.is_a?(TrueClass) ? "true" : "false")
end
def self.next_token(debug = 0)
char = @json[@index, 1]
@index += 1
case char
when '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-'
return TOKEN_NUMBER
when '{'
return TOKEN_CURLY_OPEN
when '}'
return TOKEN_CURLY_CLOSED
when '"'
return TOKEN_STRING
when ','
return TOKEN_COMMA
when '['
return TOKEN_SQUARED_OPEN
when ']'
return TOKEN_SQUARED_CLOSED
when ':'
return TOKEN_COLON
end
@index -= 1
if @json[@index, 5] == "false"
@index += 5
return TOKEN_FALSE
elsif @json[@index, 4] == "true"
@index += 4
return TOKEN_TRUE
elsif @json[@index, 4] == "null"
@index += 4
return TOKEN_NULL
end
return TOKEN_NONE
end
def self.parse(debug = 0)
complete = false
while !complete
if @index >= @length
break
end
token = self.next_token
case token
when TOKEN_NONE
return nil
when TOKEN_NUMBER
return self.parse_number
when TOKEN_CURLY_OPEN
return self.parse_object
when TOKEN_STRING
return self.parse_string
when TOKEN_SQUARED_OPEN
return self.parse_array
when TOKEN_TRUE
return true
when TOKEN_FALSE
return false
when TOKEN_NULL
return nil
end
end
end
def self.parse_object
obj = {}
complete = false
while !complete
token = self.next_token
if token == TOKEN_CURLY_CLOSED
complete = true
break
elsif token == TOKEN_NONE
return nil
elsif token == TOKEN_COMMA
else
name = self.parse_string
return nil if name == nil
token = self.next_token
return nil if token != TOKEN_COLON
value = self.parse
obj[name] = value
end
end
return obj
end
def self.parse_string
complete = false
string = ""
while !complete
break if @index >= @length
char = @json[@index, 1]
@index += 1
case char
when '"'
complete = true
break
else
string += char.to_s
end
end
if !complete
return nil
end
return string
end
def self.parse_number
@index -= 1
negative = @json[@index, 1] == "-" ? true : false
string = ""
complete = false
while !complete
break if @index >= @length
char = @json[@index, 1]
@index += 1
case char
when "{", "}", ":", ",", "[", "]"
@index -= 1
complete = true
break
when "0", "1", "2", '3', '4', '5', '6', '7', '8', '9'
string += char.to_s
end
end
return string.to_i
end
def self.parse_array
obj = []
complete = false
while !complete
token = self.next_token(1)
if token == TOKEN_SQUARED_CLOSED
complete = true
break
elsif token == TOKEN_NONE
return nil
elsif token == TOKEN_COMMA
else
@index -= 1
value = self.parse
obj.push(value)
end
end
return obj
end
end