fiveruns-dash-ruby 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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