fiveruns-dash-ruby 0.8.4 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -94,17 +94,18 @@ module Fiveruns::Dash
94
94
  @architecture = `uname -p`.strip
95
95
  @os_version = `uname -r`.strip
96
96
  end
97
- when /win32|i386-mingw32/
98
- require "dl/win32"
99
- getVersionEx = Win32API.new("kernel32", "GetVersionExA", ['P'], 'L')
100
-
101
- lpVersionInfo = [148, 0, 0, 0, 0].pack("LLLLL") + "�0" * 128
102
- getVersionEx.Call lpVersionInfo
103
-
104
- dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion, dwBuildNumber, dwPlatformId, szCSDVersion = lpVersionInfo.unpack("LLLLLC128")
105
- @os_name = ['Windows 3.1/3.11', 'Windows 95/98', 'Windows NT/XP'][dwPlatformId]
106
- @os_version = "#{dwMajorVersion}.#{dwMinorVersion}"
107
- @architecture = ENV['PROCESSOR_ARCHITECTURE']
97
+ # when /win32|i386-mingw32/
98
+ # require "dl/win32"
99
+ # getVersionEx = Win32API.new("kernel32", "GetVersionExA", ['P'], 'L')
100
+ #
101
+ # This line done broke on Ruby 1.9.1:
102
+ # lpVersionInfo = [148, 0, 0, 0, 0].pack("LLLLL") + "�0" * 128
103
+ # getVersionEx.Call lpVersionInfo
104
+ #
105
+ # dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion, dwBuildNumber, dwPlatformId, szCSDVersion = lpVersionInfo.unpack("LLLLLC128")
106
+ # @os_name = ['Windows 3.1/3.11', 'Windows 95/98', 'Windows NT/XP'][dwPlatformId]
107
+ # @os_version = "#{dwMajorVersion}.#{dwMinorVersion}"
108
+ # @architecture = ENV['PROCESSOR_ARCHITECTURE']
108
109
  end
109
110
 
110
111
  @ip_addresses = []
@@ -19,11 +19,11 @@ module Fiveruns::JSON
19
19
  attr_reader :parser
20
20
 
21
21
  # Set the FiverunsJSON parser class _parser_ to be used by FiverunsJSON.
22
- # def parser=(parser) # :nodoc:
23
- # @parser = parser
24
- # remove_const :Parser if const_defined? :Parser
25
- # const_set :Parser, parser
26
- # end
22
+ def parser=(parser) # :nodoc:
23
+ @parser = parser
24
+ remove_const :Parser if const_defined? :Parser
25
+ const_set :Parser, parser
26
+ end
27
27
 
28
28
  # Return the constant located at _path_. The format of _path_ has to be
29
29
  # either ::A::B::C or A::B::C. In any case A has to be located at the top
@@ -116,9 +116,9 @@ module Fiveruns::JSON
116
116
  # * *create_additions*: If set to false, the Parser doesn't create
117
117
  # additions even if a matchin class and create_id was found. This option
118
118
  # defaults to true.
119
- # def parse(source, opts = {})
120
- # ::Fiveruns::JSON.parser.new(source, opts).parse
121
- # end
119
+ def parse(source, opts = {})
120
+ ::Fiveruns::JSON.parser.new(source, opts).parse
121
+ end
122
122
 
123
123
  # Parse the FiverunsJSON string _source_ into a Ruby data structure and return it.
124
124
  # The bang version of the parse method, defaults to the more dangerous values
@@ -135,13 +135,13 @@ module Fiveruns::JSON
135
135
  # * *create_additions*: If set to false, the Parser doesn't create
136
136
  # additions even if a matchin class and create_id was found. This option
137
137
  # defaults to true.
138
- # def parse!(source, opts = {})
139
- # opts = {
140
- # :max_nesting => false,
141
- # :allow_nan => true
142
- # }.update(opts)
143
- # ::Fiveruns::JSON.parser.new(source, opts).parse
144
- # end
138
+ def parse!(source, opts = {})
139
+ opts = {
140
+ :max_nesting => false,
141
+ :allow_nan => true
142
+ }.update(opts)
143
+ ::Fiveruns::JSON.parser.new(source, opts).parse
144
+ end
145
145
 
146
146
  # Unparse the Ruby data structure _obj_ into a single line FiverunsJSON string and
147
147
  # return it. _state_ is
@@ -333,11 +333,11 @@ module ::Kernel
333
333
  # The _opts_ argument is passed through to generate/parse respectively, see
334
334
  # generate and parse for their documentation.
335
335
  def FJSON(object, opts = {})
336
- # if object.respond_to? :to_str
337
- # ::Fiveruns::JSON.parse(object.to_str, opts)
338
- # else
336
+ if object.respond_to? :to_str
337
+ ::Fiveruns::JSON.parse(object.to_str, opts)
338
+ else
339
339
  ::Fiveruns::JSON.generate(object, opts)
340
- # end
340
+ end
341
341
  end
342
342
  end
343
343
 
@@ -0,0 +1,259 @@
1
+ require 'strscan'
2
+
3
+ module Fiveruns::JSON
4
+ module Pure
5
+ # This class implements the FiverunsJSON parser that is used to parse a FiverunsJSON string
6
+ # into a Ruby data structure.
7
+ class Parser < StringScanner
8
+ STRING = /" ((?:[^\x0-\x1f"\\] |
9
+ \\["\\\/bfnrt] |
10
+ \\u[0-9a-fA-F]{4} |
11
+ \\[\x20-\xff])*)
12
+ "/nx
13
+ INTEGER = /(-?0|-?[1-9]\d*)/
14
+ FLOAT = /(-?
15
+ (?:0|[1-9]\d*)
16
+ (?:
17
+ \.\d+(?i:e[+-]?\d+) |
18
+ \.\d+ |
19
+ (?i:e[+-]?\d+)
20
+ )
21
+ )/x
22
+ NAN = /NaN/
23
+ INFINITY = /Infinity/
24
+ MINUS_INFINITY = /-Infinity/
25
+ OBJECT_OPEN = /\{/
26
+ OBJECT_CLOSE = /\}/
27
+ ARRAY_OPEN = /\[/
28
+ ARRAY_CLOSE = /\]/
29
+ PAIR_DELIMITER = /:/
30
+ COLLECTION_DELIMITER = /,/
31
+ TRUE = /true/
32
+ FALSE = /false/
33
+ NULL = /null/
34
+ IGNORE = %r(
35
+ (?:
36
+ //[^\n\r]*[\n\r]| # line comments
37
+ /\* # c-style comments
38
+ (?:
39
+ [^*/]| # normal chars
40
+ /[^*]| # slashes that do not start a nested comment
41
+ \*[^/]| # asterisks that do not end this comment
42
+ /(?=\*/) # single slash before this comment's end
43
+ )*
44
+ \*/ # the End of this comment
45
+ |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
46
+ )+
47
+ )mx
48
+
49
+ UNPARSED = Object.new
50
+
51
+ # Creates a new FiverunsJSON::Pure::Parser instance for the string _source_.
52
+ #
53
+ # It will be configured by the _opts_ hash. _opts_ can have the following
54
+ # keys:
55
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
56
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
57
+ # it defaults to 19.
58
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
59
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
60
+ # to false.
61
+ # * *create_additions*: If set to false, the Parser doesn't create
62
+ # additions even if a matchin class and create_id was found. This option
63
+ # defaults to true.
64
+ def initialize(source, opts = {})
65
+ super
66
+ if !opts.key?(:max_nesting) # defaults to 19
67
+ @max_nesting = 19
68
+ elsif opts[:max_nesting]
69
+ @max_nesting = opts[:max_nesting]
70
+ else
71
+ @max_nesting = 0
72
+ end
73
+ @allow_nan = !!opts[:allow_nan]
74
+ ca = true
75
+ ca = opts[:create_additions] if opts.key?(:create_additions)
76
+ @create_id = ca ? ::Fiveruns::JSON.create_id : nil
77
+ end
78
+
79
+ alias source string
80
+
81
+ # Parses the current FiverunsJSON string _source_ and returns the complete data
82
+ # structure as a result.
83
+ def parse
84
+ reset
85
+ obj = nil
86
+ until eos?
87
+ case
88
+ when scan(OBJECT_OPEN)
89
+ obj and raise ParserError, "source '#{peek(20)}' not in FiverunsJSON!"
90
+ @current_nesting = 1
91
+ obj = parse_object
92
+ when scan(ARRAY_OPEN)
93
+ obj and raise ParserError, "source '#{peek(20)}' not in FiverunsJSON!"
94
+ @current_nesting = 1
95
+ obj = parse_array
96
+ when skip(IGNORE)
97
+ ;
98
+ else
99
+ raise ParserError, "source '#{peek(20)}' not in FiverunsJSON!"
100
+ end
101
+ end
102
+ obj or raise ParserError, "source did not contain any FiverunsJSON!"
103
+ obj
104
+ end
105
+
106
+ private
107
+
108
+ # Unescape characters in strings.
109
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
110
+ UNESCAPE_MAP.update({
111
+ ?" => '"',
112
+ ?\\ => '\\',
113
+ ?/ => '/',
114
+ ?b => "\b",
115
+ ?f => "\f",
116
+ ?n => "\n",
117
+ ?r => "\r",
118
+ ?t => "\t",
119
+ ?u => nil,
120
+ })
121
+
122
+ def parse_string
123
+ if scan(STRING)
124
+ return '' if self[1].empty?
125
+ self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
126
+ if u = UNESCAPE_MAP[$&[1]]
127
+ u
128
+ else # \uXXXX
129
+ bytes = ''
130
+ i = 0
131
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
132
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
133
+ i += 1
134
+ end
135
+ ::Fiveruns::JSON::UTF16toUTF8.iconv(bytes)
136
+ end
137
+ end
138
+ else
139
+ UNPARSED
140
+ end
141
+ rescue Iconv::Failure => e
142
+ raise GeneratorError, "Caught #{e.class}: #{e}"
143
+ end
144
+
145
+ def parse_value
146
+ case
147
+ when scan(FLOAT)
148
+ Float(self[1])
149
+ when scan(INTEGER)
150
+ Integer(self[1])
151
+ when scan(TRUE)
152
+ true
153
+ when scan(FALSE)
154
+ false
155
+ when scan(NULL)
156
+ nil
157
+ when (string = parse_string) != UNPARSED
158
+ string
159
+ when scan(ARRAY_OPEN)
160
+ @current_nesting += 1
161
+ ary = parse_array
162
+ @current_nesting -= 1
163
+ ary
164
+ when scan(OBJECT_OPEN)
165
+ @current_nesting += 1
166
+ obj = parse_object
167
+ @current_nesting -= 1
168
+ obj
169
+ when @allow_nan && scan(NAN)
170
+ NaN
171
+ when @allow_nan && scan(INFINITY)
172
+ Infinity
173
+ when @allow_nan && scan(MINUS_INFINITY)
174
+ MinusInfinity
175
+ else
176
+ UNPARSED
177
+ end
178
+ end
179
+
180
+ def parse_array
181
+ raise NestingError, "nesting of #@current_nesting is to deep" if
182
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
183
+ result = []
184
+ delim = false
185
+ until eos?
186
+ case
187
+ when (value = parse_value) != UNPARSED
188
+ delim = false
189
+ result << value
190
+ skip(IGNORE)
191
+ if scan(COLLECTION_DELIMITER)
192
+ delim = true
193
+ elsif match?(ARRAY_CLOSE)
194
+ ;
195
+ else
196
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
197
+ end
198
+ when scan(ARRAY_CLOSE)
199
+ if delim
200
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
201
+ end
202
+ break
203
+ when skip(IGNORE)
204
+ ;
205
+ else
206
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
207
+ end
208
+ end
209
+ result
210
+ end
211
+
212
+ def parse_object
213
+ raise NestingError, "nesting of #@current_nesting is to deep" if
214
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
215
+ result = {}
216
+ delim = false
217
+ until eos?
218
+ case
219
+ when (string = parse_string) != UNPARSED
220
+ skip(IGNORE)
221
+ unless scan(PAIR_DELIMITER)
222
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
223
+ end
224
+ skip(IGNORE)
225
+ unless (value = parse_value).equal? UNPARSED
226
+ result[string] = value
227
+ delim = false
228
+ skip(IGNORE)
229
+ if scan(COLLECTION_DELIMITER)
230
+ delim = true
231
+ elsif match?(OBJECT_CLOSE)
232
+ ;
233
+ else
234
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
235
+ end
236
+ else
237
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
238
+ end
239
+ when scan(OBJECT_CLOSE)
240
+ if delim
241
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
242
+ end
243
+ if @create_id and klassname = result[@create_id]
244
+ klass = ::Fiveruns::JSON.deep_const_get klassname
245
+ break unless klass and klass.fjson_creatable?
246
+ result = klass.fjson_create(result)
247
+ end
248
+ break
249
+ when skip(IGNORE)
250
+ ;
251
+ else
252
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
253
+ end
254
+ end
255
+ result
256
+ end
257
+ end
258
+ end
259
+ end
@@ -66,6 +66,7 @@ module Fiveruns::JSON
66
66
  # functionality in pure ruby.
67
67
  module Pure
68
68
  $DEBUG and warn "Using pure library for Fiveruns::JSON."
69
+ ::Fiveruns::JSON.parser = Parser
69
70
  ::Fiveruns::JSON.generator = Generator
70
71
  end
71
72
  end
data/lib/fiveruns/json.rb CHANGED
@@ -10,6 +10,7 @@
10
10
  require 'fiveruns/json/version'
11
11
  require 'fiveruns/json/common'
12
12
  require 'fiveruns/json/generator'
13
+ require 'fiveruns/json/parser'
13
14
  require 'fiveruns/json/pure'
14
15
  require 'fiveruns/json/add/core'
15
16
  require 'fiveruns/json/add/rails'
data/test/json_test.rb CHANGED
@@ -22,12 +22,18 @@ class JsonTest < Test::Unit::TestCase
22
22
  end
23
23
  end
24
24
 
25
- def test_serialization
26
- xprofile('fjson') do
27
- @data.to_fjson
28
- end
29
- a = Time.now
30
- fjson = @data.to_fjson
31
- # puts "FJSON: #{Time.now - a}"
32
- end
25
+ def test_parser
26
+ json = '{"token":"abcxyz","name":"Foo","owner":"John Smith"}'
27
+ hash = Fiveruns::JSON.load(json)
28
+ assert_equal 'abcxyz', hash['token']
29
+ end
30
+
31
+ def test_generator
32
+ xprofile('fjson') do
33
+ @data.to_fjson
34
+ end
35
+ a = Time.now
36
+ fjson = @data.to_fjson
37
+ # puts "FJSON: #{Time.now - a}"
38
+ end
33
39
  end
data/version.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 8
4
- :patch: 4
4
+ :patch: 5
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiveruns-dash-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - FiveRuns Development Team
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-04 00:00:00 -08:00
12
+ date: 2009-03-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -19,8 +19,8 @@ executables: []
19
19
 
20
20
  extensions: []
21
21
 
22
- extra_rdoc_files: []
23
-
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
24
  files:
25
25
  - README.rdoc
26
26
  - Rakefile
@@ -52,6 +52,7 @@ files:
52
52
  - lib/fiveruns/json/add/rails.rb
53
53
  - lib/fiveruns/json/common.rb
54
54
  - lib/fiveruns/json/generator.rb
55
+ - lib/fiveruns/json/parser.rb
55
56
  - lib/fiveruns/json/pure.rb
56
57
  - lib/fiveruns/json/version.rb
57
58
  - lib/fiveruns/json.rb