JSON Encoder/Decoder
Authors: game_guy
Version: 1.1
Type: Script Utility
IntroductionQuoteJSON (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. You can also encode certain Ruby objects into JSON.
This is a scripter's utility and isn't meant to add any new functionality or prove usefulness to non-scripters.
Features
- Decodes JSON format into ruby strings, arrays, hashes, integers, booleans.
- Encodes Ruby objects into JSON format.
ScreenshotsN/A
DemoNo demo.
Script[SPOILER]
#===============================================================================
# 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
[/SPOILER]
InstructionsIts recommended to place this script at the top, then it can be used in any script below it. To call the parsing method, use
[spoiler=JSON Decode Example]
JSON.decode(json)
Returns any of the following depending on "json":
-Integer
-String
-Boolean
-Hash
-Array
-NilExample:
json = '{"result":true,"profile":{"id":23,"display_name":"game_guy","group":{"id":"1","name":"Administrator","color":"#FF0000"}},"array":[0,1,2,3]}'
data = JSON.decode(json)Output
data = {'result' => true, 'profile' => {'id' => 23, 'display_name' => 'game_guy', 'group' => {'id' => 1, 'name' => 'Administrator', 'color' => '#FF0000'}}, 'array' => [0, 1, 2, 3]}As you can see, it supports multi-level hashes and the method returned a hash object since the string started with a "{". The first character is what defines what object its going to return.[/spoiler]
[spoiler=JSON Encode Example]This can encode the following Ruby objects into JSON format.
Integer
Boolean
String
Hash
Array
NilHere's your input.
data = {'result' => true, 'profile' => {'id' => 23, 'display_name' => 'game_guy', 'group' => {'id' => 1, 'name' => 'Administrator', 'color' => '#FF0000'}}, 'array' => [0, 1, 2, 3]}
json = JSON.encode(data)Output
'{"result":true,"profile":{"id":23,"display_name":"game_guy","group":{"id":"1","name":"Administrator","color":"#FF0000"}},"array":[0,1,2,3]}'[/spoiler]
CompatibilityShould work with anything.
Credits and Thanks
- game_guy ~ For creating it.
Author's NotesEnjoy! :) You guys are lucky that VX Ace uses Ruby 1.9, or else this script wouldn't have been released. With the example code I posted, it takes a few seconds for Ruby 1.8 to parse it all.
Seems like it could be pretty neat!
P.S. I don't know what this says about my character, but I've always wanted to write a script that started with "J", but have never been able to do so. It, "X", "Y", and "Z" have all proven elusive.
Ha, thanks! You might wanna update the Script Index, I changed the name and updated to 1.1. I added the encoder implementation. Whats great about JSON is that its data easily readable by humans and there are several languages that have an encoder/decoder. Its essentially cross-language way to serialize data.
And maybe to toss an idea out, if you wanted to create a script that started with a Y, you could create a YAML Encoder/Decoder.