summaryrefslogtreecommitdiff
path: root/trunk/ext/json/lib/json
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ext/json/lib/json')
-rw-r--r--trunk/ext/json/lib/json/Array.xpm21
-rw-r--r--trunk/ext/json/lib/json/FalseClass.xpm21
-rw-r--r--trunk/ext/json/lib/json/Hash.xpm21
-rw-r--r--trunk/ext/json/lib/json/Key.xpm73
-rw-r--r--trunk/ext/json/lib/json/NilClass.xpm21
-rw-r--r--trunk/ext/json/lib/json/Numeric.xpm28
-rw-r--r--trunk/ext/json/lib/json/String.xpm96
-rw-r--r--trunk/ext/json/lib/json/TrueClass.xpm21
-rw-r--r--trunk/ext/json/lib/json/add/core.rb120
-rw-r--r--trunk/ext/json/lib/json/add/rails.rb58
-rw-r--r--trunk/ext/json/lib/json/common.rb354
-rw-r--r--trunk/ext/json/lib/json/editor.rb1363
-rw-r--r--trunk/ext/json/lib/json/ext.rb13
-rw-r--r--trunk/ext/json/lib/json/json.xpm1499
-rw-r--r--trunk/ext/json/lib/json/pure.rb75
-rw-r--r--trunk/ext/json/lib/json/pure/generator.rb394
-rw-r--r--trunk/ext/json/lib/json/pure/parser.rb260
-rw-r--r--trunk/ext/json/lib/json/version.rb9
18 files changed, 0 insertions, 4447 deletions
diff --git a/trunk/ext/json/lib/json/Array.xpm b/trunk/ext/json/lib/json/Array.xpm
deleted file mode 100644
index 27c48011f9..0000000000
--- a/trunk/ext/json/lib/json/Array.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * Array_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" .......... ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" .......... ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/FalseClass.xpm b/trunk/ext/json/lib/json/FalseClass.xpm
deleted file mode 100644
index 25ce60832d..0000000000
--- a/trunk/ext/json/lib/json/FalseClass.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * False_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #FF0000",
-" ",
-" ",
-" ",
-" ...... ",
-" . ",
-" . ",
-" . ",
-" ...... ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/Hash.xpm b/trunk/ext/json/lib/json/Hash.xpm
deleted file mode 100644
index cd8f6f7b53..0000000000
--- a/trunk/ext/json/lib/json/Hash.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * Hash_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" . . ",
-" . . ",
-" . . ",
-" ......... ",
-" . . ",
-" . . ",
-" ......... ",
-" . . ",
-" . . ",
-" . . ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/Key.xpm b/trunk/ext/json/lib/json/Key.xpm
deleted file mode 100644
index 9fd7281388..0000000000
--- a/trunk/ext/json/lib/json/Key.xpm
+++ /dev/null
@@ -1,73 +0,0 @@
-/* XPM */
-static char * Key_xpm[] = {
-"16 16 54 1",
-" c None",
-". c #110007",
-"+ c #0E0900",
-"@ c #000013",
-"# c #070600",
-"$ c #F6F006",
-"% c #ECE711",
-"& c #E5EE00",
-"* c #16021E",
-"= c #120900",
-"- c #EDF12B",
-"; c #000033",
-"> c #0F0000",
-", c #FFFE03",
-"' c #E6E500",
-") c #16021B",
-"! c #F7F502",
-"~ c #000E00",
-"{ c #130000",
-"] c #FFF000",
-"^ c #FFE711",
-"/ c #140005",
-"( c #190025",
-"_ c #E9DD27",
-": c #E7DC04",
-"< c #FFEC09",
-"[ c #FFE707",
-"} c #FFDE10",
-"| c #150021",
-"1 c #160700",
-"2 c #FAF60E",
-"3 c #EFE301",
-"4 c #FEF300",
-"5 c #E7E000",
-"6 c #FFFF08",
-"7 c #0E0206",
-"8 c #040000",
-"9 c #03052E",
-"0 c #041212",
-"a c #070300",
-"b c #F2E713",
-"c c #F9DE13",
-"d c #36091E",
-"e c #00001C",
-"f c #1F0010",
-"g c #FFF500",
-"h c #DEDE00",
-"i c #050A00",
-"j c #FAF14A",
-"k c #F5F200",
-"l c #040404",
-"m c #1A0D00",
-"n c #EDE43D",
-"o c #ECE007",
-" ",
-" ",
-" .+@ ",
-" #$%&* ",
-" =-;>,') ",
-" >!~{]^/ ",
-" (_:<[}| ",
-" 1234567 ",
-" 890abcd ",
-" efghi ",
-" >jkl ",
-" mnol ",
-" >kl ",
-" ll ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/NilClass.xpm b/trunk/ext/json/lib/json/NilClass.xpm
deleted file mode 100644
index 3509f06c99..0000000000
--- a/trunk/ext/json/lib/json/NilClass.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * False_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" ... ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" ... ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/Numeric.xpm b/trunk/ext/json/lib/json/Numeric.xpm
deleted file mode 100644
index e071e2ee9c..0000000000
--- a/trunk/ext/json/lib/json/Numeric.xpm
+++ /dev/null
@@ -1,28 +0,0 @@
-/* XPM */
-static char * Numeric_xpm[] = {
-"16 16 9 1",
-" c None",
-". c #FF0000",
-"+ c #0000FF",
-"@ c #0023DB",
-"# c #00EA14",
-"$ c #00FF00",
-"% c #004FAF",
-"& c #0028D6",
-"* c #00F20C",
-" ",
-" ",
-" ",
-" ... +++@#$$$$ ",
-" .+ %& $$ ",
-" . + $ ",
-" . + $$ ",
-" . ++$$$$ ",
-" . + $$ ",
-" . + $ ",
-" . + $ ",
-" . + $ $$ ",
-" .....++++*$$ ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/String.xpm b/trunk/ext/json/lib/json/String.xpm
deleted file mode 100644
index f79a89cdc1..0000000000
--- a/trunk/ext/json/lib/json/String.xpm
+++ /dev/null
@@ -1,96 +0,0 @@
-/* XPM */
-static char * String_xpm[] = {
-"16 16 77 1",
-" c None",
-". c #000000",
-"+ c #040404",
-"@ c #080806",
-"# c #090606",
-"$ c #EEEAE1",
-"% c #E7E3DA",
-"& c #E0DBD1",
-"* c #D4B46F",
-"= c #0C0906",
-"- c #E3C072",
-"; c #E4C072",
-"> c #060505",
-", c #0B0A08",
-"' c #D5B264",
-") c #D3AF5A",
-"! c #080602",
-"~ c #E1B863",
-"{ c #DDB151",
-"] c #DBAE4A",
-"^ c #DDB152",
-"/ c #DDB252",
-"( c #070705",
-"_ c #0C0A07",
-": c #D3A33B",
-"< c #020201",
-"[ c #DAAA41",
-"} c #040302",
-"| c #E4D9BF",
-"1 c #0B0907",
-"2 c #030201",
-"3 c #020200",
-"4 c #C99115",
-"5 c #080704",
-"6 c #DBC8A2",
-"7 c #E7D7B4",
-"8 c #E0CD9E",
-"9 c #080601",
-"0 c #040400",
-"a c #010100",
-"b c #0B0B08",
-"c c #DCBF83",
-"d c #DCBC75",
-"e c #DEB559",
-"f c #040301",
-"g c #BC8815",
-"h c #120E07",
-"i c #060402",
-"j c #0A0804",
-"k c #D4A747",
-"l c #D6A12F",
-"m c #0E0C05",
-"n c #C8C1B0",
-"o c #1D1B15",
-"p c #D7AD51",
-"q c #070502",
-"r c #080804",
-"s c #BC953B",
-"t c #C4BDAD",
-"u c #0B0807",
-"v c #DBAC47",
-"w c #1B150A",
-"x c #B78A2C",
-"y c #D8A83C",
-"z c #D4A338",
-"A c #0F0B03",
-"B c #181105",
-"C c #C59325",
-"D c #C18E1F",
-"E c #060600",
-"F c #CC992D",
-"G c #B98B25",
-"H c #B3831F",
-"I c #C08C1C",
-"J c #060500",
-"K c #0E0C03",
-"L c #0D0A00",
-" ",
-" .+@# ",
-" .$%&*= ",
-" .-;>,')! ",
-" .~. .{]. ",
-" .^/. (_:< ",
-" .[.}|$12 ",
-" 345678}90 ",
-" a2bcdefgh ",
-" ijkl.mno ",
-" <pq. rstu ",
-" .]v. wx= ",
-" .yzABCDE ",
-" .FGHIJ ",
-" 0KL0 ",
-" "};
diff --git a/trunk/ext/json/lib/json/TrueClass.xpm b/trunk/ext/json/lib/json/TrueClass.xpm
deleted file mode 100644
index 143eef49bb..0000000000
--- a/trunk/ext/json/lib/json/TrueClass.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * TrueClass_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #0BF311",
-" ",
-" ",
-" ",
-" ......... ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" . ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/add/core.rb b/trunk/ext/json/lib/json/add/core.rb
deleted file mode 100644
index 630ed6e4b7..0000000000
--- a/trunk/ext/json/lib/json/add/core.rb
+++ /dev/null
@@ -1,120 +0,0 @@
-# This file contains implementations of ruby core's custom objects for
-# serialisation/deserialisation.
-
-unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
- ::JSON::JSON_LOADED
- require 'json'
-end
-require 'date'
-
-class Time
- def self.json_create(object)
- at(*object.values_at('s', 'u'))
- end
-
- def to_json(*args)
- {
- 'json_class' => self.class.name.to_s,
- 's' => tv_sec,
- 'u' => tv_usec,
- }.to_json(*args)
- end
-end
-
-class Date
- def self.json_create(object)
- civil(*object.values_at('y', 'm', 'd', 'sg'))
- end
-
- def to_json(*args)
- {
- 'json_class' => self.class.name.to_s,
- 'y' => year,
- 'm' => month,
- 'd' => day,
- 'sg' => @sg,
- }.to_json(*args)
- end
-end
-
-class DateTime
- def self.json_create(object)
- args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
- of_a, of_b = object['of'].split('/')
- args << Rational(of_a.to_i, of_b.to_i)
- args << object['sg']
- civil(*args)
- end
-
- def to_json(*args)
- {
- 'json_class' => self.class.name.to_s,
- 'y' => year,
- 'm' => month,
- 'd' => day,
- 'H' => hour,
- 'M' => min,
- 'S' => sec,
- 'of' => offset.to_s,
- 'sg' => @sg,
- }.to_json(*args)
- end
-end
-
-class Range
- def self.json_create(object)
- new(*object['a'])
- end
-
- def to_json(*args)
- {
- 'json_class' => self.class.name.to_s,
- 'a' => [ first, last, exclude_end? ]
- }.to_json(*args)
- end
-end
-
-class Struct
- def self.json_create(object)
- new(*object['v'])
- end
-
- def to_json(*args)
- klass = self.class.name.to_s
- klass.empty? and raise JSON::JSONError, "Only named structs are supported!"
- {
- 'json_class' => klass,
- 'v' => values,
- }.to_json(*args)
- end
-end
-
-class Exception
- def self.json_create(object)
- result = new(object['m'])
- result.set_backtrace object['b']
- result
- end
-
- def to_json(*args)
- {
- 'json_class' => self.class.name.to_s,
- 'm' => message,
- 'b' => backtrace,
- }.to_json(*args)
- end
-end
-
-class Regexp
- def self.json_create(object)
- new(object['s'], object['o'])
- end
-
- def to_json(*)
- {
- 'json_class' => self.class.name.to_s,
- 'o' => options,
- 's' => source,
- }.to_json
- end
-end
diff --git a/trunk/ext/json/lib/json/add/rails.rb b/trunk/ext/json/lib/json/add/rails.rb
deleted file mode 100644
index e86ed1aab9..0000000000
--- a/trunk/ext/json/lib/json/add/rails.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file contains implementations of rails custom objects for
-# serialisation/deserialisation.
-
-unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
- ::JSON::JSON_LOADED
- require 'json'
-end
-
-class Object
- def self.json_create(object)
- obj = new
- for key, value in object
- next if key == 'json_class'
- instance_variable_set "@#{key}", value
- end
- obj
- end
-
- def to_json(*a)
- result = {
- 'json_class' => self.class.name
- }
- instance_variables.inject(result) do |r, name|
- r[name[1..-1]] = instance_variable_get name
- r
- end
- result.to_json(*a)
- end
-end
-
-class Symbol
- def to_json(*a)
- to_s.to_json(*a)
- end
-end
-
-module Enumerable
- def to_json(*a)
- to_a.to_json(*a)
- end
-end
-
-# class Regexp
-# def to_json(*)
-# inspect
-# end
-# end
-#
-# The above rails definition has some problems:
-#
-# 1. { 'foo' => /bar/ }.to_json # => "{foo: /bar/}"
-# This isn't valid JSON, because the regular expression syntax is not
-# defined in RFC 4627. (And unquoted strings are disallowed there, too.)
-# Though it is valid Javascript.
-#
-# 2. { 'foo' => /bar/mix }.to_json # => "{foo: /bar/mix}"
-# This isn't even valid Javascript.
-
diff --git a/trunk/ext/json/lib/json/common.rb b/trunk/ext/json/lib/json/common.rb
deleted file mode 100644
index 7bc5ae0656..0000000000
--- a/trunk/ext/json/lib/json/common.rb
+++ /dev/null
@@ -1,354 +0,0 @@
-require 'json/version'
-
-module JSON
- class << self
- # If _object_ is string like parse the string and return the parsed result
- # as a Ruby data structure. Otherwise generate a JSON text from the Ruby
- # data structure object and return it.
- #
- # The _opts_ argument is passed through to generate/parse respectively, see
- # generate and parse for their documentation.
- def [](object, opts = {})
- if object.respond_to? :to_str
- JSON.parse(object.to_str, opts => {})
- else
- JSON.generate(object, opts => {})
- end
- end
-
- # Returns the JSON parser class, that is used by JSON. This might be either
- # JSON::Ext::Parser or JSON::Pure::Parser.
- attr_reader :parser
-
- # Set the JSON parser class _parser_ to be used by JSON.
- def parser=(parser) # :nodoc:
- @parser = parser
- remove_const :Parser if const_defined? :Parser
- const_set :Parser, parser
- end
-
- # Return the constant located at _path_. The format of _path_ has to be
- # either ::A::B::C or A::B::C. In any case A has to be located at the top
- # level (absolute namespace path?). If there doesn't exist a constant at
- # the given path, an ArgumentError is raised.
- def deep_const_get(path) # :nodoc:
- path = path.to_s
- path.split(/::/).inject(Object) do |p, c|
- case
- when c.empty? then p
- when p.const_defined?(c) then p.const_get(c)
- else raise ArgumentError, "can't find const #{path}"
- end
- end
- end
-
- # Set the module _generator_ to be used by JSON.
- def generator=(generator) # :nodoc:
- @generator = generator
- generator_methods = generator::GeneratorMethods
- for const in generator_methods.constants
- klass = deep_const_get(const)
- modul = generator_methods.const_get(const)
- klass.class_eval do
- instance_methods(false).each do |m|
- m.to_s == 'to_json' and remove_method m
- end
- include modul
- end
- end
- self.state = generator::State
- const_set :State, self.state
- end
-
- # Returns the JSON generator modul, that is used by JSON. This might be
- # either JSON::Ext::Generator or JSON::Pure::Generator.
- attr_reader :generator
-
- # Returns the JSON generator state class, that is used by JSON. This might
- # be either JSON::Ext::Generator::State or JSON::Pure::Generator::State.
- attr_accessor :state
-
- # This is create identifier, that is used to decide, if the _json_create_
- # hook of a class should be called. It defaults to 'json_class'.
- attr_accessor :create_id
- end
- self.create_id = 'json_class'
-
- NaN = (-1.0) ** 0.5
-
- Infinity = 1.0/0
-
- MinusInfinity = -Infinity
-
- # The base exception for JSON errors.
- class JSONError < StandardError; end
-
- # This exception is raised, if a parser error occurs.
- class ParserError < JSONError; end
-
- # This exception is raised, if the nesting of parsed datastructures is too
- # deep.
- class NestingError < ParserError; end
-
- # This exception is raised, if a generator or unparser error occurs.
- class GeneratorError < JSONError; end
- # For backwards compatibility
- UnparserError = GeneratorError
-
- # If a circular data structure is encountered while unparsing
- # this exception is raised.
- class CircularDatastructure < GeneratorError; end
-
- # This exception is raised, if the required unicode support is missing on the
- # system. Usually this means, that the iconv library is not installed.
- class MissingUnicodeSupport < JSONError; end
-
- module_function
-
- # Parse the JSON string _source_ into a Ruby data structure and return it.
- #
- # _opts_ can have the following
- # keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Disable depth checking with :max_nesting => false, it defaults
- # to 19.
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to false.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- def parse(source, opts = {})
- JSON.parser.new(source, opts).parse
- end
-
- # Parse the JSON string _source_ into a Ruby data structure and return it.
- # The bang version of the parse method, defaults to the more dangerous values
- # for the _opts_ hash, so be sure only to parse trusted _source_ strings.
- #
- # _opts_ can have the following keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Enable depth checking with :max_nesting => anInteger. The parse!
- # methods defaults to not doing max depth checking: This can be dangerous,
- # if someone wants to fill up your stack.
- # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to true.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- def parse!(source, opts = {})
- opts = {
- :max_nesting => false,
- :allow_nan => true
- }.update(opts)
- JSON.parser.new(source, opts).parse
- end
-
- # Unparse the Ruby data structure _obj_ into a single line JSON string and
- # return it. _state_ is
- # * a JSON::State object,
- # * or a Hash like object (responding to to_hash),
- # * an object convertible into a hash by a to_h method,
- # that is used as or to configure a State object.
- #
- # It defaults to a state object, that creates the shortest possible JSON text
- # in one line, checks for circular data structures and doesn't allow NaN,
- # Infinity, and -Infinity.
- #
- # A _state_ hash can have the following keys:
- # * *indent*: a string used to indent levels (default: ''),
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
- # * *check_circular*: true if checking for circular data structures
- # should be done (the default), false otherwise.
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
- # generated, otherwise an exception is thrown, if these values are
- # encountered. This options defaults to false.
- # * *max_nesting*: The maximum depth of nesting allowed in the data
- # structures from which JSON is to be generated. Disable depth checking
- # with :max_nesting => false, it defaults to 19.
- #
- # See also the fast_generate for the fastest creation method with the least
- # amount of sanity checks, and the pretty_generate method for some
- # defaults for a pretty output.
- def generate(obj, state = nil)
- if state
- state = State.from_state(state)
- else
- state = State.new
- end
- obj.to_json(state)
- end
-
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
- alias unparse generate
- module_function :unparse
- # :startdoc:
-
- # Unparse the Ruby data structure _obj_ into a single line JSON string and
- # return it. This method disables the checks for circles in Ruby objects, and
- # also generates NaN, Infinity, and, -Infinity float values.
- #
- # *WARNING*: Be careful not to pass any Ruby data structures with circles as
- # _obj_ argument, because this will cause JSON to go into an infinite loop.
- def fast_generate(obj)
- obj.to_json(nil)
- end
-
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
- alias fast_unparse fast_generate
- module_function :fast_unparse
- # :startdoc:
-
- # Unparse the Ruby data structure _obj_ into a JSON string and return it. The
- # returned string is a prettier form of the string returned by #unparse.
- #
- # The _opts_ argument can be used to configure the generator, see the
- # generate method for a more detailed explanation.
- def pretty_generate(obj, opts = nil)
- state = JSON.state.new(
- :indent => ' ',
- :space => ' ',
- :object_nl => "\n",
- :array_nl => "\n",
- :check_circular => true
- )
- if opts
- if opts.respond_to? :to_hash
- opts = opts.to_hash
- elsif opts.respond_to? :to_h
- opts = opts.to_h
- else
- raise TypeError, "can't convert #{opts.class} into Hash"
- end
- state.configure(opts)
- end
- obj.to_json(state)
- end
-
- # :stopdoc:
- # I want to deprecate these later, so I'll first be silent about them, and later delete them.
- alias pretty_unparse pretty_generate
- module_function :pretty_unparse
- # :startdoc:
-
- # Load a ruby data structure from a JSON _source_ and return it. A source can
- # either be a string like object, an IO like object, or an object responding
- # to the read method. If _proc_ was given, it will be called with any nested
- # Ruby object as an argument recursively in depth first order.
- #
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
- def load(source, proc = nil)
- if source.respond_to? :to_str
- source = source.to_str
- elsif source.respond_to? :to_io
- source = source.to_io.read
- else
- source = source.read
- end
- result = parse(source, :max_nesting => false, :allow_nan => true)
- recurse_proc(result, &proc) if proc
- result
- end
-
- def recurse_proc(result, &proc)
- case result
- when Array
- result.each { |x| recurse_proc x, &proc }
- proc.call result
- when Hash
- result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
- proc.call result
- else
- proc.call result
- end
- end
- private :recurse_proc
- module_function :recurse_proc
-
- alias restore load
- module_function :restore
-
- # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns
- # the result.
- #
- # If anIO (an IO like object or an object that responds to the write method)
- # was given, the resulting JSON is written to it.
- #
- # If the number of nested arrays or objects exceeds _limit_ an ArgumentError
- # exception is raised. This argument is similar (but not exactly the
- # same!) to the _limit_ argument in Marshal.dump.
- #
- # This method is part of the implementation of the load/dump interface of
- # Marshal and YAML.
- def dump(obj, anIO = nil, limit = nil)
- if anIO and limit.nil?
- anIO = anIO.to_io if anIO.respond_to?(:to_io)
- unless anIO.respond_to?(:write)
- limit = anIO
- anIO = nil
- end
- end
- limit ||= 0
- result = generate(obj, :allow_nan => true, :max_nesting => limit)
- if anIO
- anIO.write result
- anIO
- else
- result
- end
- rescue JSON::NestingError
- raise ArgumentError, "exceed depth limit"
- end
-end
-
-module ::Kernel
- # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
- # one line.
- def j(*objs)
- objs.each do |obj|
- puts JSON::generate(obj, :allow_nan => true, :max_nesting => false)
- end
- nil
- end
-
- # Ouputs _objs_ to STDOUT as JSON strings in a pretty format, with
- # indentation and over many lines.
- def jj(*objs)
- objs.each do |obj|
- puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false)
- end
- nil
- end
-
- # If _object_ is string like parse the string and return the parsed result as
- # a Ruby data structure. Otherwise generate a JSON text from the Ruby data
- # structure object and return it.
- #
- # The _opts_ argument is passed through to generate/parse respectively, see
- # generate and parse for their documentation.
- def JSON(object, opts = {})
- if object.respond_to? :to_str
- JSON.parse(object.to_str, opts)
- else
- JSON.generate(object, opts)
- end
- end
-end
-
-class ::Class
- # Returns true, if this class can be used to create an instance
- # from a serialised JSON string. The class has to implement a class
- # method _json_create_ that expects a hash as first parameter, which includes
- # the required data.
- def json_creatable?
- respond_to?(:json_create)
- end
-end
- # vim: set et sw=2 ts=2:
diff --git a/trunk/ext/json/lib/json/editor.rb b/trunk/ext/json/lib/json/editor.rb
deleted file mode 100644
index 9a65400622..0000000000
--- a/trunk/ext/json/lib/json/editor.rb
+++ /dev/null
@@ -1,1363 +0,0 @@
-# To use the GUI JSON editor, start the edit_json.rb executable script. It
-# requires ruby-gtk to be installed.
-
-require 'gtk2'
-require 'iconv'
-require 'json'
-require 'rbconfig'
-require 'open-uri'
-
-module JSON
- module Editor
- include Gtk
-
- # Beginning of the editor window title
- TITLE = 'JSON Editor'.freeze
-
- # Columns constants
- ICON_COL, TYPE_COL, CONTENT_COL = 0, 1, 2
-
- # JSON primitive types (Containers)
- CONTAINER_TYPES = %w[Array Hash].sort
- # All JSON primitive types
- ALL_TYPES = (%w[TrueClass FalseClass Numeric String NilClass] +
- CONTAINER_TYPES).sort
-
- # The Nodes necessary for the tree representation of a JSON document
- ALL_NODES = (ALL_TYPES + %w[Key]).sort
-
- DEFAULT_DIALOG_KEY_PRESS_HANDLER = lambda do |dialog, event|
- case event.keyval
- when Gdk::Keyval::GDK_Return
- dialog.response Dialog::RESPONSE_ACCEPT
- when Gdk::Keyval::GDK_Escape
- dialog.response Dialog::RESPONSE_REJECT
- end
- end
-
- # Returns the Gdk::Pixbuf of the icon named _name_ from the icon cache.
- def Editor.fetch_icon(name)
- @icon_cache ||= {}
- unless @icon_cache.key?(name)
- path = File.dirname(__FILE__)
- @icon_cache[name] = Gdk::Pixbuf.new(File.join(path, name + '.xpm'))
- end
- @icon_cache[name]
- end
-
- # Opens an error dialog on top of _window_ showing the error message
- # _text_.
- def Editor.error_dialog(window, text)
- dialog = MessageDialog.new(window, Dialog::MODAL,
- MessageDialog::ERROR,
- MessageDialog::BUTTONS_CLOSE, text)
- dialog.show_all
- dialog.run
- rescue TypeError
- dialog = MessageDialog.new(Editor.window, Dialog::MODAL,
- MessageDialog::ERROR,
- MessageDialog::BUTTONS_CLOSE, text)
- dialog.show_all
- dialog.run
- ensure
- dialog.destroy if dialog
- end
-
- # Opens a yes/no question dialog on top of _window_ showing the error
- # message _text_. If yes was answered _true_ is returned, otherwise
- # _false_.
- def Editor.question_dialog(window, text)
- dialog = MessageDialog.new(window, Dialog::MODAL,
- MessageDialog::QUESTION,
- MessageDialog::BUTTONS_YES_NO, text)
- dialog.show_all
- dialog.run do |response|
- return Gtk::Dialog::RESPONSE_YES === response
- end
- ensure
- dialog.destroy if dialog
- end
-
- # Convert the tree model starting from Gtk::TreeIter _iter_ into a Ruby
- # data structure and return it.
- def Editor.model2data(iter)
- return nil if iter.nil?
- case iter.type
- when 'Hash'
- hash = {}
- iter.each { |c| hash[c.content] = Editor.model2data(c.first_child) }
- hash
- when 'Array'
- array = Array.new(iter.n_children)
- iter.each_with_index { |c, i| array[i] = Editor.model2data(c) }
- array
- when 'Key'
- iter.content
- when 'String'
- iter.content
- when 'Numeric'
- content = iter.content
- if /\./.match(content)
- content.to_f
- else
- content.to_i
- end
- when 'TrueClass'
- true
- when 'FalseClass'
- false
- when 'NilClass'
- nil
- else
- fail "Unknown type found in model: #{iter.type}"
- end
- end
-
- # Convert the Ruby data structure _data_ into tree model data for Gtk and
- # returns the whole model. If the parameter _model_ wasn't given a new
- # Gtk::TreeStore is created as the model. The _parent_ parameter specifies
- # the parent node (iter, Gtk:TreeIter instance) to which the data is
- # appended, alternativeley the result of the yielded block is used as iter.
- def Editor.data2model(data, model = nil, parent = nil)
- model ||= TreeStore.new(Gdk::Pixbuf, String, String)
- iter = if block_given?
- yield model
- else
- model.append(parent)
- end
- case data
- when Hash
- iter.type = 'Hash'
- data.sort.each do |key, value|
- pair_iter = model.append(iter)
- pair_iter.type = 'Key'
- pair_iter.content = key.to_s
- Editor.data2model(value, model, pair_iter)
- end
- when Array
- iter.type = 'Array'
- data.each do |value|
- Editor.data2model(value, model, iter)
- end
- when Numeric
- iter.type = 'Numeric'
- iter.content = data.to_s
- when String, true, false, nil
- iter.type = data.class.name
- iter.content = data.nil? ? 'null' : data.to_s
- else
- iter.type = 'String'
- iter.content = data.to_s
- end
- model
- end
-
- # The Gtk::TreeIter class is reopened and some auxiliary methods are added.
- class Gtk::TreeIter
- include Enumerable
-
- # Traverse each of this Gtk::TreeIter instance's children
- # and yield to them.
- def each
- n_children.times { |i| yield nth_child(i) }
- end
-
- # Recursively traverse all nodes of this Gtk::TreeIter's subtree
- # (including self) and yield to them.
- def recursive_each(&block)
- yield self
- each do |i|
- i.recursive_each(&block)
- end
- end
-
- # Remove the subtree of this Gtk::TreeIter instance from the
- # model _model_.
- def remove_subtree(model)
- while current = first_child
- model.remove(current)
- end
- end
-
- # Returns the type of this node.
- def type
- self[TYPE_COL]
- end
-
- # Sets the type of this node to _value_. This implies setting
- # the respective icon accordingly.
- def type=(value)
- self[TYPE_COL] = value
- self[ICON_COL] = Editor.fetch_icon(value)
- end
-
- # Returns the content of this node.
- def content
- self[CONTENT_COL]
- end
-
- # Sets the content of this node to _value_.
- def content=(value)
- self[CONTENT_COL] = value
- end
- end
-
- # This module bundles some method, that can be used to create a menu. It
- # should be included into the class in question.
- module MenuExtension
- include Gtk
-
- # Creates a Menu, that includes MenuExtension. _treeview_ is the
- # Gtk::TreeView, on which it operates.
- def initialize(treeview)
- @treeview = treeview
- @menu = Menu.new
- end
-
- # Returns the Gtk::TreeView of this menu.
- attr_reader :treeview
-
- # Returns the menu.
- attr_reader :menu
-
- # Adds a Gtk::SeparatorMenuItem to this instance's #menu.
- def add_separator
- menu.append SeparatorMenuItem.new
- end
-
- # Adds a Gtk::MenuItem to this instance's #menu. _label_ is the label
- # string, _klass_ is the item type, and _callback_ is the procedure, that
- # is called if the _item_ is activated.
- def add_item(label, keyval = nil, klass = MenuItem, &callback)
- label = "#{label} (C-#{keyval.chr})" if keyval
- item = klass.new(label)
- item.signal_connect(:activate, &callback)
- if keyval
- self.signal_connect(:'key-press-event') do |item, event|
- if event.state & Gdk::Window::ModifierType::CONTROL_MASK != 0 and
- event.keyval == keyval
- callback.call item
- end
- end
- end
- menu.append item
- item
- end
-
- # This method should be implemented in subclasses to create the #menu of
- # this instance. It has to be called after an instance of this class is
- # created, to build the menu.
- def create
- raise NotImplementedError
- end
-
- def method_missing(*a, &b)
- treeview.__send__(*a, &b)
- end
- end
-
- # This class creates the popup menu, that opens when clicking onto the
- # treeview.
- class PopUpMenu
- include MenuExtension
-
- # Change the type or content of the selected node.
- def change_node(item)
- if current = selection.selected
- parent = current.parent
- old_type, old_content = current.type, current.content
- if ALL_TYPES.include?(old_type)
- @clipboard_data = Editor.model2data(current)
- type, content = ask_for_element(parent, current.type,
- current.content)
- if type
- current.type, current.content = type, content
- current.remove_subtree(model)
- toplevel.display_status("Changed a node in tree.")
- window.change
- end
- else
- toplevel.display_status(
- "Cannot change node of type #{old_type} in tree!")
- end
- end
- end
-
- # Cut the selected node and its subtree, and save it into the
- # clipboard.
- def cut_node(item)
- if current = selection.selected
- if current and current.type == 'Key'
- @clipboard_data = {
- current.content => Editor.model2data(current.first_child)
- }
- else
- @clipboard_data = Editor.model2data(current)
- end
- model.remove(current)
- window.change
- toplevel.display_status("Cut a node from tree.")
- end
- end
-
- # Copy the selected node and its subtree, and save it into the
- # clipboard.
- def copy_node(item)
- if current = selection.selected
- if current and current.type == 'Key'
- @clipboard_data = {
- current.content => Editor.model2data(current.first_child)
- }
- else
- @clipboard_data = Editor.model2data(current)
- end
- window.change
- toplevel.display_status("Copied a node from tree.")
- end
- end
-
- # Paste the data in the clipboard into the selected Array or Hash by
- # appending it.
- def paste_node_appending(item)
- if current = selection.selected
- if @clipboard_data
- case current.type
- when 'Array'
- Editor.data2model(@clipboard_data, model, current)
- expand_collapse(current)
- when 'Hash'
- if @clipboard_data.is_a? Hash
- parent = current.parent
- hash = Editor.model2data(current)
- model.remove(current)
- hash.update(@clipboard_data)
- Editor.data2model(hash, model, parent)
- if parent
- expand_collapse(parent)
- elsif @expanded
- expand_all
- end
- window.change
- else
- toplevel.display_status(
- "Cannot paste non-#{current.type} data into '#{current.type}'!")
- end
- else
- toplevel.display_status(
- "Cannot paste node below '#{current.type}'!")
- end
- else
- toplevel.display_status("Nothing to paste in clipboard!")
- end
- else
- toplevel.display_status("Append a node into the root first!")
- end
- end
-
- # Paste the data in the clipboard into the selected Array inserting it
- # before the selected element.
- def paste_node_inserting_before(item)
- if current = selection.selected
- if @clipboard_data
- parent = current.parent or return
- parent_type = parent.type
- if parent_type == 'Array'
- selected_index = parent.each_with_index do |c, i|
- break i if c == current
- end
- Editor.data2model(@clipboard_data, model, parent) do |m|
- m.insert_before(parent, current)
- end
- expand_collapse(current)
- toplevel.display_status("Inserted an element to " +
- "'#{parent_type}' before index #{selected_index}.")
- window.change
- else
- toplevel.display_status(
- "Cannot insert node below '#{parent_type}'!")
- end
- else
- toplevel.display_status("Nothing to paste in clipboard!")
- end
- else
- toplevel.display_status("Append a node into the root first!")
- end
- end
-
- # Append a new node to the selected Hash or Array.
- def append_new_node(item)
- if parent = selection.selected
- parent_type = parent.type
- case parent_type
- when 'Hash'
- key, type, content = ask_for_hash_pair(parent)
- key or return
- iter = create_node(parent, 'Key', key)
- iter = create_node(iter, type, content)
- toplevel.display_status(
- "Added a (key, value)-pair to '#{parent_type}'.")
- window.change
- when 'Array'
- type, content = ask_for_element(parent)
- type or return
- iter = create_node(parent, type, content)
- window.change
- toplevel.display_status("Appendend an element to '#{parent_type}'.")
- else
- toplevel.display_status("Cannot append to '#{parent_type}'!")
- end
- else
- type, content = ask_for_element
- type or return
- iter = create_node(nil, type, content)
- window.change
- end
- end
-
- # Insert a new node into an Array before the selected element.
- def insert_new_node(item)
- if current = selection.selected
- parent = current.parent or return
- parent_parent = parent.parent
- parent_type = parent.type
- if parent_type == 'Array'
- selected_index = parent.each_with_index do |c, i|
- break i if c == current
- end
- type, content = ask_for_element(parent)
- type or return
- iter = model.insert_before(parent, current)
- iter.type, iter.content = type, content
- toplevel.display_status("Inserted an element to " +
- "'#{parent_type}' before index #{selected_index}.")
- window.change
- else
- toplevel.display_status(
- "Cannot insert node below '#{parent_type}'!")
- end
- else
- toplevel.display_status("Append a node into the root first!")
- end
- end
-
- # Recursively collapse/expand a subtree starting from the selected node.
- def collapse_expand(item)
- if current = selection.selected
- if row_expanded?(current.path)
- collapse_row(current.path)
- else
- expand_row(current.path, true)
- end
- else
- toplevel.display_status("Append a node into the root first!")
- end
- end
-
- # Create the menu.
- def create
- add_item("Change node", ?n, &method(:change_node))
- add_separator
- add_item("Cut node", ?X, &method(:cut_node))
- add_item("Copy node", ?C, &method(:copy_node))
- add_item("Paste node (appending)", ?A, &method(:paste_node_appending))
- add_item("Paste node (inserting before)", ?I,
- &method(:paste_node_inserting_before))
- add_separator
- add_item("Append new node", ?a, &method(:append_new_node))
- add_item("Insert new node before", ?i, &method(:insert_new_node))
- add_separator
- add_item("Collapse/Expand node (recursively)", ?e,
- &method(:collapse_expand))
-
- menu.show_all
- signal_connect(:button_press_event) do |widget, event|
- if event.kind_of? Gdk::EventButton and event.button == 3
- menu.popup(nil, nil, event.button, event.time)
- end
- end
- signal_connect(:popup_menu) do
- menu.popup(nil, nil, 0, Gdk::Event::CURRENT_TIME)
- end
- end
- end
-
- # This class creates the File pulldown menu.
- class FileMenu
- include MenuExtension
-
- # Clear the model and filename, but ask to save the JSON document, if
- # unsaved changes have occured.
- def new(item)
- window.clear
- end
-
- # Open a file and load it into the editor. Ask to save the JSON document
- # first, if unsaved changes have occured.
- def open(item)
- window.file_open
- end
-
- def open_location(item)
- window.location_open
- end
-
- # Revert the current JSON document in the editor to the saved version.
- def revert(item)
- window.instance_eval do
- @filename and file_open(@filename)
- end
- end
-
- # Save the current JSON document.
- def save(item)
- window.file_save
- end
-
- # Save the current JSON document under the given filename.
- def save_as(item)
- window.file_save_as
- end
-
- # Quit the editor, after asking to save any unsaved changes first.
- def quit(item)
- window.quit
- end
-
- # Create the menu.
- def create
- title = MenuItem.new('File')
- title.submenu = menu
- add_item('New', &method(:new))
- add_item('Open', ?o, &method(:open))
- add_item('Open location', ?l, &method(:open_location))
- add_item('Revert', &method(:revert))
- add_separator
- add_item('Save', ?s, &method(:save))
- add_item('Save As', ?S, &method(:save_as))
- add_separator
- add_item('Quit', ?q, &method(:quit))
- title
- end
- end
-
- # This class creates the Edit pulldown menu.
- class EditMenu
- include MenuExtension
-
- # Copy data from model into primary clipboard.
- def copy(item)
- data = Editor.model2data(model.iter_first)
- json = JSON.pretty_generate(data, :max_nesting => false)
- c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY)
- c.text = json
- end
-
- # Copy json text from primary clipboard into model.
- def paste(item)
- c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY)
- if json = c.wait_for_text
- window.ask_save if @changed
- begin
- window.edit json
- rescue JSON::ParserError
- window.clear
- end
- end
- end
-
- # Find a string in all nodes' contents and select the found node in the
- # treeview.
- def find(item)
- @search = ask_for_find_term(@search) or return
- iter = model.get_iter('0') or return
- iter.recursive_each do |i|
- if @iter
- if @iter != i
- next
- else
- @iter = nil
- next
- end
- elsif @search.match(i[CONTENT_COL])
- set_cursor(i.path, nil, false)
- @iter = i
- break
- end
- end
- end
-
- # Repeat the last search given by #find.
- def find_again(item)
- @search or return
- iter = model.get_iter('0')
- iter.recursive_each do |i|
- if @iter
- if @iter != i
- next
- else
- @iter = nil
- next
- end
- elsif @search.match(i[CONTENT_COL])
- set_cursor(i.path, nil, false)
- @iter = i
- break
- end
- end
- end
-
- # Sort (Reverse sort) all elements of the selected array by the given
- # expression. _x_ is the element in question.
- def sort(item)
- if current = selection.selected
- if current.type == 'Array'
- parent = current.parent
- ary = Editor.model2data(current)
- order, reverse = ask_for_order
- order or return
- begin
- block = eval "lambda { |x| #{order} }"
- if reverse
- ary.sort! { |a,b| block[b] <=> block[a] }
- else
- ary.sort! { |a,b| block[a] <=> block[b] }
- end
- rescue => e
- Editor.error_dialog(self, "Failed to sort Array with #{order}: #{e}!")
- else
- Editor.data2model(ary, model, parent) do |m|
- m.insert_before(parent, current)
- end
- model.remove(current)
- expand_collapse(parent)
- window.change
- toplevel.display_status("Array has been sorted.")
- end
- else
- toplevel.display_status("Only Array nodes can be sorted!")
- end
- else
- toplevel.display_status("Select an Array to sort first!")
- end
- end
-
- # Create the menu.
- def create
- title = MenuItem.new('Edit')
- title.submenu = menu
- add_item('Copy', ?c, &method(:copy))
- add_item('Paste', ?v, &method(:paste))
- add_separator
- add_item('Find', ?f, &method(:find))
- add_item('Find Again', ?g, &method(:find_again))
- add_separator
- add_item('Sort', ?S, &method(:sort))
- title
- end
- end
-
- class OptionsMenu
- include MenuExtension
-
- # Collapse/Expand all nodes by default.
- def collapsed_nodes(item)
- if expanded
- self.expanded = false
- collapse_all
- else
- self.expanded = true
- expand_all
- end
- end
-
- # Toggle pretty saving mode on/off.
- def pretty_saving(item)
- @pretty_item.toggled
- window.change
- end
-
- attr_reader :pretty_item
-
- # Create the menu.
- def create
- title = MenuItem.new('Options')
- title.submenu = menu
- add_item('Collapsed nodes', nil, CheckMenuItem, &method(:collapsed_nodes))
- @pretty_item = add_item('Pretty saving', nil, CheckMenuItem,
- &method(:pretty_saving))
- @pretty_item.active = true
- window.unchange
- title
- end
- end
-
- # This class inherits from Gtk::TreeView, to configure it and to add a lot
- # of behaviour to it.
- class JSONTreeView < Gtk::TreeView
- include Gtk
-
- # Creates a JSONTreeView instance, the parameter _window_ is
- # a MainWindow instance and used for self delegation.
- def initialize(window)
- @window = window
- super(TreeStore.new(Gdk::Pixbuf, String, String))
- self.selection.mode = SELECTION_BROWSE
-
- @expanded = false
- self.headers_visible = false
- add_columns
- add_popup_menu
- end
-
- # Returns the MainWindow instance of this JSONTreeView.
- attr_reader :window
-
- # Returns true, if nodes are autoexpanding, false otherwise.
- attr_accessor :expanded
-
- private
-
- def add_columns
- cell = CellRendererPixbuf.new
- column = TreeViewColumn.new('Icon', cell,
- 'pixbuf' => ICON_COL
- )
- append_column(column)
-
- cell = CellRendererText.new
- column = TreeViewColumn.new('Type', cell,
- 'text' => TYPE_COL
- )
- append_column(column)
-
- cell = CellRendererText.new
- cell.editable = true
- column = TreeViewColumn.new('Content', cell,
- 'text' => CONTENT_COL
- )
- cell.signal_connect(:edited, &method(:cell_edited))
- append_column(column)
- end
-
- def unify_key(iter, key)
- return unless iter.type == 'Key'
- parent = iter.parent
- if parent.any? { |c| c != iter and c.content == key }
- old_key = key
- i = 0
- begin
- key = sprintf("%s.%d", old_key, i += 1)
- end while parent.any? { |c| c != iter and c.content == key }
- end
- iter.content = key
- end
-
- def cell_edited(cell, path, value)
- iter = model.get_iter(path)
- case iter.type
- when 'Key'
- unify_key(iter, value)
- toplevel.display_status('Key has been changed.')
- when 'FalseClass'
- value.downcase!
- if value == 'true'
- iter.type, iter.content = 'TrueClass', 'true'
- end
- when 'TrueClass'
- value.downcase!
- if value == 'false'
- iter.type, iter.content = 'FalseClass', 'false'
- end
- when 'Numeric'
- iter.content = (Integer(value) rescue Float(value) rescue 0).to_s
- when 'String'
- iter.content = value
- when 'Hash', 'Array'
- return
- else
- fail "Unknown type found in model: #{iter.type}"
- end
- window.change
- end
-
- def configure_value(value, type)
- value.editable = false
- case type
- when 'Array', 'Hash'
- value.text = ''
- when 'TrueClass'
- value.text = 'true'
- when 'FalseClass'
- value.text = 'false'
- when 'NilClass'
- value.text = 'null'
- when 'Numeric', 'String'
- value.text ||= ''
- value.editable = true
- else
- raise ArgumentError, "unknown type '#{type}' encountered"
- end
- end
-
- def add_popup_menu
- menu = PopUpMenu.new(self)
- menu.create
- end
-
- public
-
- # Create a _type_ node with content _content_, and add it to _parent_
- # in the model. If _parent_ is nil, create a new model and put it into
- # the editor treeview.
- def create_node(parent, type, content)
- iter = if parent
- model.append(parent)
- else
- new_model = Editor.data2model(nil)
- toplevel.view_new_model(new_model)
- new_model.iter_first
- end
- iter.type, iter.content = type, content
- expand_collapse(parent) if parent
- iter
- end
-
- # Ask for a hash key, value pair to be added to the Hash node _parent_.
- def ask_for_hash_pair(parent)
- key_input = type_input = value_input = nil
-
- dialog = Dialog.new("New (key, value) pair for Hash", nil, nil,
- [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
- [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
- )
- dialog.width_request = 640
-
- hbox = HBox.new(false, 5)
- hbox.pack_start(Label.new("Key:"), false)
- hbox.pack_start(key_input = Entry.new)
- key_input.text = @key || ''
- dialog.vbox.pack_start(hbox, false)
- key_input.signal_connect(:activate) do
- if parent.any? { |c| c.content == key_input.text }
- toplevel.display_status('Key already exists in Hash!')
- key_input.text = ''
- else
- toplevel.display_status('Key has been changed.')
- end
- end
-
- hbox = HBox.new(false, 5)
- hbox.pack_start(Label.new("Type:"), false)
- hbox.pack_start(type_input = ComboBox.new(true))
- ALL_TYPES.each { |t| type_input.append_text(t) }
- type_input.active = @type || 0
- dialog.vbox.pack_start(hbox, false)
-
- type_input.signal_connect(:changed) do
- value_input.editable = false
- case ALL_TYPES[type_input.active]
- when 'Array', 'Hash'
- value_input.text = ''
- when 'TrueClass'
- value_input.text = 'true'
- when 'FalseClass'
- value_input.text = 'false'
- when 'NilClass'
- value_input.text = 'null'
- else
- value_input.text = ''
- value_input.editable = true
- end
- end
-
- hbox = HBox.new(false, 5)
- hbox.pack_start(Label.new("Value:"), false)
- hbox.pack_start(value_input = Entry.new)
- value_input.width_chars = 60
- value_input.text = @value || ''
- dialog.vbox.pack_start(hbox, false)
-
- dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
- dialog.show_all
- self.focus = dialog
- dialog.run do |response|
- if response == Dialog::RESPONSE_ACCEPT
- @key = key_input.text
- type = ALL_TYPES[@type = type_input.active]
- content = value_input.text
- return @key, type, content
- end
- end
- return
- ensure
- dialog.destroy
- end
-
- # Ask for an element to be appended _parent_.
- def ask_for_element(parent = nil, default_type = nil, value_text = @content)
- type_input = value_input = nil
-
- dialog = Dialog.new(
- "New element into #{parent ? parent.type : 'root'}",
- nil, nil,
- [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
- [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
- )
- hbox = HBox.new(false, 5)
- hbox.pack_start(Label.new("Type:"), false)
- hbox.pack_start(type_input = ComboBox.new(true))
- default_active = 0
- types = parent ? ALL_TYPES : CONTAINER_TYPES
- types.each_with_index do |t, i|
- type_input.append_text(t)
- if t == default_type
- default_active = i
- end
- end
- type_input.active = default_active
- dialog.vbox.pack_start(hbox, false)
- type_input.signal_connect(:changed) do
- configure_value(value_input, types[type_input.active])
- end
-
- hbox = HBox.new(false, 5)
- hbox.pack_start(Label.new("Value:"), false)
- hbox.pack_start(value_input = Entry.new)
- value_input.width_chars = 60
- value_input.text = value_text if value_text
- configure_value(value_input, types[type_input.active])
-
- dialog.vbox.pack_start(hbox, false)
-
- dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
- dialog.show_all
- self.focus = dialog
- dialog.run do |response|
- if response == Dialog::RESPONSE_ACCEPT
- type = types[type_input.active]
- @content = case type
- when 'Numeric'
- Integer(value_input.text) rescue Float(value_input.text) rescue 0
- else
- value_input.text
- end.to_s
- return type, @content
- end
- end
- return
- ensure
- dialog.destroy if dialog
- end
-
- # Ask for an order criteria for sorting, using _x_ for the element in
- # question. Returns the order criterium, and true/false for reverse
- # sorting.
- def ask_for_order
- dialog = Dialog.new(
- "Give an order criterium for 'x'.",
- nil, nil,
- [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
- [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
- )
- hbox = HBox.new(false, 5)
-
- hbox.pack_start(Label.new("Order:"), false)
- hbox.pack_start(order_input = Entry.new)
- order_input.text = @order || 'x'
- order_input.width_chars = 60
-
- hbox.pack_start(reverse_checkbox = CheckButton.new('Reverse'), false)
-
- dialog.vbox.pack_start(hbox, false)
-
- dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
- dialog.show_all
- self.focus = dialog
- dialog.run do |response|
- if response == Dialog::RESPONSE_ACCEPT
- return @order = order_input.text, reverse_checkbox.active?
- end
- end
- return
- ensure
- dialog.destroy if dialog
- end
-
- # Ask for a find term to search for in the tree. Returns the term as a
- # string.
- def ask_for_find_term(search = nil)
- dialog = Dialog.new(
- "Find a node matching regex in tree.",
- nil, nil,
- [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
- [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
- )
- hbox = HBox.new(false, 5)
-
- hbox.pack_start(Label.new("Regex:"), false)
- hbox.pack_start(regex_input = Entry.new)
- hbox.pack_start(icase_checkbox = CheckButton.new('Icase'), false)
- regex_input.width_chars = 60
- if search
- regex_input.text = search.source
- icase_checkbox.active = search.casefold?
- end
-
- dialog.vbox.pack_start(hbox, false)
-
- dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
- dialog.show_all
- self.focus = dialog
- dialog.run do |response|
- if response == Dialog::RESPONSE_ACCEPT
- begin
- return Regexp.new(regex_input.text, icase_checkbox.active? ? Regexp::IGNORECASE : 0)
- rescue => e
- Editor.error_dialog(self, "Evaluation of regex /#{regex_input.text}/ failed: #{e}!")
- return
- end
- end
- end
- return
- ensure
- dialog.destroy if dialog
- end
-
- # Expand or collapse row pointed to by _iter_ according
- # to the #expanded attribute.
- def expand_collapse(iter)
- if expanded
- expand_row(iter.path, true)
- else
- collapse_row(iter.path)
- end
- end
- end
-
- # The editor main window
- class MainWindow < Gtk::Window
- include Gtk
-
- def initialize(encoding)
- @changed = false
- @encoding = encoding
- super(TOPLEVEL)
- display_title
- set_default_size(800, 600)
- signal_connect(:delete_event) { quit }
-
- vbox = VBox.new(false, 0)
- add(vbox)
- #vbox.border_width = 0
-
- @treeview = JSONTreeView.new(self)
- @treeview.signal_connect(:'cursor-changed') do
- display_status('')
- end
-
- menu_bar = create_menu_bar
- vbox.pack_start(menu_bar, false, false, 0)
-
- sw = ScrolledWindow.new(nil, nil)
- sw.shadow_type = SHADOW_ETCHED_IN
- sw.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
- vbox.pack_start(sw, true, true, 0)
- sw.add(@treeview)
-
- @status_bar = Statusbar.new
- vbox.pack_start(@status_bar, false, false, 0)
-
- @filename ||= nil
- if @filename
- data = read_data(@filename)
- view_new_model Editor.data2model(data)
- end
-
- signal_connect(:button_release_event) do |_,event|
- if event.button == 2
- c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY)
- if url = c.wait_for_text
- location_open url
- end
- false
- else
- true
- end
- end
- end
-
- # Creates the menu bar with the pulldown menus and returns it.
- def create_menu_bar
- menu_bar = MenuBar.new
- @file_menu = FileMenu.new(@treeview)
- menu_bar.append @file_menu.create
- @edit_menu = EditMenu.new(@treeview)
- menu_bar.append @edit_menu.create
- @options_menu = OptionsMenu.new(@treeview)
- menu_bar.append @options_menu.create
- menu_bar
- end
-
- # Sets editor status to changed, to indicate that the edited data
- # containts unsaved changes.
- def change
- @changed = true
- display_title
- end
-
- # Sets editor status to unchanged, to indicate that the edited data
- # doesn't containt unsaved changes.
- def unchange
- @changed = false
- display_title
- end
-
- # Puts a new model _model_ into the Gtk::TreeView to be edited.
- def view_new_model(model)
- @treeview.model = model
- @treeview.expanded = true
- @treeview.expand_all
- unchange
- end
-
- # Displays _text_ in the status bar.
- def display_status(text)
- @cid ||= nil
- @status_bar.pop(@cid) if @cid
- @cid = @status_bar.get_context_id('dummy')
- @status_bar.push(@cid, text)
- end
-
- # Opens a dialog, asking, if changes should be saved to a file.
- def ask_save
- if Editor.question_dialog(self,
- "Unsaved changes to JSON model. Save?")
- if @filename
- file_save
- else
- file_save_as
- end
- end
- end
-
- # Quit this editor, that is, leave this editor's main loop.
- def quit
- ask_save if @changed
- if Gtk.main_level > 0
- destroy
- Gtk.main_quit
- end
- nil
- end
-
- # Display the new title according to the editor's current state.
- def display_title
- title = TITLE.dup
- title << ": #@filename" if @filename
- title << " *" if @changed
- self.title = title
- end
-
- # Clear the current model, after asking to save all unsaved changes.
- def clear
- ask_save if @changed
- @filename = nil
- self.view_new_model nil
- end
-
- def check_pretty_printed(json)
- pretty = !!((nl_index = json.index("\n")) && nl_index != json.size - 1)
- @options_menu.pretty_item.active = pretty
- end
- private :check_pretty_printed
-
- # Open the data at the location _uri_, if given. Otherwise open a dialog
- # to ask for the _uri_.
- def location_open(uri = nil)
- uri = ask_for_location unless uri
- uri or return
- ask_save if @changed
- data = load_location(uri) or return
- view_new_model Editor.data2model(data)
- end
-
- # Open the file _filename_ or call the #select_file method to ask for a
- # filename.
- def file_open(filename = nil)
- filename = select_file('Open as a JSON file') unless filename
- data = load_file(filename) or return
- view_new_model Editor.data2model(data)
- end
-
- # Edit the string _json_ in the editor.
- def edit(json)
- if json.respond_to? :read
- json = json.read
- end
- data = parse_json json
- view_new_model Editor.data2model(data)
- end
-
- # Save the current file.
- def file_save
- if @filename
- store_file(@filename)
- else
- file_save_as
- end
- end
-
- # Save the current file as the filename
- def file_save_as
- filename = select_file('Save as a JSON file')
- store_file(filename)
- end
-
- # Store the current JSON document to _path_.
- def store_file(path)
- if path
- data = Editor.model2data(@treeview.model.iter_first)
- File.open(path + '.tmp', 'wb') do |output|
- data or break
- if @options_menu.pretty_item.active?
- output.puts JSON.pretty_generate(data, :max_nesting => false)
- else
- output.write JSON.generate(data, :max_nesting => false)
- end
- end
- File.rename path + '.tmp', path
- @filename = path
- toplevel.display_status("Saved data to '#@filename'.")
- unchange
- end
- rescue SystemCallError => e
- Editor.error_dialog(self, "Failed to store JSON file: #{e}!")
- end
-
- # Load the file named _filename_ into the editor as a JSON document.
- def load_file(filename)
- if filename
- if File.directory?(filename)
- Editor.error_dialog(self, "Try to select a JSON file!")
- nil
- else
- @filename = filename
- if data = read_data(filename)
- toplevel.display_status("Loaded data from '#@filename'.")
- end
- display_title
- data
- end
- end
- end
-
- # Load the data at location _uri_ into the editor as a JSON document.
- def load_location(uri)
- data = read_data(uri) or return
- @filename = nil
- toplevel.display_status("Loaded data from '#{uri}'.")
- display_title
- data
- end
-
- def parse_json(json)
- check_pretty_printed(json)
- if @encoding && !/^utf8$/i.match(@encoding)
- iconverter = Iconv.new('utf8', @encoding)
- json = iconverter.iconv(json)
- end
- JSON::parse(json, :max_nesting => false, :create_additions => false)
- end
- private :parse_json
-
- # Read a JSON document from the file named _filename_, parse it into a
- # ruby data structure, and return the data.
- def read_data(filename)
- open(filename) do |f|
- json = f.read
- return parse_json(json)
- end
- rescue => e
- Editor.error_dialog(self, "Failed to parse JSON file: #{e}!")
- return
- end
-
- # Open a file selecton dialog, displaying _message_, and return the
- # selected filename or nil, if no file was selected.
- def select_file(message)
- filename = nil
- fs = FileSelection.new(message)
- fs.set_modal(true)
- @default_dir = File.join(Dir.pwd, '') unless @default_dir
- fs.set_filename(@default_dir)
- fs.set_transient_for(self)
- fs.signal_connect(:destroy) { Gtk.main_quit }
- fs.ok_button.signal_connect(:clicked) do
- filename = fs.filename
- @default_dir = File.join(File.dirname(filename), '')
- fs.destroy
- Gtk.main_quit
- end
- fs.cancel_button.signal_connect(:clicked) do
- fs.destroy
- Gtk.main_quit
- end
- fs.show_all
- Gtk.main
- filename
- end
-
- # Ask for location URI a to load data from. Returns the URI as a string.
- def ask_for_location
- dialog = Dialog.new(
- "Load data from location...",
- nil, nil,
- [ Stock::OK, Dialog::RESPONSE_ACCEPT ],
- [ Stock::CANCEL, Dialog::RESPONSE_REJECT ]
- )
- hbox = HBox.new(false, 5)
-
- hbox.pack_start(Label.new("Location:"), false)
- hbox.pack_start(location_input = Entry.new)
- location_input.width_chars = 60
- location_input.text = @location || ''
-
- dialog.vbox.pack_start(hbox, false)
-
- dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER)
- dialog.show_all
- dialog.run do |response|
- if response == Dialog::RESPONSE_ACCEPT
- return @location = location_input.text
- end
- end
- return
- ensure
- dialog.destroy if dialog
- end
- end
-
- class << self
- # Starts a JSON Editor. If a block was given, it yields
- # to the JSON::Editor::MainWindow instance.
- def start(encoding = 'utf8') # :yield: window
- Gtk.init
- @window = Editor::MainWindow.new(encoding)
- @window.icon_list = [ Editor.fetch_icon('json') ]
- yield @window if block_given?
- @window.show_all
- Gtk.main
- end
-
- # Edit the string _json_ with encoding _encoding_ in the editor.
- def edit(json, encoding = 'utf8')
- start(encoding) do |window|
- window.edit json
- end
- end
-
- attr_reader :window
- end
- end
-end
- # vim: set et sw=2 ts=2:
diff --git a/trunk/ext/json/lib/json/ext.rb b/trunk/ext/json/lib/json/ext.rb
deleted file mode 100644
index ff4fa42329..0000000000
--- a/trunk/ext/json/lib/json/ext.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'json/common'
-
-module JSON
- # This module holds all the modules/classes that implement JSON's
- # functionality as C extensions.
- module Ext
- require 'json/ext/parser'
- require 'json/ext/generator'
- $DEBUG and warn "Using c extension for JSON."
- JSON.parser = Parser
- JSON.generator = Generator
- end
-end
diff --git a/trunk/ext/json/lib/json/json.xpm b/trunk/ext/json/lib/json/json.xpm
deleted file mode 100644
index 2cb626bb05..0000000000
--- a/trunk/ext/json/lib/json/json.xpm
+++ /dev/null
@@ -1,1499 +0,0 @@
-/* XPM */
-static char * json_xpm[] = {
-"64 64 1432 2",
-" c None",
-". c #641839",
-"+ c #CF163C",
-"@ c #D31C3B",
-"# c #E11A38",
-"$ c #5F242D",
-"% c #320C22",
-"& c #9B532D",
-"* c #F32E34",
-"= c #820F33",
-"- c #4B0F34",
-"; c #8E1237",
-"> c #944029",
-", c #961325",
-"' c #A00C24",
-") c #872C23",
-"! c #694021",
-"~ c #590D1F",
-"{ c #420528",
-"] c #D85A2D",
-"^ c #7E092B",
-"/ c #0E0925",
-"( c #0D081F",
-"_ c #0F081E",
-": c #12071F",
-"< c #360620",
-"[ c #682A21",
-"} c #673F21",
-"| c #780E21",
-"1 c #A82320",
-"2 c #8D1D1F",
-"3 c #970127",
-"4 c #0D0123",
-"5 c #0D0324",
-"6 c #3B1E28",
-"7 c #C28429",
-"8 c #0C0523",
-"9 c #0C041E",
-"0 c #0E031A",
-"a c #11031A",
-"b c #13031B",
-"c c #13031C",
-"d c #11031D",
-"e c #19051E",
-"f c #390E20",
-"g c #9C0C20",
-"h c #C00721",
-"i c #980320",
-"j c #14031E",
-"k c #CD9F32",
-"l c #C29F2E",
-"m c #0F0325",
-"n c #0D0321",
-"o c #0E0324",
-"p c #D08329",
-"q c #9D1B27",
-"r c #1C0320",
-"s c #0D011A",
-"t c #120117",
-"u c #130017",
-"v c #150018",
-"w c #160119",
-"x c #17021A",
-"y c #15021B",
-"z c #11021E",
-"A c #0F021F",
-"B c #8C1821",
-"C c #CF4522",
-"D c #831821",
-"E c #BA7033",
-"F c #EDB339",
-"G c #C89733",
-"H c #280727",
-"I c #0F051F",
-"J c #0E0420",
-"K c #591F27",
-"L c #E47129",
-"M c #612224",
-"N c #0C021D",
-"O c #120018",
-"P c #140017",
-"Q c #170017",
-"R c #190018",
-"S c #1B0019",
-"T c #1B011A",
-"U c #18011B",
-"V c #15011C",
-"W c #12031E",
-"X c #460A21",
-"Y c #A13823",
-"Z c #784323",
-"` c #5A0C21",
-" . c #BC4530",
-".. c #EB5B38",
-"+. c #CE4E3B",
-"@. c #DD9334",
-"#. c #751A27",
-"$. c #11071E",
-"%. c #0F041C",
-"&. c #1E0824",
-"*. c #955A28",
-"=. c #9A5027",
-"-. c #1E0321",
-";. c #11011A",
-">. c #140018",
-",. c #180018",
-"'. c #1F001A",
-"). c #20001B",
-"!. c #1E001A",
-"~. c #1B001A",
-"{. c #16021B",
-"]. c #16041E",
-"^. c #220622",
-"/. c #5F3525",
-"(. c #DE5724",
-"_. c #611021",
-":. c #0F0925",
-"<. c #D1892E",
-"[. c #F27036",
-"}. c #EC633B",
-"|. c #DA293C",
-"1. c #E64833",
-"2. c #912226",
-"3. c #11081C",
-"4. c #110419",
-"5. c #0F041E",
-"6. c #451425",
-"7. c #BF6F28",
-"8. c #332225",
-"9. c #0E021E",
-"0. c #13001B",
-"a. c #17001A",
-"b. c #1C001B",
-"c. c #21001C",
-"d. c #23001C",
-"e. c #21001B",
-"f. c #19021A",
-"g. c #17041E",
-"h. c #150721",
-"i. c #602424",
-"j. c #D51223",
-"k. c #540820",
-"l. c #D04D2D",
-"m. c #EA8933",
-"n. c #875637",
-"o. c #88543A",
-"p. c #E5923A",
-"q. c #891931",
-"r. c #130B25",
-"s. c #10051B",
-"t. c #110217",
-"u. c #12021A",
-"v. c #761826",
-"w. c #E2A728",
-"x. c #300224",
-"y. c #10011E",
-"z. c #16001B",
-"A. c #1B001B",
-"B. c #21001A",
-"C. c #1E0019",
-"D. c #1D0019",
-"E. c #1A011A",
-"F. c #17031C",
-"G. c #120720",
-"H. c #4E0822",
-"I. c #670721",
-"J. c #C07630",
-"K. c #F59734",
-"L. c #BE1B35",
-"M. c #0E1435",
-"N. c #522037",
-"O. c #DB8039",
-"P. c #D45933",
-"Q. c #420927",
-"R. c #0F041D",
-"S. c #140118",
-"T. c #13021D",
-"U. c #100423",
-"V. c #7B6227",
-"W. c #C04326",
-"X. c #0E0020",
-"Y. c #13001D",
-"Z. c #18001B",
-"`. c #1E001B",
-" + c #22001C",
-".+ c #22001B",
-"++ c #1B011B",
-"@+ c #16041D",
-"#+ c #130520",
-"$+ c #860521",
-"%+ c #710520",
-"&+ c #670A2A",
-"*+ c #A66431",
-"=+ c #E97536",
-"-+ c #F8833A",
-";+ c #F77A3A",
-">+ c #C45337",
-",+ c #0A1C35",
-"'+ c #993638",
-")+ c #F7863B",
-"!+ c #F49736",
-"~+ c #94462B",
-"{+ c #0E031F",
-"]+ c #130119",
-"^+ c #160018",
-"/+ c #16011B",
-"(+ c #15021F",
-"_+ c #120123",
-":+ c #A65C28",
-"<+ c #5C4D23",
-"[+ c #0F001F",
-"}+ c #14001D",
-"|+ c #1A001B",
-"1+ c #1F001B",
-"2+ c #24001D",
-"3+ c #25001D",
-"4+ c #24001C",
-"5+ c #1F001C",
-"6+ c #1A011C",
-"7+ c #16021E",
-"8+ c #3F0421",
-"9+ c #BC0522",
-"0+ c #1C041E",
-"a+ c #7F5531",
-"b+ c #E68A38",
-"c+ c #F8933E",
-"d+ c #FA7942",
-"e+ c #FB7543",
-"f+ c #FA6F41",
-"g+ c #F1793D",
-"h+ c #7D3B3A",
-"i+ c #28263B",
-"j+ c #D45441",
-"k+ c #F8A238",
-"l+ c #996B2D",
-"m+ c #0E0421",
-"n+ c #12011A",
-"o+ c #180019",
-"p+ c #17001C",
-"q+ c #12001F",
-"r+ c #4C2B2A",
-"s+ c #DB8130",
-"t+ c #540023",
-"u+ c #0F0120",
-"v+ c #16011C",
-"w+ c #22001D",
-"x+ c #25001F",
-"y+ c #26001F",
-"z+ c #25001E",
-"A+ c #24001E",
-"B+ c #1D001C",
-"C+ c #18011D",
-"D+ c #16031F",
-"E+ c #3C0522",
-"F+ c #9B0821",
-"G+ c #13041E",
-"H+ c #F6462E",
-"I+ c #E6AB37",
-"J+ c #E7A03E",
-"K+ c #FA9F44",
-"L+ c #FB8A48",
-"M+ c #FD7A4A",
-"N+ c #FD794A",
-"O+ c #FD7748",
-"P+ c #FD7E45",
-"Q+ c #FD8343",
-"R+ c #FB5D42",
-"S+ c #6E3A40",
-"T+ c #EE8A37",
-"U+ c #7E252B",
-"V+ c #100520",
-"W+ c #13011A",
-"X+ c #170019",
-"Y+ c #15001C",
-"Z+ c #0F0020",
-"`+ c #564427",
-" @ c #E0BA29",
-".@ c #5E2B25",
-"+@ c #10011F",
-"@@ c #17011C",
-"#@ c #1E001D",
-"$@ c #23001F",
-"%@ c #250020",
-"&@ c #24001F",
-"*@ c #23001E",
-"=@ c #21001E",
-"-@ c #1B001C",
-";@ c #17021D",
-">@ c #14041E",
-",@ c #AC0B25",
-"'@ c #5E1420",
-")@ c #F28635",
-"!@ c #C2733E",
-"~@ c #984C44",
-"{@ c #EA9148",
-"]@ c #FB844B",
-"^@ c #FD7E4C",
-"/@ c #FE7E4C",
-"(@ c #FE7E4B",
-"_@ c #FE7749",
-":@ c #FD7148",
-"<@ c #FB7D46",
-"[@ c #F89641",
-"}@ c #B95634",
-"|@ c #0D0927",
-"1@ c #11041D",
-"2@ c #150119",
-"3@ c #180017",
-"4@ c #16001A",
-"5@ c #13001E",
-"6@ c #110023",
-"7@ c #944C29",
-"8@ c #EE6229",
-"9@ c #3D0324",
-"0@ c #12021F",
-"a@ c #19011D",
-"b@ c #21001F",
-"c@ c #22001F",
-"d@ c #20001E",
-"e@ c #1F001D",
-"f@ c #1C001C",
-"g@ c #19011C",
-"h@ c #3D1621",
-"i@ c #B53622",
-"j@ c #31061F",
-"k@ c #841D34",
-"l@ c #F2703F",
-"m@ c #C14445",
-"n@ c #E67349",
-"o@ c #FB8E4B",
-"p@ c #FD834C",
-"q@ c #FE834D",
-"r@ c #FE834C",
-"s@ c #FE804C",
-"t@ c #FD814B",
-"u@ c #FB7D49",
-"v@ c #F79B43",
-"w@ c #AF1234",
-"x@ c #0D0625",
-"y@ c #13021C",
-"z@ c #1A0019",
-"A@ c #190019",
-"B@ c #410225",
-"C@ c #D39729",
-"D@ c #AA5927",
-"E@ c #0E0422",
-"F@ c #15021E",
-"G@ c #1A011D",
-"H@ c #1D001D",
-"I@ c #15031D",
-"J@ c #240820",
-"K@ c #A01023",
-"L@ c #670B21",
-"M@ c #3D0D33",
-"N@ c #E63C3E",
-"O@ c #EF7C45",
-"P@ c #F59048",
-"Q@ c #FB944A",
-"R@ c #FD904A",
-"S@ c #FE8E4B",
-"T@ c #FE854A",
-"U@ c #FE854B",
-"V@ c #FE884C",
-"W@ c #FC954B",
-"X@ c #F8AB45",
-"Y@ c #C37A35",
-"Z@ c #0D0425",
-"`@ c #13011B",
-" # c #170018",
-".# c #1A0018",
-"+# c #1C0019",
-"@# c #15001B",
-"## c #100120",
-"$# c #311F25",
-"%# c #E68E28",
-"&# c #7A1425",
-"*# c #130321",
-"=# c #17011E",
-"-# c #1A001D",
-";# c #19001B",
-"># c #16021C",
-",# c #130521",
-"'# c #6F3123",
-")# c #6D3022",
-"!# c #C89433",
-"~# c #EA7E3E",
-"{# c #DB2943",
-"]# c #EF7745",
-"^# c #FB8544",
-"/# c #FD9A43",
-"(# c #FE9941",
-"_# c #FE9D43",
-":# c #FEA548",
-"<# c #FEAE49",
-"[# c #FCB944",
-"}# c #CA9F35",
-"|# c #0E0225",
-"1# c #11001B",
-"2# c #160019",
-"3# c #12011B",
-"4# c #0F0220",
-"5# c #351D26",
-"6# c #D85B28",
-"7# c #6C0F26",
-"8# c #190121",
-"9# c #1B001E",
-"0# c #1A001C",
-"a# c #1D001B",
-"b# c #130220",
-"c# c #703A23",
-"d# c #713A23",
-"e# c #140327",
-"f# c #411B36",
-"g# c #C8713E",
-"h# c #7A3A3F",
-"i# c #CE2C3C",
-"j# c #E77338",
-"k# c #9C6535",
-"l# c #9C6233",
-"m# c #9C6332",
-"n# c #9C6A35",
-"o# c #C37D3C",
-"p# c #FEAC41",
-"q# c #FEC23E",
-"r# c #826330",
-"s# c #100122",
-"t# c #120019",
-"u# c #150017",
-"v# c #190017",
-"w# c #1B0018",
-"x# c #12001A",
-"y# c #10021F",
-"z# c #1A0326",
-"A# c #5F292A",
-"B# c #7B4E29",
-"C# c #3C0E25",
-"D# c #1A0020",
-"E# c #14021F",
-"F# c #723B23",
-"G# c #14001A",
-"H# c #58042A",
-"I# c #A28337",
-"J# c #C8813B",
-"K# c #B14B38",
-"L# c #761231",
-"M# c #5A132A",
-"N# c #0D0726",
-"O# c #0C0623",
-"P# c #0B0723",
-"Q# c #0B0A26",
-"R# c #321C2D",
-"S# c #C45B33",
-"T# c #FEBB33",
-"U# c #13052A",
-"V# c #13011F",
-"W# c #160017",
-"X# c #15001A",
-"Y# c #12001D",
-"Z# c #94062A",
-"`# c #630D2C",
-" $ c #85292B",
-".$ c #AA5E29",
-"+$ c #1F0123",
-"@$ c #19011F",
-"#$ c #1E001C",
-"$$ c #15031F",
-"%$ c #712122",
-"&$ c #712223",
-"*$ c #14011B",
-"=$ c #110321",
-"-$ c #AF0C2B",
-";$ c #E7D534",
-">$ c #EAC934",
-",$ c #84582D",
-"'$ c #1B0824",
-")$ c #11041E",
-"!$ c #10021B",
-"~$ c #100119",
-"{$ c #100218",
-"]$ c #0F041A",
-"^$ c #0E0720",
-"/$ c #2C1026",
-"($ c #D8A328",
-"_$ c #140322",
-":$ c #160016",
-"<$ c #14001F",
-"[$ c #120024",
-"}$ c #100128",
-"|$ c #3C032F",
-"1$ c #2C062E",
-"2$ c #29022B",
-"3$ c #A31D29",
-"4$ c #976A25",
-"5$ c #1A0321",
-"6$ c #17031E",
-"7$ c #1B021D",
-"8$ c #20001C",
-"9$ c #14041F",
-"0$ c #703422",
-"a$ c #6F3522",
-"b$ c #8D0328",
-"c$ c #920329",
-"d$ c #0F0326",
-"e$ c #100321",
-"f$ c #11021B",
-"g$ c #130117",
-"h$ c #140016",
-"i$ c #150015",
-"j$ c #140015",
-"k$ c #130116",
-"l$ c #120219",
-"m$ c #11031C",
-"n$ c #12031D",
-"o$ c #170016",
-"p$ c #160020",
-"q$ c #250029",
-"r$ c #670033",
-"s$ c #DCA238",
-"t$ c #F5C736",
-"u$ c #9A732E",
-"v$ c #110227",
-"w$ c #110324",
-"x$ c #811924",
-"y$ c #A04323",
-"z$ c #250721",
-"A$ c #1A041F",
-"B$ c #1E011D",
-"C$ c #1C011C",
-"D$ c #18031D",
-"E$ c #130721",
-"F$ c #6F3623",
-"G$ c #6B3622",
-"H$ c #1A001A",
-"I$ c #14011F",
-"J$ c #12011E",
-"K$ c #11011C",
-"L$ c #140117",
-"M$ c #170015",
-"N$ c #150016",
-"O$ c #120119",
-"P$ c #11011B",
-"Q$ c #11001A",
-"R$ c #130018",
-"S$ c #170118",
-"T$ c #170119",
-"U$ c #18021E",
-"V$ c #1A0126",
-"W$ c #6F2332",
-"X$ c #E5563B",
-"Y$ c #F1B83F",
-"Z$ c #F6CC38",
-"`$ c #9D7A2D",
-" % c #130123",
-".% c #130320",
-"+% c #2A0721",
-"@% c #B00E24",
-"#% c #7D0B23",
-"$% c #1F0522",
-"%% c #1E0220",
-"&% c #1D011E",
-"*% c #1A031E",
-"=% c #15051F",
-"-% c #241322",
-";% c #A32F23",
-">% c #670E21",
-",% c #1C001A",
-"'% c #19001A",
-")% c #180016",
-"!% c #160118",
-"~% c #140219",
-"{% c #11021C",
-"]% c #10021E",
-"^% c #0F011D",
-"/% c #170117",
-"(% c #160219",
-"_% c #17041D",
-":% c #190523",
-"<% c #8C042E",
-"[% c #B65838",
-"}% c #E9D73F",
-"|% c #EED43E",
-"1% c #D85538",
-"2% c #493129",
-"3% c #130120",
-"4% c #15021D",
-"5% c #330822",
-"6% c #8A0825",
-"7% c #3C0424",
-"8% c #1E0322",
-"9% c #1C0321",
-"0% c #180421",
-"a% c #130822",
-"b% c #AF2D24",
-"c% c #BC5623",
-"d% c #2F071F",
-"e% c #1A041C",
-"f% c #1C031C",
-"g% c #1D011C",
-"h% c #160117",
-"i% c #150419",
-"j% c #12081D",
-"k% c #0F0923",
-"l% c #A77027",
-"m% c #A60525",
-"n% c #11021A",
-"o% c #130218",
-"p% c #150319",
-"q% c #16061D",
-"r% c #180923",
-"s% c #9C1D2B",
-"t% c #A32636",
-"u% c #A66E3B",
-"v% c #4B2E3C",
-"w% c #412C36",
-"x% c #36012D",
-"y% c #140123",
-"z% c #17001E",
-"A% c #19011B",
-"B% c #1A0421",
-"C% c #340425",
-"D% c #9E0326",
-"E% c #1F0424",
-"F% c #1C0524",
-"G% c #180724",
-"H% c #A91024",
-"I% c #D55D24",
-"J% c #90071E",
-"K% c #3C051D",
-"L% c #1C021C",
-"M% c #1C011A",
-"N% c #1D001A",
-"O% c #160116",
-"P% c #150216",
-"Q% c #140217",
-"R% c #140618",
-"S% c #120D1D",
-"T% c #231925",
-"U% c #B16A2E",
-"V% c #FDAC34",
-"W% c #D58631",
-"X% c #280E2A",
-"Y% c #0D0A23",
-"Z% c #0F0920",
-"`% c #120C21",
-" & c #1F1026",
-".& c #A3352E",
-"+& c #EE9F36",
-"@& c #5D2A3C",
-"#& c #960D3C",
-"$& c #970638",
-"%& c #A00330",
-"&& c #4D0126",
-"*& c #1C001F",
-"=& c #280120",
-"-& c #290223",
-";& c #1F0425",
-">& c #260726",
-",& c #340A26",
-"'& c #850925",
-")& c #3A0823",
-"!& c #82071D",
-"~& c #5E071D",
-"{& c #18051C",
-"]& c #18021A",
-"^& c #190118",
-"/& c #160217",
-"(& c #150418",
-"_& c #130618",
-":& c #110718",
-"<& c #10081A",
-"[& c #110D1D",
-"}& c #291C24",
-"|& c #A73B2D",
-"1& c #FD6B36",
-"2& c #FD853C",
-"3& c #FD863B",
-"4& c #C24A35",
-"5& c #6B442F",
-"6& c #6D302D",
-"7& c #6E252E",
-"8& c #8E3B32",
-"9& c #DE7739",
-"0& c #F48E3F",
-"a& c #DD8D41",
-"b& c #854F3D",
-"c& c #7E2D35",
-"d& c #33082B",
-"e& c #1C0222",
-"f& c #20001F",
-"g& c #1F0222",
-"h& c #1A0524",
-"i& c #440C27",
-"j& c #BC1427",
-"k& c #20041B",
-"l& c #53061C",
-"m& c #25071B",
-"n& c #11061A",
-"o& c #130418",
-"p& c #140317",
-"q& c #150217",
-"r& c #160318",
-"s& c #12051B",
-"t& c #100C1D",
-"u& c #0E101E",
-"v& c #0C121F",
-"w& c #0C1321",
-"x& c #781725",
-"y& c #B25D2C",
-"z& c #FA6335",
-"A& c #FD633C",
-"B& c #FE6D42",
-"C& c #FE7C42",
-"D& c #FE813F",
-"E& c #FE873C",
-"F& c #FD743B",
-"G& c #FB683B",
-"H& c #FA7A3E",
-"I& c #F98242",
-"J& c #F97844",
-"K& c #F98943",
-"L& c #F79C3D",
-"M& c #A25133",
-"N& c #280B28",
-"O& c #1D021F",
-"P& c #1F011C",
-"Q& c #280321",
-"R& c #1C0724",
-"S& c #3F1C27",
-"T& c #D33C27",
-"U& c #0E061B",
-"V& c #0C091C",
-"W& c #0C0A1B",
-"X& c #0E091A",
-"Y& c #11081B",
-"Z& c #100A20",
-"`& c #0E0D23",
-" * c #551227",
-".* c #B21829",
-"+* c #C42329",
-"@* c #C62C29",
-"#* c #C55429",
-"$* c #E76F2B",
-"%* c #F14232",
-"&* c #F95E3A",
-"** c #FC6740",
-"=* c #FE6E45",
-"-* c #FE7246",
-";* c #FE7545",
-">* c #FE7744",
-",* c #FD7745",
-"'* c #FD7845",
-")* c #FD7847",
-"!* c #FD7948",
-"~* c #FD7B44",
-"{* c #FC7C3B",
-"]* c #6F3130",
-"^* c #140B24",
-"/* c #19031D",
-"(* c #1C011B",
-"_* c #5A011F",
-":* c #B70421",
-"<* c #380824",
-"[* c #3E2626",
-"}* c #9F5626",
-"|* c #13051E",
-"1* c #360A21",
-"2* c #361223",
-"3* c #371724",
-"4* c #381824",
-"5* c #3B1524",
-"6* c #3E1E26",
-"7* c #471A29",
-"8* c #DB252E",
-"9* c #ED2733",
-"0* c #EE5436",
-"a* c #F04237",
-"b* c #F33934",
-"c* c #F53D2F",
-"d* c #D7312B",
-"e* c #AF212B",
-"f* c #3A2C31",
-"g* c #F65F39",
-"h* c #FB6F41",
-"i* c #FD6D45",
-"j* c #FE7047",
-"k* c #FE7647",
-"l* c #FE7847",
-"m* c #FE7848",
-"n* c #FE7748",
-"o* c #FE7948",
-"p* c #FE7C48",
-"q* c #FE7C47",
-"r* c #FE7642",
-"s* c #FE7439",
-"t* c #6D332C",
-"u* c #100B21",
-"v* c #16031B",
-"w* c #2B001B",
-"x* c #22011F",
-"y* c #220521",
-"z* c #1B0A23",
-"A* c #421425",
-"B* c #951924",
-"C* c #381023",
-"D* c #E94028",
-"E* c #E7302B",
-"F* c #EF432D",
-"G* c #F4302E",
-"H* c #F32C30",
-"I* c #CB4432",
-"J* c #DD3235",
-"K* c #EF4B3A",
-"L* c #F0333E",
-"M* c #CC3D3F",
-"N* c #E4313C",
-"O* c #F34834",
-"P* c #D13E2C",
-"Q* c #431825",
-"R* c #0E1424",
-"S* c #3C202C",
-"T* c #F15537",
-"U* c #F97140",
-"V* c #FC6E45",
-"W* c #FE7547",
-"X* c #FE7947",
-"Y* c #FE7B48",
-"Z* c #FE7D48",
-"`* c #FE8047",
-" = c #FE7A42",
-".= c #FE7A38",
-"+= c #6D442B",
-"@= c #0F0B21",
-"#= c #15031A",
-"$= c #49001B",
-"%= c #2F001C",
-"&= c #21021E",
-"*= c #220620",
-"== c #1B0D23",
-"-= c #641625",
-";= c #951823",
-">= c #390F25",
-",= c #AC3A2A",
-"'= c #B6492E",
-")= c #ED7531",
-"!= c #F45A34",
-"~= c #F54C36",
-"{= c #C72D39",
-"]= c #DE283C",
-"^= c #F33B40",
-"/= c #F34142",
-"(= c #D0393F",
-"_= c #E72E39",
-":= c #DB3C2E",
-"<= c #461724",
-"[= c #0F0D1E",
-"}= c #140B1E",
-"|= c #341427",
-"1= c #CB4834",
-"2= c #F7743F",
-"3= c #FB7145",
-"4= c #FE7747",
-"5= c #FE7A47",
-"6= c #FF7B48",
-"7= c #FF7C48",
-"8= c #FE7F47",
-"9= c #FE8247",
-"0= c #FE8642",
-"a= c #FE8439",
-"b= c #6D442D",
-"c= c #0F0A21",
-"d= c #14031A",
-"e= c #20031D",
-"f= c #210821",
-"g= c #191024",
-"h= c #CC1C25",
-"i= c #961423",
-"j= c #2C162C",
-"k= c #BD242E",
-"l= c #EF2C31",
-"m= c #F54C34",
-"n= c #F34037",
-"o= c #F5353A",
-"p= c #F7413D",
-"q= c #F8423D",
-"r= c #F93A39",
-"s= c #F95731",
-"t= c #341425",
-"u= c #110A1D",
-"v= c #140619",
-"w= c #18051B",
-"x= c #200F26",
-"y= c #864833",
-"z= c #F8773F",
-"A= c #FC7445",
-"B= c #FF7E48",
-"C= c #FF7E49",
-"D= c #FF7D49",
-"E= c #FF7D48",
-"F= c #FE8347",
-"G= c #FE8743",
-"H= c #FE893B",
-"I= c #6E452F",
-"J= c #100E23",
-"K= c #14041A",
-"L= c #55041D",
-"M= c #540921",
-"N= c #161124",
-"O= c #CE6A25",
-"P= c #3F1129",
-"Q= c #170A29",
-"R= c #0F0F29",
-"S= c #15132B",
-"T= c #1E182D",
-"U= c #A82B3D",
-"V= c #CB6633",
-"W= c #CC6932",
-"X= c #CC3D2D",
-"Y= c #331225",
-"Z= c #0F091C",
-"`= c #120417",
-" - c #160216",
-".- c #190419",
-"+- c #210F26",
-"@- c #8C4934",
-"#- c #F97A40",
-"$- c #FC7545",
-"%- c #FF7B49",
-"&- c #FE7D46",
-"*- c #FE7E43",
-"=- c #FD7B3E",
-"-- c #FA6934",
-";- c #532328",
-">- c #130B1D",
-",- c #150519",
-"'- c #14041C",
-")- c #120920",
-"!- c #C43624",
-"~- c #A21E23",
-"{- c #F87C30",
-"]- c #C9302D",
-"^- c #300F2A",
-"/- c #591129",
-"(- c #171328",
-"_- c #171628",
-":- c #141829",
-"<- c #101A2B",
-"[- c #0F172B",
-"}- c #0F1226",
-"|- c #0E0C20",
-"1- c #100619",
-"2- c #140316",
-"3- c #19051B",
-"4- c #3C1428",
-"5- c #E04B36",
-"6- c #FA7B41",
-"7- c #FD7346",
-"8- c #FE7548",
-"9- c #FF7849",
-"0- c #FF7749",
-"a- c #FE7B47",
-"b- c #FE7945",
-"c- c #FC7740",
-"d- c #FA7E39",
-"e- c #C1432F",
-"f- c #131523",
-"g- c #130A1C",
-"h- c #420621",
-"i- c #D08423",
-"j- c #F87739",
-"k- c #C03D37",
-"l- c #962B34",
-"m- c #A14332",
-"n- c #E54B30",
-"o- c #9E3E2F",
-"p- c #7F262E",
-"q- c #922D2E",
-"r- c #9C4B2E",
-"s- c #65212C",
-"t- c #101628",
-"u- c #101022",
-"v- c #11091C",
-"w- c #130619",
-"x- c #160A1E",
-"y- c #43252C",
-"z- c #F66439",
-"A- c #FA6942",
-"B- c #FD6C47",
-"C- c #FE6E48",
-"D- c #FE6F48",
-"E- c #FE7049",
-"F- c #FE714A",
-"G- c #FE744A",
-"H- c #FE7846",
-"I- c #FD7243",
-"J- c #FC703E",
-"K- c #FA6C37",
-"L- c #81312B",
-"M- c #121123",
-"N- c #15071D",
-"O- c #16031A",
-"P- c #17021B",
-"Q- c #8F3D22",
-"R- c #F8393E",
-"S- c #E42A3D",
-"T- c #E7473B",
-"U- c #FB503B",
-"V- c #FB4F3A",
-"W- c #F95439",
-"X- c #ED4C38",
-"Y- c #F45938",
-"Z- c #FB6537",
-"`- c #EA5236",
-" ; c #CE6232",
-".; c #CD392C",
-"+; c #181425",
-"@; c #120F21",
-"#; c #130D20",
-"$; c #151225",
-"%; c #903431",
-"&; c #F8703D",
-"*; c #FB6344",
-"=; c #FD6748",
-"-; c #FE6849",
-";; c #FE6949",
-">; c #FE6A49",
-",; c #FE6C4A",
-"'; c #FE704A",
-"); c #FE734A",
-"!; c #FE7449",
-"~; c #FE7347",
-"{; c #FE7145",
-"]; c #FD6C42",
-"^; c #FD753D",
-"/; c #F36E35",
-"(; c #CB452C",
-"_; c #600D24",
-":; c #1C061F",
-"<; c #1E031F",
-"[; c #5B3821",
-"}; c #CE9822",
-"|; c #FA4341",
-"1; c #FB4341",
-"2; c #FC4541",
-"3; c #FC4542",
-"4; c #FC4143",
-"5; c #FC4D42",
-"6; c #FB5042",
-"7; c #FB5342",
-"8; c #FC5242",
-"9; c #FD4F40",
-"0; c #FD503E",
-"a; c #FB6339",
-"b; c #F45E33",
-"c; c #A12A2E",
-"d; c #401E2C",
-"e; c #452D2F",
-"f; c #F74F38",
-"g; c #FA5940",
-"h; c #FC6245",
-"i; c #FE6447",
-"j; c #FE6449",
-"k; c #FE6549",
-"l; c #FE6749",
-"m; c #FE6B49",
-"n; c #FE6D49",
-"o; c #FE6D48",
-"p; c #FE6D47",
-"q; c #FE6D45",
-"r; c #FE6C44",
-"s; c #FE6A42",
-"t; c #FE663C",
-"u; c #FC6233",
-"v; c #752129",
-"w; c #1F0922",
-"x; c #750520",
-"y; c #81061F",
-"z; c #FA3D42",
-"A; c #FB4142",
-"B; c #FD4543",
-"C; c #FD4844",
-"D; c #FD4A45",
-"E; c #FD4D45",
-"F; c #FD5045",
-"G; c #FD5345",
-"H; c #FE5346",
-"I; c #FE5445",
-"J; c #FD5444",
-"K; c #FC4F41",
-"L; c #FA513D",
-"M; c #F95339",
-"N; c #F63736",
-"O; c #F75737",
-"P; c #F95F3B",
-"Q; c #FB5840",
-"R; c #FD5F43",
-"S; c #FE6345",
-"T; c #FE6547",
-"U; c #FE6548",
-"V; c #FE6448",
-"W; c #FE6248",
-"X; c #FE6348",
-"Y; c #FE6748",
-"Z; c #FE6848",
-"`; c #FE6846",
-" > c #FE6A45",
-".> c #FE6D43",
-"+> c #FE703F",
-"@> c #FC6F36",
-"#> c #6F302B",
-"$> c #140A22",
-"%> c #FA3B42",
-"&> c #FC4243",
-"*> c #FD4744",
-"=> c #FE4A45",
-"-> c #FE4C47",
-";> c #FE4D47",
-">> c #FE5047",
-",> c #FE5347",
-"'> c #FE5447",
-")> c #FD5246",
-"!> c #FB503F",
-"~> c #FA543D",
-"{> c #9B3D3B",
-"]> c #A3433B",
-"^> c #F9683D",
-"/> c #FC6940",
-"(> c #FE6342",
-"_> c #FE6645",
-":> c #FE6646",
-"<> c #FE6147",
-"[> c #FE6048",
-"}> c #FE6148",
-"|> c #FE6746",
-"1> c #FE6A46",
-"2> c #FE6F45",
-"3> c #FE7441",
-"4> c #FC7D39",
-"5> c #6C422E",
-"6> c #0F0F23",
-"7> c #FA4142",
-"8> c #FC4643",
-"9> c #FE4D46",
-"0> c #FE4E47",
-"a> c #FE4F48",
-"b> c #FE5148",
-"c> c #FE5348",
-"d> c #FE5548",
-"e> c #FE5247",
-"f> c #FD5445",
-"g> c #FC5544",
-"h> c #F96041",
-"i> c #D33F3D",
-"j> c #392D39",
-"k> c #973C38",
-"l> c #F94E3A",
-"m> c #FD693E",
-"n> c #FE6C43",
-"o> c #FE6047",
-"p> c #FE5D47",
-"q> c #FE5E48",
-"r> c #FE6948",
-"s> c #FE6947",
-"t> c #FE6B47",
-"u> c #FE6E46",
-"v> c #FD6D43",
-"w> c #FB723D",
-"x> c #D54A33",
-"y> c #301C29",
-"z> c #FB4A42",
-"A> c #FD4B44",
-"B> c #FE4F47",
-"C> c #FE5048",
-"D> c #FE5648",
-"E> c #FE5848",
-"F> c #FE5747",
-"G> c #FE5547",
-"H> c #FC5945",
-"I> c #F95742",
-"J> c #F3543D",
-"K> c #A33336",
-"L> c #302032",
-"M> c #152433",
-"N> c #CD3E38",
-"O> c #FD5A3F",
-"P> c #FE6343",
-"Q> c #FE6446",
-"R> c #FE6247",
-"S> c #FE6A47",
-"T> c #FC6542",
-"U> c #FB6A3B",
-"V> c #FA6D34",
-"W> c #D73C2D",
-"X> c #442428",
-"Y> c #281323",
-"Z> c #FD4E42",
-"`> c #FD4D43",
-" , c #FE4D45",
-"., c #FE5248",
-"+, c #FE5947",
-"@, c #FE5C47",
-"#, c #FE5B47",
-"$, c #FE5A47",
-"%, c #FE5847",
-"&, c #FC5C45",
-"*, c #F95B43",
-"=, c #F3613F",
-"-, c #E74F37",
-";, c #8C2431",
-">, c #161E2F",
-",, c #CD4E33",
-"', c #FD503A",
-"), c #FE5D40",
-"!, c #FE6445",
-"~, c #FE6946",
-"{, c #FE6847",
-"], c #FE6747",
-"^, c #FD6644",
-"/, c #FD6241",
-"(, c #FD5B3D",
-"_, c #FE6739",
-":, c #FE6135",
-"<, c #AB4830",
-"[, c #733E2A",
-"}, c #161224",
-"|, c #FC4E42",
-"1, c #FE4D44",
-"2, c #FE4E46",
-"3, c #FE5147",
-"4, c #FE5E47",
-"5, c #FD5C46",
-"6, c #FA5B44",
-"7, c #F45441",
-"8, c #EB393A",
-"9, c #CC3433",
-"0, c #47212F",
-"a, c #59242F",
-"b, c #FC6734",
-"c, c #FC6F3A",
-"d, c #FC723E",
-"e, c #FD6540",
-"f, c #FE6442",
-"g, c #FE6643",
-"h, c #FE6944",
-"i, c #FE6546",
-"j, c #FE6444",
-"k, c #FE6143",
-"l, c #FE5E41",
-"m, c #FE613F",
-"n, c #FE683C",
-"o, c #FE7937",
-"p, c #A25030",
-"q, c #692629",
-"r, c #151122",
-"s, c #FA573F",
-"t, c #FB4D40",
-"u, c #FC4F43",
-"v, c #FE5246",
-"w, c #FF6347",
-"x, c #FE5F48",
-"y, c #F65942",
-"z, c #F0493D",
-"A, c #ED3736",
-"B, c #73262F",
-"C, c #10152C",
-"D, c #3B292F",
-"E, c #363034",
-"F, c #AC3938",
-"G, c #FC6B3B",
-"H, c #FD763C",
-"I, c #FE6D3F",
-"J, c #FE6341",
-"K, c #FE6642",
-"L, c #FE6745",
-"M, c #FE6245",
-"N, c #FE6244",
-"O, c #FE6841",
-"P, c #FF683B",
-"Q, c #EC7035",
-"R, c #D0412D",
-"S, c #3A1627",
-"T, c #CF3938",
-"U, c #F6543C",
-"V, c #FB5040",
-"W, c #FD5544",
-"X, c #FE5A48",
-"Y, c #FE5D48",
-"Z, c #FE5F47",
-"`, c #FF6147",
-" ' c #FD5C45",
-".' c #FB5B43",
-"+' c #FA5A42",
-"@' c #F76040",
-"#' c #F4623D",
-"$' c #F26D38",
-"%' c #EC4130",
-"&' c #380E2B",
-"*' c #13122C",
-"=' c #362D31",
-"-' c #353435",
-";' c #352E37",
-">' c #2D3337",
-",' c #CC5838",
-"'' c #CD6F3A",
-")' c #CE6E3D",
-"!' c #FE793F",
-"~' c #FD7541",
-"{' c #FD6243",
-"]' c #FE6545",
-"^' c #FF6543",
-"/' c #FF6240",
-"(' c #FE723B",
-"_' c #FE8034",
-":' c #442D2C",
-"<' c #311725",
-"[' c #222830",
-"}' c #B73B36",
-"|' c #F94C3D",
-"1' c #FD5543",
-"2' c #FE5B48",
-"3' c #FF5E47",
-"4' c #FE5C48",
-"5' c #FC5B44",
-"6' c #F95640",
-"7' c #C34E3D",
-"8' c #A45A3A",
-"9' c #F37438",
-"0' c #F28935",
-"a' c #AF422F",
-"b' c #240D2B",
-"c' c #88292F",
-"d' c #FA8E34",
-"e' c #FC7E38",
-"f' c #FC5939",
-"g' c #694A37",
-"h' c #693437",
-"i' c #382638",
-"j' c #142439",
-"k' c #9F483A",
-"l' c #C45E3C",
-"m' c #FD7240",
-"n' c #FF6645",
-"o' c #FF6245",
-"p' c #FF6045",
-"q' c #FF6146",
-"r' c #FF6246",
-"s' c #FF6446",
-"t' c #FF6545",
-"u' c #FE763F",
-"v' c #FE7237",
-"w' c #C65331",
-"x' c #3D272A",
-"y' c #0D1E2B",
-"z' c #683032",
-"A' c #F9453A",
-"B' c #FD5341",
-"C' c #FE5A46",
-"D' c #FF5A48",
-"E' c #FE5948",
-"F' c #FD5A47",
-"G' c #FC5D43",
-"H' c #F95B3D",
-"I' c #713F37",
-"J' c #1E2D32",
-"K' c #C44531",
-"L' c #EF7A2F",
-"M' c #6B2E2C",
-"N' c #0F0E2C",
-"O' c #F56633",
-"P' c #FA803A",
-"Q' c #FC673E",
-"R' c #FD673E",
-"S' c #FC6F3C",
-"T' c #FA6E3B",
-"U' c #C6633A",
-"V' c #A06739",
-"W' c #835638",
-"X' c #381F38",
-"Y' c #713B38",
-"Z' c #7B503C",
-"`' c #FE7741",
-" ) c #FE7344",
-".) c #FE6D46",
-"+) c #FF6946",
-"@) c #FF5E46",
-"#) c #FF5D46",
-"$) c #FF5D47",
-"%) c #FF5F48",
-"&) c #FF6248",
-"*) c #FE6941",
-"=) c #FC783C",
-"-) c #C46B35",
-";) c #892730",
-">) c #111629",
-",) c #1F2630",
-"') c #AD3939",
-")) c #FC5D41",
-"!) c #FE5946",
-"~) c #FF5848",
-"{) c #FE5549",
-"]) c #FC5E42",
-"^) c #FA673B",
-"/) c #DB7033",
-"() c #392E2B",
-"_) c #311A28",
-":) c #3C2127",
-"<) c #1D1027",
-"[) c #92102C",
-"}) c #F58336",
-"|) c #FA673E",
-"1) c #FD6642",
-"2) c #FD5A41",
-"3) c #FC6D41",
-"4) c #FC6D3F",
-"5) c #FD683E",
-"6) c #F38C39",
-"7) c #CE6535",
-"8) c #612E34",
-"9) c #1D2637",
-"0) c #71513E",
-"a) c #FF6847",
-"b) c #FF5F47",
-"c) c #FF5A46",
-"d) c #FF5847",
-"e) c #FF5748",
-"f) c #FF594A",
-"g) c #FF5E4B",
-"h) c #FE654C",
-"i) c #FE694B",
-"j) c #FE6B48",
-"k) c #FC6A43",
-"l) c #F7683E",
-"m) c #EC6E39",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" . + @ # $ % ",
-" & * = - ; > , ' ) ! ~ ",
-" { ] ^ / ( _ : < [ } | 1 2 ",
-" 3 4 5 6 7 8 9 0 a b c d e f g h i j ",
-" k l m n o p q r s t u v w x y z A B C D ",
-" E F G H I J K L M N O P Q R S T U V W X Y Z ` ",
-" ...+.@.#.$.%.&.*.=.-.;.>.,.S '.).!.~.{.].^./.(._. ",
-" :.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.!.S f.g.h.i.j.k. ",
-" l.m.n.o.p.q.r.s.t.u.J v.w.x.y.z.A.c.d.d.B.C.D.E.F.G.H.I. ",
-" J.K.L.M.N.O.P.Q.R.t S.T.U.V.W.X.Y.Z.`. +d.d..+B.'.++@+#+$+%+ ",
-" &+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+d.2+3+4+d.5+6+7+8+9+0+ ",
-" a+b+c+d+e+f+g+h+i+j+k+l+m+n+^+o+p+q+r+s+t+u+v+b.w+x+y+z+A+w+B+C+D+E+F+G+ ",
-" H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+Q ,.X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@#@-@;@>@,@'@ ",
-" )@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@3@R ,.4@5@6@7@8@9@0@a@#@b@c@=@d@e@f@g@>@h@i@j@ ",
-" k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@^+R S z@A@z.q+B@C@D@E@F@G@H@#@e@#@#@f@g@I@J@K@L@ ",
-" M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#+#S A@@###$#%#&#*#=#-#f@B+B+B+f@;#>#,#'#)# ",
-" !#~#{#]#^#/#(#(#_#:#<#[#}#|#1#^+.#S +#+#z@2#3#4#5#6#7#8#9#0#A.B+B+a#A.@@b#c#d# ",
-" e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#.#w#S R ^+x#y#z#A#B#C#D#-#A.a#`.`.b.g@E#d#F# ",
-" G#0@H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#>.W#3@v#R R X+X#Y#s#Z#`# $.$+$@$g@f@5+5+#$6+$$%$&$ ",
-" *$=$-$;$>$,$'$)$!$~${$]$^$/$($_$*$u#:$Q 3@,.X+z.<$[$}$|$1$2$3$4$5$6$7$e@8$#$G@9$0$a$ ",
-" ,.4@E#b$c$d$e$f$g$h$i$j$k$l$m$n$`@>.:$o$3@,. #a.p$q$r$s$t$u$v$w$x$y$z$A$B$#@C$D$E$F$G$ ",
-" R S H$v+I$J$K$n+L$:$o$o$M$N$L$O$P$Q$R$N$o$3@S$T$U$V$W$X$Y$Z$`$ %.%+%@%#%$%%%&%*%=%-%;%>% ",
-" E.,%~.'%Z.4@v W#o$)%)%)%Q !%~%{%]%^%Q$u u#/%(%_%:%<%[%}%|%1%2%3%4%=%5%6%7%8%9%0%a%b%c%d% ",
-" e%f%g%a#,%,%z@R 3@3@3@)%Q h%i%j%k%l%m%{+n%o%p%q%r%s%t%u%v%w%x%y%z%A%*%B%C%D%E%F%G%H%I% ",
-" J%K%L%M%N%D.S v#)%)%O%P%Q%R%S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&f@a##@=&-&;&>&,&'&)& ",
-" !&~&{&]&^&.#w#^&/%/&(&_&:&<&[&}&|&1&2&3&4&5&6&7&8&9&0&a&b&c&d&e&e@1+5+e@f&g&h&i&j& ",
-" k&l&m&n&o&p&q&r&i%s&3.t&u&v&w&x&y&z&A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&P&1+`.e@f&Q&R&S&T& ",
-" 0 U&V&W&X&<&Y&j%Z&`& *.*+*@*#*$*%*&***=*-*;*>*>*,*'*)*!*~*{*]*^*/*(*a#B+#@_*:*<*[*}* ",
-" |*1*2*3*4*5*6*7*8*9*0*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*E.w*d.e@x*y*z*A*B* ",
-" C*D*E*F*G*H*I*J*K*L*M*N*O*P*Q*R*S*T*U*V*W*l*X*o*o*Y*Z*`* =.=+=@=#='%$=%=e@&=*===-=;= ",
-" >=,='=)=!=~={=]=^=/=(=_=:=<=[=}=|=1=2=3=4=5=p*6=6=7=8=9=0=a=b=c=d=A@~.b.B+e=f=g=h=i= ",
-" j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=A=5=Z*B=C=D=E=8=F=G=H=I=J=K=S$R z@'%L=M=N=O= ",
-" P=Q=R=S=T=U=V=W=X=Y=Z=`= -.-+-@-#-$-5=p*E=D=%-%-q*&-*-=---;->-,-/%3@^+'-)-!-~- ",
-" {-]-^-/-(-_-:-<-[-}-|-1-2- -3-4-5-6-7-8-n*m*9-0-9-o*a-b-c-d-e-f-g-(&h%w c h-i- ",
-" j-k-l-m-n-o-p-q-r-s-t-u-v-w-,-x-y-z-A-B-C-D-E-E-F-G-_@m*H-I-J-K-L-M-N-O-P-(+Q- ",
-" R-S-T-U-V-W-X-Y-Z-`- ;.;+;@;#;$;%;&;*;=;-;-;;;>;,;';);!;~;{;];^;/;(;_;:;<;[;}; ",
-" |;1;2;3;4;5;6;7;8;9;0;a;b;c;d;e;f;g;h;i;j;j;k;k;l;m;n;o;p;q;r;s;t;u;v;w;x;y; ",
-" z;A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;k;Y;Z;`; >r;.>+>@>#>$> ",
-" %>&>*>=>->;>>>,>'>,>)>F;8;!>~>{>]>^>/>(>_>:>i;<>[>X;}>i;|>1>q;2>3>4>5>6> ",
-" 7>8>=>9>0>a>b>c>d>,>e>e>f>g>h>i>j>k>l>m>n>:>i;o>p>q>W;r>s>t>p;u>v>w>x>y> ",
-" z>A>9>0>B>C>c>D>E>F>G>G>F>H>I>J>K>L>M>N>O>P>Q>R>o>R>T;s>S>S>S>t>1>T>U>V>W>X>Y> ",
-" Z>`> ,9>B>.,D>+,@,#,$,%,$,&,*,=,-,;,>,,,',),P>!,!,_>~,t>s>{,],{,],^,/,(,_,:,<,[,}, ",
-" |,`>1,2,3,G>+,4,o>o>4,@,@,5,6,7,8,9,0,a,b,c,d,e,f,g,h, >~,|>T;T;T;i,j,k,l,m,n,o,p,q,r, ",
-" s,t,u,v,G>%,@,o>w,R>x,p>@,5,6,y,z,A,B,C,D,E,F,G,H,I,J,K,L,L,i,i;i;i;Q>S;M,N,P>O,P,Q,R,S, ",
-" T,U,V,W,%,X,Y,Z,`,[>q>@, '.'+'@'#'$'%'&'*'='-';'>',''')'!'~'{'N,i,:>_>]'M,M,Q>_>^'/'('_':'<' ",
-" ['}'|'1'$,X,2'p>3'4'2'@,5'6'7'8'9'0'a'b'c'd'e'f'g'h'i'j'k'l'd,m'g, > >n'o'p'q'r's't'.>u'v'w'x' ",
-" y'z'A'B'C'X,X,2'D'E'E'F'G'H'I'J'K'L'M'N'O'P'Q'R'S'T'U'V'W'X'Y'Z'`' ).)+)r'@)#)$)%)&)l;1>*)=)-);) ",
-" >),)')))!)X,E'X,~){)d>!)])^)/)()_):)<)[)})|)1)f,2)3)4)5)6)7)8)9)0)*--*a)b)c)d)e)f)g)h)i)j)k)l)m) ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/trunk/ext/json/lib/json/pure.rb b/trunk/ext/json/lib/json/pure.rb
deleted file mode 100644
index b86d905523..0000000000
--- a/trunk/ext/json/lib/json/pure.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'json/common'
-require 'json/pure/parser'
-require 'json/pure/generator'
-
-module JSON
- begin
- require 'iconv'
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- # Iconv doesn't support big endian utf-16. Let's try to hack this manually
- # into the converters.
- begin
- old_verbose, $VERBSOSE = $VERBOSE, nil
- # An iconv instance to convert from UTF8 to UTF16 Big Endian.
- UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
- # An iconv instance to convert from UTF16 Big Endian to UTF8.
- UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
- UTF8toUTF16.iconv('no bom')
- if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
-
- def iconv(string) # :nodoc:
- result = @iconv.iconv(string)
- JSON.swap!(result)
- end
- end
- UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
- end
- if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
- swapper = Class.new do
- def initialize(iconv) # :nodoc:
- @iconv = iconv
- end
-
- def iconv(string) # :nodoc:
- string = JSON.swap!(string.dup)
- @iconv.iconv(string)
- end
- end
- UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
- end
- rescue Errno::EINVAL, Iconv::InvalidEncoding
- raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
- ensure
- $VERBOSE = old_verbose
- end
- rescue LoadError
- raise MissingUnicodeSupport,
- "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
- end
-
- # Swap consecutive bytes of _string_ in place.
- def self.swap!(string) # :nodoc:
- 0.upto(string.size / 2) do |i|
- break unless string[2 * i + 1]
- string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
- end
- string
- end
-
- # This module holds all the modules/classes that implement JSON's
- # functionality in pure ruby.
- module Pure
- $DEBUG and warn "Using pure library for JSON."
- JSON.parser = Parser
- JSON.generator = Generator
- end
-end
diff --git a/trunk/ext/json/lib/json/pure/generator.rb b/trunk/ext/json/lib/json/pure/generator.rb
deleted file mode 100644
index c8bbfd09ee..0000000000
--- a/trunk/ext/json/lib/json/pure/generator.rb
+++ /dev/null
@@ -1,394 +0,0 @@
-module JSON
- MAP = {
- "\x0" => '\u0000',
- "\x1" => '\u0001',
- "\x2" => '\u0002',
- "\x3" => '\u0003',
- "\x4" => '\u0004',
- "\x5" => '\u0005',
- "\x6" => '\u0006',
- "\x7" => '\u0007',
- "\b" => '\b',
- "\t" => '\t',
- "\n" => '\n',
- "\xb" => '\u000b',
- "\f" => '\f',
- "\r" => '\r',
- "\xe" => '\u000e',
- "\xf" => '\u000f',
- "\x10" => '\u0010',
- "\x11" => '\u0011',
- "\x12" => '\u0012',
- "\x13" => '\u0013',
- "\x14" => '\u0014',
- "\x15" => '\u0015',
- "\x16" => '\u0016',
- "\x17" => '\u0017',
- "\x18" => '\u0018',
- "\x19" => '\u0019',
- "\x1a" => '\u001a',
- "\x1b" => '\u001b',
- "\x1c" => '\u001c',
- "\x1d" => '\u001d',
- "\x1e" => '\u001e',
- "\x1f" => '\u001f',
- '"' => '\"',
- '\\' => '\\\\',
- '/' => '\/',
- } # :nodoc:
-
- # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
- # UTF16 big endian characters as \u????, and return it.
- def utf8_to_json(string) # :nodoc:
- string = string.gsub(/["\\\/\x0-\x1f]/) { MAP[$&] }
- string.gsub!(/(
- (?:
- [\xc2-\xdf][\x80-\xbf] |
- [\xe0-\xef][\x80-\xbf]{2} |
- [\xf0-\xf4][\x80-\xbf]{3}
- )+ |
- [\x80-\xc1\xf5-\xff] # invalid
- )/nx) { |c|
- c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
- s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
- s.gsub!(/.{4}/n, '\\\\u\&')
- }
- string
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
- end
- module_function :utf8_to_json
-
- module Pure
- module Generator
- # This class is used to create State instances, that are use to hold data
- # while generating a JSON text from a a Ruby data structure.
- class State
- # Creates a State object from _opts_, which ought to be Hash to create
- # a new State instance configured by _opts_, something else to create
- # an unconfigured instance. If _opts_ is a State object, it is just
- # returned.
- def self.from_state(opts)
- case opts
- when self
- opts
- when Hash
- new(opts)
- else
- new
- end
- end
-
- # Instantiates a new State object, configured by _opts_.
- #
- # _opts_ can have the following keys:
- #
- # * *indent*: a string used to indent levels (default: ''),
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
- # * *check_circular*: true if checking for circular data structures
- # should be done (the default), false otherwise.
- # * *check_circular*: true if checking for circular data structures
- # should be done, false (the default) otherwise.
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
- # generated, otherwise an exception is thrown, if these values are
- # encountered. This options defaults to false.
- def initialize(opts = {})
- @seen = {}
- @indent = ''
- @space = ''
- @space_before = ''
- @object_nl = ''
- @array_nl = ''
- @check_circular = true
- @allow_nan = false
- configure opts
- end
-
- # This string is used to indent levels in the JSON text.
- attr_accessor :indent
-
- # This string is used to insert a space between the tokens in a JSON
- # string.
- attr_accessor :space
-
- # This string is used to insert a space before the ':' in JSON objects.
- attr_accessor :space_before
-
- # This string is put at the end of a line that holds a JSON object (or
- # Hash).
- attr_accessor :object_nl
-
- # This string is put at the end of a line that holds a JSON array.
- attr_accessor :array_nl
-
- # This integer returns the maximum level of data structure nesting in
- # the generated JSON, max_nesting = 0 if no maximum is checked.
- attr_accessor :max_nesting
-
- def check_max_nesting(depth) # :nodoc:
- return if @max_nesting.zero?
- current_nesting = depth + 1
- current_nesting > @max_nesting and
- raise NestingError, "nesting of #{current_nesting} is too deep"
- end
-
- # Returns true, if circular data structures should be checked,
- # otherwise returns false.
- def check_circular?
- @check_circular
- end
-
- # Returns true if NaN, Infinity, and -Infinity should be considered as
- # valid JSON and output.
- def allow_nan?
- @allow_nan
- end
-
- # Returns _true_, if _object_ was already seen during this generating
- # run.
- def seen?(object)
- @seen.key?(object.__id__)
- end
-
- # Remember _object_, to find out if it was already encountered (if a
- # cyclic data structure is if a cyclic data structure is rendered).
- def remember(object)
- @seen[object.__id__] = true
- end
-
- # Forget _object_ for this generating run.
- def forget(object)
- @seen.delete object.__id__
- end
-
- # Configure this State instance with the Hash _opts_, and return
- # itself.
- def configure(opts)
- @indent = opts[:indent] if opts.key?(:indent)
- @space = opts[:space] if opts.key?(:space)
- @space_before = opts[:space_before] if opts.key?(:space_before)
- @object_nl = opts[:object_nl] if opts.key?(:object_nl)
- @array_nl = opts[:array_nl] if opts.key?(:array_nl)
- @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
- @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
- if !opts.key?(:max_nesting) # defaults to 19
- @max_nesting = 19
- elsif opts[:max_nesting]
- @max_nesting = opts[:max_nesting]
- else
- @max_nesting = 0
- end
- self
- end
-
- # Returns the configuration instance variables as a hash, that can be
- # passed to the configure method.
- def to_h
- result = {}
- for iv in %w[indent space space_before object_nl array_nl check_circular allow_nan max_nesting]
- result[iv.intern] = instance_variable_get("@#{iv}")
- end
- result
- end
- end
-
- module GeneratorMethods
- module Object
- # Converts this object to a string (calling #to_s), converts
- # it to a JSON string, and returns the result. This is a fallback, if no
- # special method #to_json was defined for some object.
- def to_json(*) to_s.to_json end
- end
-
- module Hash
- # Returns a JSON string containing a JSON object, that is unparsed from
- # this Hash instance.
- # _state_ is a JSON::State object, that can also be used to configure the
- # produced JSON string output further.
- # _depth_ is used to find out nesting depth, to indent accordingly.
- def to_json(state = nil, depth = 0, *)
- if state
- state = JSON.state.from_state(state)
- state.check_max_nesting(depth)
- json_check_circular(state) { json_transform(state, depth) }
- else
- json_transform(state, depth)
- end
- end
-
- private
-
- def json_check_circular(state)
- if state and state.check_circular?
- state.seen?(self) and raise JSON::CircularDatastructure,
- "circular data structures not supported!"
- state.remember self
- end
- yield
- ensure
- state and state.forget self
- end
-
- def json_shift(state, depth)
- state and not state.object_nl.empty? or return ''
- state.indent * depth
- end
-
- def json_transform(state, depth)
- delim = ','
- delim << state.object_nl if state
- result = '{'
- result << state.object_nl if state
- result << map { |key,value|
- s = json_shift(state, depth + 1)
- s << key.to_s.to_json(state, depth + 1)
- s << state.space_before if state
- s << ':'
- s << state.space if state
- s << value.to_json(state, depth + 1)
- }.join(delim)
- result << state.object_nl if state
- result << json_shift(state, depth)
- result << '}'
- result
- end
- end
-
- module Array
- # Returns a JSON string containing a JSON array, that is unparsed from
- # this Array instance.
- # _state_ is a JSON::State object, that can also be used to configure the
- # produced JSON string output further.
- # _depth_ is used to find out nesting depth, to indent accordingly.
- def to_json(state = nil, depth = 0, *)
- if state
- state = JSON.state.from_state(state)
- state.check_max_nesting(depth)
- json_check_circular(state) { json_transform(state, depth) }
- else
- json_transform(state, depth)
- end
- end
-
- private
-
- def json_check_circular(state)
- if state and state.check_circular?
- state.seen?(self) and raise JSON::CircularDatastructure,
- "circular data structures not supported!"
- state.remember self
- end
- yield
- ensure
- state and state.forget self
- end
-
- def json_shift(state, depth)
- state and not state.array_nl.empty? or return ''
- state.indent * depth
- end
-
- def json_transform(state, depth)
- delim = ','
- delim << state.array_nl if state
- result = '['
- result << state.array_nl if state
- result << map { |value|
- json_shift(state, depth + 1) << value.to_json(state, depth + 1)
- }.join(delim)
- result << state.array_nl if state
- result << json_shift(state, depth)
- result << ']'
- result
- end
- end
-
- module Integer
- # Returns a JSON string representation for this Integer number.
- def to_json(*) to_s end
- end
-
- module Float
- # Returns a JSON string representation for this Float number.
- def to_json(state = nil, *)
- case
- when infinite?
- if !state || state.allow_nan?
- to_s
- else
- raise GeneratorError, "#{self} not allowed in JSON"
- end
- when nan?
- if !state || state.allow_nan?
- to_s
- else
- raise GeneratorError, "#{self} not allowed in JSON"
- end
- else
- to_s
- end
- end
- end
-
- module String
- # This string should be encoded with UTF-8 A call to this method
- # returns a JSON string encoded with UTF16 big endian characters as
- # \u????.
- def to_json(*)
- '"' << JSON.utf8_to_json(self) << '"'
- end
-
- # Module that holds the extinding methods if, the String module is
- # included.
- module Extend
- # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
- # key "raw"). The Ruby String can be created by this module method.
- def json_create(o)
- o['raw'].pack('C*')
- end
- end
-
- # Extends _modul_ with the String::Extend module.
- def self.included(modul)
- modul.extend Extend
- end
-
- # This method creates a raw object hash, that can be nested into
- # other data structures and will be unparsed as a raw string. This
- # method should be used, if you want to convert raw strings to JSON
- # instead of UTF-8 strings, e. g. binary data.
- def to_json_raw_object
- {
- JSON.create_id => self.class.name,
- 'raw' => self.unpack('C*'),
- }
- end
-
- # This method creates a JSON text from the result of
- # a call to to_json_raw_object of this String.
- def to_json_raw(*args)
- to_json_raw_object.to_json(*args)
- end
- end
-
- module TrueClass
- # Returns a JSON string for true: 'true'.
- def to_json(*) 'true' end
- end
-
- module FalseClass
- # Returns a JSON string for false: 'false'.
- def to_json(*) 'false' end
- end
-
- module NilClass
- # Returns a JSON string for nil: 'null'.
- def to_json(*) 'null' end
- end
- end
- end
- end
-end
diff --git a/trunk/ext/json/lib/json/pure/parser.rb b/trunk/ext/json/lib/json/pure/parser.rb
deleted file mode 100644
index 39bee54269..0000000000
--- a/trunk/ext/json/lib/json/pure/parser.rb
+++ /dev/null
@@ -1,260 +0,0 @@
-require 'strscan'
-
-module JSON
- module Pure
- # This class implements the JSON parser that is used to parse a JSON string
- # into a Ruby data structure.
- class Parser < StringScanner
- STRING = /" ((?:[^\x0-\x1f"\\] |
- \\["\\\/bfnrt] |
- \\u[0-9a-fA-F]{4} |
- \\[\x20-\xff])*)
- "/nx
- INTEGER = /(-?0|-?[1-9]\d*)/
- FLOAT = /(-?
- (?:0|[1-9]\d*)
- (?:
- \.\d+(?i:e[+-]?\d+) |
- \.\d+ |
- (?i:e[+-]?\d+)
- )
- )/x
- NAN = /NaN/
- INFINITY = /Infinity/
- MINUS_INFINITY = /-Infinity/
- OBJECT_OPEN = /\{/
- OBJECT_CLOSE = /\}/
- ARRAY_OPEN = /\[/
- ARRAY_CLOSE = /\]/
- PAIR_DELIMITER = /:/
- COLLECTION_DELIMITER = /,/
- TRUE = /true/
- FALSE = /false/
- NULL = /null/
- IGNORE = %r(
- (?:
- //[^\n\r]*[\n\r]| # line comments
- /\* # c-style comments
- (?:
- [^*/]| # normal chars
- /[^*]| # slashes that do not start a nested comment
- \*[^/]| # asterisks that do not end this comment
- /(?=\*/) # single slash before this comment's end
- )*
- \*/ # the End of this comment
- |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
- )+
- )mx
-
- UNPARSED = Object.new
-
- # Creates a new JSON::Pure::Parser instance for the string _source_.
- #
- # It will be configured by the _opts_ hash. _opts_ can have the following
- # keys:
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
- # structures. Disable depth checking with :max_nesting => false|nil|0,
- # it defaults to 19.
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
- # to false.
- # * *create_additions*: If set to false, the Parser doesn't create
- # additions even if a matchin class and create_id was found. This option
- # defaults to true.
- def initialize(source, opts = {})
- super
- if !opts.key?(:max_nesting) # defaults to 19
- @max_nesting = 19
- elsif opts[:max_nesting]
- @max_nesting = opts[:max_nesting]
- else
- @max_nesting = 0
- end
- @allow_nan = !!opts[:allow_nan]
- ca = true
- ca = opts[:create_additions] if opts.key?(:create_additions)
- @create_id = ca ? JSON.create_id : nil
- end
-
- alias source string
-
- # Parses the current JSON string _source_ and returns the complete data
- # structure as a result.
- def parse
- reset
- obj = nil
- until eos?
- case
- when scan(OBJECT_OPEN)
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
- @current_nesting = 1
- obj = parse_object
- when scan(ARRAY_OPEN)
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
- @current_nesting = 1
- obj = parse_array
- when skip(IGNORE)
- ;
- else
- raise ParserError, "source '#{peek(20)}' not in JSON!"
- end
- end
- obj or raise ParserError, "source did not contain any JSON!"
- obj
- end
-
- private
-
- # Unescape characters in strings.
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
- UNESCAPE_MAP.update({
- ?" => '"',
- ?\\ => '\\',
- ?/ => '/',
- ?b => "\b",
- ?f => "\f",
- ?n => "\n",
- ?r => "\r",
- ?t => "\t",
- ?u => nil,
- })
-
- def parse_string
- if scan(STRING)
- return '' if self[1].empty?
- self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do
- c = $&
- if u = UNESCAPE_MAP[c[1]]
- u
- else # \uXXXX
- bytes = ''
- i = 0
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
- i += 1
- end
- JSON::UTF16toUTF8.iconv(bytes)
- end
- end
- else
- UNPARSED
- end
- rescue Iconv::Failure => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
- end
-
- def parse_value
- case
- when scan(FLOAT)
- Float(self[1])
- when scan(INTEGER)
- Integer(self[1])
- when scan(TRUE)
- true
- when scan(FALSE)
- false
- when scan(NULL)
- nil
- when (string = parse_string) != UNPARSED
- string
- when scan(ARRAY_OPEN)
- @current_nesting += 1
- ary = parse_array
- @current_nesting -= 1
- ary
- when scan(OBJECT_OPEN)
- @current_nesting += 1
- obj = parse_object
- @current_nesting -= 1
- obj
- when @allow_nan && scan(NAN)
- NaN
- when @allow_nan && scan(INFINITY)
- Infinity
- when @allow_nan && scan(MINUS_INFINITY)
- MinusInfinity
- else
- UNPARSED
- end
- end
-
- def parse_array
- raise NestingError, "nesting of #@current_nesting is to deep" if
- @max_nesting.nonzero? && @current_nesting > @max_nesting
- result = []
- delim = false
- until eos?
- case
- when (value = parse_value) != UNPARSED
- delim = false
- result << value
- skip(IGNORE)
- if scan(COLLECTION_DELIMITER)
- delim = true
- elsif match?(ARRAY_CLOSE)
- ;
- else
- raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
- end
- when scan(ARRAY_CLOSE)
- if delim
- raise ParserError, "expected next element in array at '#{peek(20)}'!"
- end
- break
- when skip(IGNORE)
- ;
- else
- raise ParserError, "unexpected token in array at '#{peek(20)}'!"
- end
- end
- result
- end
-
- def parse_object
- raise NestingError, "nesting of #@current_nesting is to deep" if
- @max_nesting.nonzero? && @current_nesting > @max_nesting
- result = {}
- delim = false
- until eos?
- case
- when (string = parse_string) != UNPARSED
- skip(IGNORE)
- unless scan(PAIR_DELIMITER)
- raise ParserError, "expected ':' in object at '#{peek(20)}'!"
- end
- skip(IGNORE)
- unless (value = parse_value).equal? UNPARSED
- result[string] = value
- delim = false
- skip(IGNORE)
- if scan(COLLECTION_DELIMITER)
- delim = true
- elsif match?(OBJECT_CLOSE)
- ;
- else
- raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
- end
- else
- raise ParserError, "expected value in object at '#{peek(20)}'!"
- end
- when scan(OBJECT_CLOSE)
- if delim
- raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
- end
- if @create_id and klassname = result[@create_id]
- klass = JSON.deep_const_get klassname
- break unless klass and klass.json_creatable?
- result = klass.json_create(result)
- end
- break
- when skip(IGNORE)
- ;
- else
- raise ParserError, "unexpected token in object at '#{peek(20)}'!"
- end
- end
- result
- end
- end
- end
-end
diff --git a/trunk/ext/json/lib/json/version.rb b/trunk/ext/json/lib/json/version.rb
deleted file mode 100644
index 3d674ac44f..0000000000
--- a/trunk/ext/json/lib/json/version.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module JSON
- # JSON version
- VERSION = '1.1.2'
- VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
- VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
- VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
- VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
- VARIANT_BINARY = false
-end