ruby-json 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +504 -0
- data/README +16 -0
- data/doc/classes/Array.html +162 -0
- data/doc/classes/Array.src/M000011.html +27 -0
- data/doc/classes/Array.src/M000012.html +32 -0
- data/doc/classes/ArrayTest.html +129 -0
- data/doc/classes/ArrayTest.src/M000014.html +28 -0
- data/doc/classes/FalseClass.html +131 -0
- data/doc/classes/FalseClass.src/M000013.html +18 -0
- data/doc/classes/Hash.html +156 -0
- data/doc/classes/Hash.src/M000009.html +29 -0
- data/doc/classes/Hash.src/M000010.html +45 -0
- data/doc/classes/JSON.html +103 -0
- data/doc/classes/JSON/Lexer.html +411 -0
- data/doc/classes/JSON/Lexer.src/M000022.html +19 -0
- data/doc/classes/JSON/Lexer.src/M000023.html +18 -0
- data/doc/classes/JSON/Lexer.src/M000024.html +18 -0
- data/doc/classes/JSON/Lexer.src/M000025.html +20 -0
- data/doc/classes/JSON/Lexer.src/M000026.html +20 -0
- data/doc/classes/JSON/Lexer.src/M000027.html +21 -0
- data/doc/classes/JSON/Lexer.src/M000028.html +43 -0
- data/doc/classes/JSON/Lexer.src/M000029.html +67 -0
- data/doc/classes/JSON/Lexer.src/M000030.html +46 -0
- data/doc/classes/JSON/Lexer.src/M000031.html +26 -0
- data/doc/classes/JSON/Lexer.src/M000032.html +61 -0
- data/doc/classes/JSON/Lexer.src/M000033.html +29 -0
- data/doc/classes/JSON/Lexer.src/M000034.html +18 -0
- data/doc/classes/JSON/Lexer.src/M000035.html +19 -0
- data/doc/classes/JSON/Lexer.src/M000036.html +20 -0
- data/doc/classes/LexerTest.html +219 -0
- data/doc/classes/LexerTest.src/M000002.html +24 -0
- data/doc/classes/LexerTest.src/M000003.html +22 -0
- data/doc/classes/LexerTest.src/M000004.html +26 -0
- data/doc/classes/LexerTest.src/M000005.html +23 -0
- data/doc/classes/LexerTest.src/M000006.html +31 -0
- data/doc/classes/LexerTest.src/M000007.html +27 -0
- data/doc/classes/LexerTest.src/M000008.html +58 -0
- data/doc/classes/NilClass.html +131 -0
- data/doc/classes/NilClass.src/M000017.html +18 -0
- data/doc/classes/Numeric.html +131 -0
- data/doc/classes/Numeric.src/M000016.html +18 -0
- data/doc/classes/Object.html +176 -0
- data/doc/classes/Object.src/M000018.html +18 -0
- data/doc/classes/ObjectTest.html +129 -0
- data/doc/classes/ObjectTest.src/M000015.html +28 -0
- data/doc/classes/String.html +151 -0
- data/doc/classes/String.src/M000019.html +18 -0
- data/doc/classes/String.src/M000020.html +46 -0
- data/doc/classes/TrueClass.html +131 -0
- data/doc/classes/TrueClass.src/M000021.html +18 -0
- data/doc/created.rid +1 -0
- data/doc/files/install_rb.html +194 -0
- data/doc/files/install_rb.src/M000001.html +43 -0
- data/doc/files/json/lexer_rb.html +156 -0
- data/doc/files/json/objects_rb.html +154 -0
- data/doc/files/test/arraytest_rb.html +150 -0
- data/doc/files/test/lexertest_rb.html +150 -0
- data/doc/files/test/objtest_rb.html +150 -0
- data/doc/fr_class_index.html +39 -0
- data/doc/fr_file_index.html +32 -0
- data/doc/fr_method_index.html +62 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +175 -0
- data/install.rb +67 -0
- data/lib/json/lexer.rb +297 -0
- data/lib/json/objects.rb +201 -0
- data/ruby-json.gemspec +25 -0
- data/test/arraytest.rb +45 -0
- data/test/lexertest.rb +146 -0
- data/test/objtest.rb +45 -0
- metadata +126 -0
data/doc/rdoc-style.css
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
margin: 0;
|
4
|
+
padding: 0;
|
5
|
+
background: white;
|
6
|
+
}
|
7
|
+
|
8
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
9
|
+
h1 { font-size: 120%; }
|
10
|
+
h2,h3,h4 { margin-top: 1em; }
|
11
|
+
|
12
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
13
|
+
a:hover { background: #039; color: #eef; }
|
14
|
+
|
15
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
16
|
+
td > a {
|
17
|
+
background: transparent;
|
18
|
+
color: #039;
|
19
|
+
text-decoration: none;
|
20
|
+
}
|
21
|
+
|
22
|
+
/* === Structural elements =================================== */
|
23
|
+
|
24
|
+
div#index {
|
25
|
+
margin: 0;
|
26
|
+
padding: 0;
|
27
|
+
font-size: 0.9em;
|
28
|
+
}
|
29
|
+
|
30
|
+
div#index a {
|
31
|
+
margin-left: 0.7em;
|
32
|
+
}
|
33
|
+
|
34
|
+
div#classHeader {
|
35
|
+
width: auto;
|
36
|
+
background: #039;
|
37
|
+
color: white;
|
38
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
39
|
+
margin: 0;
|
40
|
+
border-bottom: 3px solid #006;
|
41
|
+
}
|
42
|
+
|
43
|
+
div#classHeader a {
|
44
|
+
background: inherit;
|
45
|
+
color: white;
|
46
|
+
}
|
47
|
+
|
48
|
+
div#classHeader td {
|
49
|
+
background: inherit;
|
50
|
+
color: white;
|
51
|
+
}
|
52
|
+
|
53
|
+
div#fileHeader {
|
54
|
+
width: auto;
|
55
|
+
background: #039;
|
56
|
+
color: white;
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
58
|
+
margin: 0;
|
59
|
+
border-bottom: 3px solid #006;
|
60
|
+
}
|
61
|
+
|
62
|
+
div#fileHeader a {
|
63
|
+
background: inherit;
|
64
|
+
color: white;
|
65
|
+
}
|
66
|
+
|
67
|
+
div#fileHeader td {
|
68
|
+
background: inherit;
|
69
|
+
color: white;
|
70
|
+
}
|
71
|
+
|
72
|
+
div#bodyContent {
|
73
|
+
padding: 0 1.5em 0 1.5em;
|
74
|
+
}
|
75
|
+
|
76
|
+
div#description {
|
77
|
+
padding: 0.5em 1.5em;
|
78
|
+
background: #efefef;
|
79
|
+
border: 1px dotted #999;
|
80
|
+
}
|
81
|
+
|
82
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
83
|
+
color: black;
|
84
|
+
background: transparent;
|
85
|
+
}
|
86
|
+
|
87
|
+
div#validator-badges {
|
88
|
+
text-align: center;
|
89
|
+
}
|
90
|
+
div#validator-badges img { border: 0; }
|
91
|
+
|
92
|
+
div#copyright {
|
93
|
+
color: #333;
|
94
|
+
background: #efefef;
|
95
|
+
font: 0.75em sans-serif;
|
96
|
+
margin-top: 5em;
|
97
|
+
margin-bottom: 0;
|
98
|
+
padding: 0.5em 2em;
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
/* === Classes =================================== */
|
103
|
+
|
104
|
+
table.header-table {
|
105
|
+
color: white;
|
106
|
+
font-size: small;
|
107
|
+
}
|
108
|
+
|
109
|
+
.type-note {
|
110
|
+
font-size: small;
|
111
|
+
color: #DEDEDE;
|
112
|
+
}
|
113
|
+
|
114
|
+
.section-bar {
|
115
|
+
background: #eee;
|
116
|
+
color: #333;
|
117
|
+
padding: 3px;
|
118
|
+
border: 1px solid #999;
|
119
|
+
}
|
120
|
+
|
121
|
+
.top-aligned-row { vertical-align: vertical-align: top }
|
122
|
+
|
123
|
+
/* --- Context section classes ----------------------- */
|
124
|
+
|
125
|
+
.context-row { }
|
126
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
127
|
+
.context-item-value { font-size: x-small; color: #448; }
|
128
|
+
.context-item-desc { background: #efefef; }
|
129
|
+
|
130
|
+
/* --- Method classes -------------------------- */
|
131
|
+
.method-detail {
|
132
|
+
background: #EFEFEF;
|
133
|
+
padding: 0;
|
134
|
+
margin-top: 0.5em;
|
135
|
+
margin-bottom: 0.5em;
|
136
|
+
border: 1px dotted #DDD;
|
137
|
+
}
|
138
|
+
.method-heading {
|
139
|
+
color: black;
|
140
|
+
background: #AAA;
|
141
|
+
border-bottom: 1px solid #666;
|
142
|
+
padding: 0.2em 0.5em 0 0.5em;
|
143
|
+
}
|
144
|
+
.method-signature { color: black; background: inherit; }
|
145
|
+
.method-name { font-weight: bold; }
|
146
|
+
.method-args { font-style: italic; }
|
147
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
148
|
+
|
149
|
+
/* --- Source code sections -------------------- */
|
150
|
+
|
151
|
+
a.source-toggle { font-size: 90%; }
|
152
|
+
div.method-source-code {
|
153
|
+
background: #262626;
|
154
|
+
color: #ffdead;
|
155
|
+
margin: 1em;
|
156
|
+
padding: 0.5em;
|
157
|
+
border: 1px dashed #999;
|
158
|
+
overflow: hidden;
|
159
|
+
}
|
160
|
+
|
161
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
162
|
+
|
163
|
+
/* --- Ruby keyword styles --------------------- */
|
164
|
+
|
165
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
166
|
+
|
167
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
168
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
169
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
170
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
171
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
172
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
173
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
174
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
175
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
data/install.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# Install Script
|
3
|
+
# Copyright (C) 2003 Rafael R. Sevilla <dido@imperium.ph>
|
4
|
+
# This file is part of JSON for Ruby
|
5
|
+
#
|
6
|
+
# JSON for Ruby is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public License
|
8
|
+
# as published by the Free Software Foundation; either version 2.1 of
|
9
|
+
# the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# JSON for Ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with JSON for Ruby; if not, write to the Free
|
18
|
+
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
19
|
+
# 02111-1307 USA.
|
20
|
+
#
|
21
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
22
|
+
# Copyright:: Copyright (c) 2003 Rafael R. Sevilla
|
23
|
+
# License:: GNU Lesser General Public License
|
24
|
+
# $Id: install.rb,v 1.1 2003/08/20 10:53:24 didosevilla Exp $
|
25
|
+
#
|
26
|
+
|
27
|
+
require 'getoptlong'
|
28
|
+
require 'ftools'
|
29
|
+
require 'find'
|
30
|
+
|
31
|
+
SOURCE_DIR = 'json'
|
32
|
+
LIBDIR = 'json'
|
33
|
+
|
34
|
+
def instdir
|
35
|
+
g = GetoptLong.new(['--install-dir', '-i', GetoptLong::REQUIRED_ARGUMENT])
|
36
|
+
g.each { | name, arg |
|
37
|
+
if name == '--install-dir'
|
38
|
+
return arg
|
39
|
+
else
|
40
|
+
$stderr.puts "usage: $0 [--install-dir dir]"
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
begin
|
45
|
+
require 'rbconfig'
|
46
|
+
libdir = Config::CONFIG['sitedir'] + "/" +
|
47
|
+
Config::CONFIG['MAJOR'] + "." +
|
48
|
+
Config::CONFIG['MINOR']
|
49
|
+
rescue ScriptError
|
50
|
+
$LOAD_PATH.each do |l|
|
51
|
+
if l =~ /site_ruby/ && l =~ /\d$/ && l !~ /#{PLATFORM}/
|
52
|
+
libdir = l
|
53
|
+
break
|
54
|
+
end
|
55
|
+
end
|
56
|
+
STDERR.puts "Can't find required file `rbconfig.rb'."
|
57
|
+
STDERR.puts "The 'json' files need to be installed manually in " +
|
58
|
+
" #{libdir}"
|
59
|
+
end
|
60
|
+
return libdir
|
61
|
+
end
|
62
|
+
|
63
|
+
INSTALL_DIR = instdir()
|
64
|
+
File.makedirs(File.join(INSTALL_DIR, LIBDIR))
|
65
|
+
Find.find(SOURCE_DIR) { |f|
|
66
|
+
File.install(f, File.join(INSTALL_DIR, f), 0644, true) if f =~ /.rb$/
|
67
|
+
}
|
data/lib/json/lexer.rb
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
#
|
2
|
+
# Lexical analyzer for JSON
|
3
|
+
# Copyright (C) 2003,2005 Rafael R. Sevilla <dido@imperium.ph>
|
4
|
+
# This file is part of JSON for Ruby
|
5
|
+
#
|
6
|
+
# JSON for Ruby is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public License
|
8
|
+
# as published by the Free Software Foundation; either version 2.1 of
|
9
|
+
# the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# JSON for Ruby is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with JSON for Ruby; if not, write to the Free
|
18
|
+
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
19
|
+
# 02111-1307 USA.
|
20
|
+
#
|
21
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
22
|
+
# Some bugs fixed by Adam Kramer (mailto:adam@the-kramers.net)
|
23
|
+
# Copyright:: Copyright (c) 2003,2005 Rafael R. Sevilla
|
24
|
+
# License:: GNU Lesser General Public License
|
25
|
+
# $Id: lexer.rb,v 1.7 2005/01/28 02:42:10 didosevilla Exp $
|
26
|
+
#
|
27
|
+
require 'json/objects'
|
28
|
+
require 'cgi'
|
29
|
+
|
30
|
+
module JSON
|
31
|
+
class Lexer
|
32
|
+
# This method will initialize the lexer to contain a string.
|
33
|
+
# =====Parameters
|
34
|
+
# +s+:: the string to initialize the lexer object with
|
35
|
+
def initialize(s)
|
36
|
+
@index = 0
|
37
|
+
@source = s
|
38
|
+
end
|
39
|
+
|
40
|
+
# Backs up the lexer status one character.
|
41
|
+
def back
|
42
|
+
@index -= 1 if @index > 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def more?
|
46
|
+
return(@index < @source.length)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Consumes the next character.
|
50
|
+
def nextchar
|
51
|
+
c = self.more?() ? @source[@index,1] : "\0"
|
52
|
+
@index += 1
|
53
|
+
return(c)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Consumes the next character and check that it matches a specified
|
57
|
+
# character.
|
58
|
+
def nextmatch(char)
|
59
|
+
n = self.nextchar
|
60
|
+
raise "Expected '#{char}' and instead saw '#{n}'." if (n != char)
|
61
|
+
return(n)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Read the next n characters from the string in the lexer.
|
65
|
+
# =====Parameters
|
66
|
+
# +n+:: the number of characters to read from the lexer
|
67
|
+
def nextchars(n)
|
68
|
+
raise "substring bounds error" if (@index + n > @source.length)
|
69
|
+
i = @index
|
70
|
+
@index += n
|
71
|
+
return(@source[i,n])
|
72
|
+
end
|
73
|
+
|
74
|
+
# Read the next n characters from the string with escape sequence
|
75
|
+
# processing.
|
76
|
+
def nextclean
|
77
|
+
while true
|
78
|
+
c = self.nextchar()
|
79
|
+
if (c == '/')
|
80
|
+
case self.nextchar()
|
81
|
+
when '/'
|
82
|
+
c = self.nextchar()
|
83
|
+
while c != "\n" && c != "\r" && c != "\0"
|
84
|
+
c = self.nextchar()
|
85
|
+
end
|
86
|
+
when '*'
|
87
|
+
while true
|
88
|
+
c = self.nextchar()
|
89
|
+
raise "unclosed comment" if (c == "\0")
|
90
|
+
if (c == '*')
|
91
|
+
break if (self.nextchar() == '/')
|
92
|
+
self.back()
|
93
|
+
end
|
94
|
+
end
|
95
|
+
else
|
96
|
+
self.back()
|
97
|
+
return '/';
|
98
|
+
end
|
99
|
+
elsif c == "\0" || c[0] > " "[0]
|
100
|
+
return(c)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Given a Unicode code point, return a string giving its UTF-8
|
106
|
+
# representation based on RFC 2279.
|
107
|
+
def utf8str(code)
|
108
|
+
if (code & ~(0x7f)) == 0
|
109
|
+
# UCS-4 range 0x00000000 - 0x0000007F
|
110
|
+
return(code.chr)
|
111
|
+
end
|
112
|
+
|
113
|
+
buf = ""
|
114
|
+
if (code & ~(0x7ff)) == 0
|
115
|
+
# UCS-4 range 0x00000080 - 0x000007FF
|
116
|
+
buf << (0b11000000 | (code >> 6)).chr
|
117
|
+
buf << (0b10000000 | (code & 0b00111111)).chr
|
118
|
+
return(buf)
|
119
|
+
end
|
120
|
+
|
121
|
+
if (code & ~(0x000ffff)) == 0
|
122
|
+
# UCS-4 range 0x00000800 - 0x0000FFFF
|
123
|
+
buf << (0b11100000 | (code >> 12)).chr
|
124
|
+
buf << (0b10000000 | ((code >> 6) & 0b00111111)).chr
|
125
|
+
buf << (0b10000000 | (code & 0b0011111)).chr
|
126
|
+
return(buf)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Not used -- JSON only has UCS-2, but for the sake
|
130
|
+
# of completeness
|
131
|
+
if (code & ~(0x1FFFFF)) == 0
|
132
|
+
# UCS-4 range 0x00010000 - 0x001FFFFF
|
133
|
+
buf << (0b11110000 | (code >> 18)).chr
|
134
|
+
buf << (0b10000000 | ((code >> 12) & 0b00111111)).chr
|
135
|
+
buf << (0b10000000 | ((code >> 6) & 0b00111111)).chr
|
136
|
+
buf << (0b10000000 | (code & 0b0011111)).chr
|
137
|
+
return(buf)
|
138
|
+
end
|
139
|
+
|
140
|
+
if (code & ~(0x03FFFFFF)) == 0
|
141
|
+
# UCS-4 range 0x00200000 - 0x03FFFFFF
|
142
|
+
buf << (0b11110000 | (code >> 24)).chr
|
143
|
+
buf << (0b10000000 | ((code >> 18) & 0b00111111)).chr
|
144
|
+
buf << (0b10000000 | ((code >> 12) & 0b00111111)).chr
|
145
|
+
buf << (0b10000000 | ((code >> 6) & 0b00111111)).chr
|
146
|
+
buf << (0b10000000 | (code & 0b0011111)).chr
|
147
|
+
return(buf)
|
148
|
+
end
|
149
|
+
|
150
|
+
# UCS-4 range 0x04000000 - 0x7FFFFFFF
|
151
|
+
buf << (0b11111000 | (code >> 30)).chr
|
152
|
+
buf << (0b10000000 | ((code >> 24) & 0b00111111)).chr
|
153
|
+
buf << (0b10000000 | ((code >> 18) & 0b00111111)).chr
|
154
|
+
buf << (0b10000000 | ((code >> 12) & 0b00111111)).chr
|
155
|
+
buf << (0b10000000 | ((code >> 6) & 0b00111111)).chr
|
156
|
+
buf << (0b10000000 | (code & 0b0011111)).chr
|
157
|
+
return(buf)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Reads the next string, given a quote character (usually ' or ")
|
161
|
+
# =====Parameters
|
162
|
+
# +quot+: the next matching quote character to use
|
163
|
+
def nextstring(quot)
|
164
|
+
c = buf = ""
|
165
|
+
while true
|
166
|
+
c = self.nextchar()
|
167
|
+
case c
|
168
|
+
when /\0|\n\r/
|
169
|
+
raise "Unterminated string"
|
170
|
+
when "\\"
|
171
|
+
chr = self.nextchar()
|
172
|
+
case chr
|
173
|
+
when 'b'
|
174
|
+
buf << "\b"
|
175
|
+
when 't'
|
176
|
+
buf << "\t"
|
177
|
+
when 'n'
|
178
|
+
buf << "\n"
|
179
|
+
when 'f'
|
180
|
+
buf << "\f"
|
181
|
+
when 'r'
|
182
|
+
buf << "\r"
|
183
|
+
when 'u'
|
184
|
+
buf << utf8str(Integer("0x" + self.nextchars(4)))
|
185
|
+
else
|
186
|
+
buf << chr
|
187
|
+
end
|
188
|
+
else
|
189
|
+
return(buf) if (c == quot)
|
190
|
+
buf << c
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Reads the next group of characters that match a regular
|
196
|
+
# expresion.
|
197
|
+
#
|
198
|
+
def nextto(regex)
|
199
|
+
buf = ""
|
200
|
+
while (true)
|
201
|
+
c = self.nextchar()
|
202
|
+
if !(regex =~ c).nil? || c == '\0' || c == '\n' || c == '\r'
|
203
|
+
self.back() if (c != '\0')
|
204
|
+
return(buf.chomp())
|
205
|
+
end
|
206
|
+
buf += c
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Reads the next value from the string. This can return either a
|
211
|
+
# string, a FixNum, a floating point value, a JSON array, or a
|
212
|
+
# JSON object.
|
213
|
+
def nextvalue
|
214
|
+
c = self.nextclean
|
215
|
+
s = ""
|
216
|
+
|
217
|
+
case c
|
218
|
+
when /\"|\'/
|
219
|
+
return(self.nextstring(c))
|
220
|
+
when '{'
|
221
|
+
self.back()
|
222
|
+
return(Hash.new.from_json(self))
|
223
|
+
when '['
|
224
|
+
self.back()
|
225
|
+
return(Array.new.from_json(self))
|
226
|
+
else
|
227
|
+
buf = ""
|
228
|
+
while ((c =~ /"| |:|,|\]|\}|\/|\0/).nil?)
|
229
|
+
buf += c
|
230
|
+
c = self.nextchar()
|
231
|
+
end
|
232
|
+
self.back()
|
233
|
+
s = buf.chomp
|
234
|
+
case s
|
235
|
+
when "true"
|
236
|
+
return(true)
|
237
|
+
when "false"
|
238
|
+
return(false)
|
239
|
+
when "null"
|
240
|
+
return(nil)
|
241
|
+
when /^[0-9]|\.|-|\+/
|
242
|
+
begin
|
243
|
+
return(Integer(s))
|
244
|
+
rescue ArgumentError
|
245
|
+
# do nothing on an error, the next case should do the trick
|
246
|
+
end
|
247
|
+
begin
|
248
|
+
return(Float(s))
|
249
|
+
rescue ArgumentError
|
250
|
+
# do nothing
|
251
|
+
end
|
252
|
+
end
|
253
|
+
if (s == "")
|
254
|
+
s = nil
|
255
|
+
end
|
256
|
+
return(s)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Skip to the next instance of the character specified
|
261
|
+
# =====Parameters
|
262
|
+
# +to+:: Character to skip to
|
263
|
+
def skipto(to)
|
264
|
+
index = @index
|
265
|
+
loop {
|
266
|
+
c = self.nextchar()
|
267
|
+
if (c == '\0')
|
268
|
+
@index = index
|
269
|
+
return(c)
|
270
|
+
end
|
271
|
+
if (c == to)
|
272
|
+
self.back
|
273
|
+
return(c)
|
274
|
+
end
|
275
|
+
}
|
276
|
+
end
|
277
|
+
|
278
|
+
def unescape
|
279
|
+
@source = CGI::unescape(@source)
|
280
|
+
end
|
281
|
+
|
282
|
+
# Skip past the next instance of the character specified
|
283
|
+
# =====Parameters
|
284
|
+
# +to+:: the character to skip past
|
285
|
+
def skippast(to)
|
286
|
+
@index = @source.index(to, @index)
|
287
|
+
@index = (@index.nil?) ? @source.length : @index + to.length
|
288
|
+
end
|
289
|
+
|
290
|
+
def each
|
291
|
+
while (n = nextvalue)
|
292
|
+
yield(n)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|