RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
[VXA] JSON Encoder/Decoder

0 Members and 1 Guest are viewing this topic.

***
Rep:
Level 84
Yes, hoh my gawd!
JSON Encoder/Decoder
Authors: game_guy
Version: 1.1
Type: Script Utility

Introduction

Quote
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. 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.

Screenshots

N/A

Demo

No demo.

Script

Spoiler for:
Code: [Select]
#===============================================================================
# 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

Instructions

Its 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 for JSON Decode Example:
Code: [Select]
JSON.decode(json)
Returns any of the following depending on "json":
-Integer
-String
-Boolean
-Hash
-Array
-Nil

Example:
Code: [Select]
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
Code: [Select]
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 for JSON Encode Example:
This can encode the following Ruby objects into JSON format.
Code: [Select]
Integer
Boolean
String
Hash
Array
Nil
Here's your input.
Code: [Select]
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
Code: [Select]
'{"result":true,"profile":{"id":23,"display_name":"game_guy","group":{"id":"1","name":"Administrator","color":"#FF0000"}},"array":[0,1,2,3]}'

Compatibility

Should work with anything.

Credits and Thanks

  • game_guy ~ For creating it.

Author's Notes

Enjoy! :) 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.
« Last Edit: February 28, 2012, 02:55:20 AM by game_guy »

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Most Mature Member2012 Favorite Staff Member2012 Best RPG Maker User (Scripting)2012 Best MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
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.

***
Rep:
Level 84
Yes, hoh my gawd!
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.