rhodes 1.5.4 → 1.5.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.
Files changed (60) hide show
  1. data/Manifest.txt +11 -1
  2. data/Rakefile +1 -1
  3. data/lib/extensions/digest/ext/Rakefile +11 -6
  4. data/lib/extensions/digest/ext/build.bat +2 -0
  5. data/lib/extensions/uri/uri.rb +29 -0
  6. data/lib/extensions/uri/uri/common.rb +727 -0
  7. data/lib/extensions/uri/uri/ftp.rb +198 -0
  8. data/lib/extensions/uri/uri/generic.rb +1128 -0
  9. data/lib/extensions/uri/uri/http.rb +100 -0
  10. data/lib/extensions/uri/uri/https.rb +20 -0
  11. data/lib/extensions/uri/uri/ldap.rb +190 -0
  12. data/lib/extensions/uri/uri/ldaps.rb +12 -0
  13. data/lib/extensions/uri/uri/mailto.rb +266 -0
  14. data/lib/framework/rhodes.rb +2 -2
  15. data/lib/framework/rhom/rhom_db_adapter.rb +12 -26
  16. data/lib/framework/rhom/rhom_object_factory.rb +8 -1
  17. data/lib/framework/version.rb +2 -2
  18. data/lib/rhodes.rb +2 -2
  19. data/platform/android/Rhodes/AndroidManifest.xml +2 -2
  20. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +87 -42
  21. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +58 -7
  22. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +2 -0
  23. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +35 -19
  24. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +4 -0
  25. data/platform/android/build/android.rake +30 -25
  26. data/platform/bb/build/rhodes_build.files +1 -1
  27. data/platform/bb/rhodes/rhodes.jdp +1 -1
  28. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +1 -1
  29. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +300 -0
  30. data/platform/bb/rhodes/src/com/rho/rubyext/GeoLocation.java +42 -5
  31. data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +3 -4
  32. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +33 -107
  33. data/platform/iphone/Classes/RhoRunnerAppDelegate.m +2 -0
  34. data/platform/iphone/Info.plist +1 -1
  35. data/platform/iphone/rbuild/iphone.rake +1 -1
  36. data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +4 -0
  37. data/platform/shared/common/RhoMutexLock.h +8 -1
  38. data/platform/shared/common/RhodesApp.cpp +1 -1
  39. data/platform/shared/db/DBAdapter.cpp +77 -8
  40. data/platform/shared/db/DBAdapter.h +24 -9
  41. data/platform/shared/db/DBResult.cpp +19 -0
  42. data/platform/shared/db/DBResult.h +7 -5
  43. data/platform/shared/net/HttpServer.cpp +2 -0
  44. data/platform/shared/ruby/ext/rho/rhoruby.c +55 -0
  45. data/platform/shared/ruby/ext/rho/rhoruby.h +9 -0
  46. data/platform/shared/ruby/ext/rho/rhosupport.c +13 -4
  47. data/platform/shared/ruby/ext/sqlite3_api/sqlite3_api_wrap.c +21 -0
  48. data/platform/shared/ruby/thread_pthread.c +4 -4
  49. data/platform/shared/ruby/thread_win32.c +4 -4
  50. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +19 -1
  51. data/platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java +57 -24
  52. data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +6 -1
  53. data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +2 -2
  54. data/platform/shared/rubyJVM/src/com/rho/sync/SyncThread.java +5 -5
  55. data/platform/shared/sync/SyncSource.cpp +1 -1
  56. data/platform/shared/sync/SyncThread.cpp +6 -9
  57. data/platform/wm/rhodes/Rhodes.cpp +4 -0
  58. data/rakefile.rb +1 -1
  59. metadata +13 -3
  60. data/platform/bb/rhodes/src/rhomobile/Alert.java +0 -65
@@ -37,6 +37,7 @@ lib/extensions/debugger/debugger.rb
37
37
  lib/extensions/digest/digest/hmac.rb
38
38
  lib/extensions/digest/digest.rb
39
39
  lib/extensions/digest/ext/build
40
+ lib/extensions/digest/ext/build.bat
40
41
  lib/extensions/digest/ext/defs.h
41
42
  lib/extensions/digest/ext/depend
42
43
  lib/extensions/digest/ext/digest.c
@@ -161,6 +162,15 @@ lib/extensions/rholang/lang_sr.rb
161
162
  lib/extensions/rholang/rhoerror_ru.rb
162
163
  lib/extensions/rholang/rhomsg_ru.rb
163
164
  lib/extensions/set/set.rb
165
+ lib/extensions/uri/uri/common.rb
166
+ lib/extensions/uri/uri/ftp.rb
167
+ lib/extensions/uri/uri/generic.rb
168
+ lib/extensions/uri/uri/http.rb
169
+ lib/extensions/uri/uri/https.rb
170
+ lib/extensions/uri/uri/ldap.rb
171
+ lib/extensions/uri/uri/ldaps.rb
172
+ lib/extensions/uri/uri/mailto.rb
173
+ lib/extensions/uri/uri.rb
164
174
  lib/framework/bsearch.rb
165
175
  lib/framework/builtinME.rb
166
176
  lib/framework/date/format.rb
@@ -514,11 +524,11 @@ platform/bb/rhodes/src/com/rho/net/SSLSocket.java
514
524
  platform/bb/rhodes/src/com/rho/net/TCPSocket.java
515
525
  platform/bb/rhodes/src/com/rho/RhoMainScreen.java
516
526
  platform/bb/rhodes/src/com/rho/RhoRubyHelper.java
527
+ platform/bb/rhodes/src/com/rho/rubyext/Alert.java
517
528
  platform/bb/rhodes/src/com/rho/rubyext/GeoLocation.java
518
529
  platform/bb/rhodes/src/com/rho/rubyext/System.java
519
530
  platform/bb/rhodes/src/com/rho/rubyext/XMLParser.java
520
531
  platform/bb/rhodes/src/com/rho/Version.java
521
- platform/bb/rhodes/src/rhomobile/Alert.java
522
532
  platform/bb/rhodes/src/rhomobile/camera/Camera.java
523
533
  platform/bb/rhodes/src/rhomobile/camera/CameraFilesListener.java
524
534
  platform/bb/rhodes/src/rhomobile/camera/CameraScreen.java
data/Rakefile CHANGED
@@ -127,7 +127,7 @@ def add_linker_library(libraryname)
127
127
  tmpdir = $startdir + "/platform/iphone/build/rhorunner.build/#{$configuration}-" +
128
128
  ( simulator ? "iphonesimulator" : "iphoneos") + "/rhorunner.build"
129
129
  end
130
- $ldflags << "#{tmpdir}/#{libraryname}\n" unless $ldflags.nil?
130
+ $ldflags << "#{tmpdir}/lib#{libraryname}.a\n" unless $ldflags.nil?
131
131
  end
132
132
 
133
133
  def set_linker_flags
@@ -9,16 +9,16 @@ def build_extension(name, arch)
9
9
 
10
10
  args = []
11
11
  args << "-I."
12
- args << "-I../../../../platform/shared/ruby/include"
13
- args << "-I../../../../platform/shared"
12
+ args << "-I#{$rootdir}/platform/shared/ruby/include"
13
+ args << "-I#{$rootdir}/platform/shared"
14
14
 
15
15
  if $android
16
- args << "-I../../../../platform/shared/ruby/linux"
17
- args << "-I../../../../platform/shared/ruby/generated"
16
+ args << "-I#{$rootdir}/platform/shared/ruby/linux"
17
+ args << "-I#{$rootdir}/platform/shared/ruby/generated"
18
18
  cc_compile f, $tempdir, args or exit 1
19
19
 
20
20
  else
21
- args << "-I../../../../platform/shared/ruby/iphone"
21
+ args << "-I#{$rootdir}/platform/shared/ruby/iphone"
22
22
  args << "-D_XOPEN_SOURCE"
23
23
  args << "-D_DARWIN_C_SOURCE"
24
24
  args << "-isysroot #{$sdkroot}"
@@ -74,8 +74,13 @@ namespace "build" do
74
74
  task :config do
75
75
  if ENV['ANDROID_API_LEVEL'] != nil
76
76
  $targetdir = ENV['TARGET_TEMP_DIR']
77
+ raise "TARGET_TEMP_DIR is not set" if $targetdir.nil?
77
78
  $tempdir = ENV['TEMP_FILES_DIR']
78
- require File.dirname(__FILE__) + '/../../../../platform/android/build/androidcommon.rb'
79
+ raise "TEMP_FILES_DIR is not set" if $tempdir.nil?
80
+ $rootdir = ENV['RHO_ROOT']
81
+ raise "RHO_ROOT is not set" if $rootdir.nil?
82
+
83
+ require File.join($rootdir, 'platform/android/build/androidcommon.rb')
79
84
 
80
85
  setup_ndk(ENV['ANDROID_NDK'],ENV['ANDROID_API_LEVEL'])
81
86
 
@@ -0,0 +1,2 @@
1
+ rake --trace
2
+
@@ -0,0 +1,29 @@
1
+ #
2
+ # URI support for Ruby
3
+ #
4
+ # Author:: Akira Yamada <akira@ruby-lang.org>
5
+ # Documentation:: Akira Yamada <akira@ruby-lang.org>, Dmitry V. Sabanin <sdmitry@lrn.ru>
6
+ # License::
7
+ # Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
8
+ # You can redistribute it and/or modify it under the same term as Ruby.
9
+ # Revision:: $Id: uri.rb 13772 2007-10-25 00:53:34Z akira $
10
+ #
11
+ # See URI for documentation
12
+ #
13
+
14
+ module URI
15
+ # :stopdoc:
16
+ VERSION_CODE = '000911'.freeze
17
+ VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
18
+ # :startdoc:
19
+
20
+ end
21
+
22
+ require 'uri/common'
23
+ require 'uri/generic'
24
+ require 'uri/ftp'
25
+ require 'uri/http'
26
+ require 'uri/https'
27
+ require 'uri/ldap'
28
+ require 'uri/ldaps'
29
+ require 'uri/mailto'
@@ -0,0 +1,727 @@
1
+ # = uri/common.rb
2
+ #
3
+ # Author:: Akira Yamada <akira@ruby-lang.org>
4
+ # Revision:: $Id: common.rb 22760 2009-03-04 09:21:12Z yugui $
5
+ # License::
6
+ # You can redistribute it and/or modify it under the same term as Ruby.
7
+ #
8
+
9
+ module URI
10
+ module REGEXP
11
+ #
12
+ # Patterns used to parse URI's
13
+ #
14
+ module PATTERN
15
+ # :stopdoc:
16
+
17
+ # RFC 2396 (URI Generic Syntax)
18
+ # RFC 2732 (IPv6 Literal Addresses in URL's)
19
+ # RFC 2373 (IPv6 Addressing Architecture)
20
+
21
+ # alpha = lowalpha | upalpha
22
+ ALPHA = "a-zA-Z"
23
+ # alphanum = alpha | digit
24
+ ALNUM = "#{ALPHA}\\d"
25
+
26
+ # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
27
+ # "a" | "b" | "c" | "d" | "e" | "f"
28
+ HEX = "a-fA-F\\d"
29
+ # escaped = "%" hex hex
30
+ ESCAPED = "%[#{HEX}]{2}"
31
+ # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
32
+ # "(" | ")"
33
+ # unreserved = alphanum | mark
34
+ UNRESERVED = "-_.!~*'()#{ALNUM}"
35
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
36
+ # "$" | ","
37
+ # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
38
+ # "$" | "," | "[" | "]" (RFC 2732)
39
+ RESERVED = ";/?:@&=+$,\\[\\]"
40
+
41
+ # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
42
+ DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
43
+ # toplabel = alpha | alpha *( alphanum | "-" ) alphanum
44
+ TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)"
45
+ # hostname = *( domainlabel "." ) toplabel [ "." ]
46
+ HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
47
+
48
+ # :startdoc:
49
+ end # PATTERN
50
+
51
+ # :startdoc:
52
+ end # REGEXP
53
+
54
+ class Parser
55
+ include REGEXP
56
+
57
+ #
58
+ # == Synopsis
59
+ #
60
+ # URI::Parser.new([opts])
61
+ #
62
+ # == Args
63
+ #
64
+ # The constructor accepts a hash as options for parser.
65
+ # Keys of options are pattern names of URI components
66
+ # and values of options are pattern strings.
67
+ # The constructor generetes set of regexps for parsing URIs.
68
+ #
69
+ # You can use the following keys:
70
+ #
71
+ # * <tt>:ESCAPED</tt> (URI::PATTERN::ESCAPED in default)
72
+ # * <tt>:UNRESERVED</tt> (URI::PATTERN::UNRESERVED in default)
73
+ # * <tt>:DOMLABEL</tt> (URI::PATTERN::DOMLABEL in default)
74
+ # * <tt>:TOPLABEL</tt> (URI::PATTERN::TOPLABEL in default)
75
+ # * <tt>:HOSTNAME</tt> (URI::PATTERN::HOSTNAME in default)
76
+ #
77
+ # == Examples
78
+ #
79
+ # p = URI::Parser.new(:ESCPAED => "(?:%[a-fA-F0-9]{2}|%u[a-fA-F0-9]{4})"
80
+ # u = p.parse("http://example.jp/%uABCD") #=> #<URI::HTTP:0xb78cf4f8 URL:http://example.jp/%uABCD>
81
+ # URI.parse(u.to_s) #=> raises URI::InvalidURIError
82
+ #
83
+ # s = "http://examle.com/ABCD"
84
+ # u1 = p.parse(s) #=> #<URI::HTTP:0xb78c3220 URL:http://example.com/ABCD>
85
+ # u2 = URI.parse(s) #=> #<URI::HTTP:0xb78b6d54 URL:http://example.com/ABCD>
86
+ # u1 == u2 #=> true
87
+ # u1.eql?(u2) #=> false
88
+ #
89
+ def initialize(opts = {})
90
+ @pattern = initialize_pattern(opts)
91
+ @pattern.each_value {|v| v.freeze}
92
+ @pattern.freeze
93
+
94
+ @regexp = initialize_regexp(@pattern)
95
+ @regexp.each_value {|v| v.freeze}
96
+ @regexp.freeze
97
+ end
98
+ attr_reader :pattern, :regexp
99
+
100
+ def split(uri)
101
+ case uri
102
+ when ''
103
+ # null uri
104
+
105
+ when @regexp[:ABS_URI]
106
+ scheme, opaque, userinfo, host, port,
107
+ registry, path, query, fragment = $~[1..-1]
108
+
109
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
110
+
111
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
112
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
113
+ # opaque_part = uric_no_slash *uric
114
+
115
+ # abs_path = "/" path_segments
116
+ # net_path = "//" authority [ abs_path ]
117
+
118
+ # authority = server | reg_name
119
+ # server = [ [ userinfo "@" ] hostport ]
120
+
121
+ if !scheme
122
+ raise InvalidURIError,
123
+ "bad URI(absolute but no scheme): #{uri}"
124
+ end
125
+ if !opaque && (!path && (!host && !registry))
126
+ raise InvalidURIError,
127
+ "bad URI(absolute but no path): #{uri}"
128
+ end
129
+
130
+ when @regexp[:REL_URI]
131
+ scheme = nil
132
+ opaque = nil
133
+
134
+ userinfo, host, port, registry,
135
+ rel_segment, abs_path, query, fragment = $~[1..-1]
136
+ if rel_segment && abs_path
137
+ path = rel_segment + abs_path
138
+ elsif rel_segment
139
+ path = rel_segment
140
+ elsif abs_path
141
+ path = abs_path
142
+ end
143
+
144
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
145
+
146
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
147
+
148
+ # net_path = "//" authority [ abs_path ]
149
+ # abs_path = "/" path_segments
150
+ # rel_path = rel_segment [ abs_path ]
151
+
152
+ # authority = server | reg_name
153
+ # server = [ [ userinfo "@" ] hostport ]
154
+
155
+ else
156
+ raise InvalidURIError, "bad URI(is not URI?): #{uri}"
157
+ end
158
+
159
+ path = '' if !path && !opaque # (see RFC2396 Section 5.2)
160
+ ret = [
161
+ scheme,
162
+ userinfo, host, port, # X
163
+ registry, # X
164
+ path, # Y
165
+ opaque, # Y
166
+ query,
167
+ fragment
168
+ ]
169
+ return ret
170
+ end
171
+
172
+ def parse(uri)
173
+ scheme, userinfo, host, port,
174
+ registry, path, opaque, query, fragment = self.split(uri)
175
+
176
+ if scheme && URI.scheme_list.include?(scheme.upcase)
177
+ URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
178
+ registry, path, opaque, query,
179
+ fragment, self)
180
+ else
181
+ Generic.new(scheme, userinfo, host, port,
182
+ registry, path, opaque, query,
183
+ fragment, self)
184
+ end
185
+ end
186
+
187
+ def join(*str)
188
+ u = self.parse(str[0])
189
+ str[1 .. -1].each do |x|
190
+ u = u.merge(x)
191
+ end
192
+ u
193
+ end
194
+
195
+ def extract(str, schemes = nil, &block)
196
+ if block_given?
197
+ str.scan(make_regexp(schemes)) { yield $& }
198
+ nil
199
+ else
200
+ result = []
201
+ str.scan(make_regexp(schemes)) { result.push $& }
202
+ result
203
+ end
204
+ end
205
+
206
+ def make_regexp(schemes = nil)
207
+ unless schemes
208
+ @regexp[:ABS_URI_REF]
209
+ else
210
+ /(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
211
+ end
212
+ end
213
+
214
+ def escape(str, unsafe = @regexp[:UNSAFE])
215
+ unless unsafe.kind_of?(Regexp)
216
+ # perhaps unsafe is String object
217
+ unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false)
218
+ end
219
+ str.gsub(unsafe) do
220
+ us = $&
221
+ tmp = ''
222
+ us.each_byte do |uc|
223
+ tmp << sprintf('%%%02X', uc)
224
+ end
225
+ tmp
226
+ end.force_encoding("US-ASCII")#Encoding::US_ASCII)
227
+ end
228
+
229
+ def unescape(str, escaped = @regexp[:ESCAPED])
230
+ str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(str.encoding)
231
+ end
232
+
233
+ @@to_s = Kernel.instance_method(:to_s)
234
+ def inspect
235
+ @@to_s.bind(self).call
236
+ end
237
+
238
+ private
239
+
240
+ def initialize_pattern(opts = {})
241
+ ret = {}
242
+ ret[:ESCAPED] = escaped = (opts.delete(:ESCAPED) || PATTERN::ESCAPED)
243
+ ret[:UNRESERVED] = unreserved = opts.delete(:UNRESERVED) || PATTERN::UNRESERVED
244
+ ret[:RESERVED] = reserved = opts.delete(:RESERVED) || PATTERN::RESERVED
245
+ ret[:DOMLABEL] = domlabel = opts.delete(:DOMLABEL) || PATTERN::DOMLABEL
246
+ ret[:TOPLABEL] = toplabel = opts.delete(:TOPLABEL) || PATTERN::TOPLABEL
247
+ ret[:HOSTNAME] = hostname = opts.delete(:HOSTNAME)
248
+
249
+ # RFC 2396 (URI Generic Syntax)
250
+ # RFC 2732 (IPv6 Literal Addresses in URL's)
251
+ # RFC 2373 (IPv6 Addressing Architecture)
252
+
253
+ # uric = reserved | unreserved | escaped
254
+ ret[:URIC] = uric = "(?:[#{unreserved}#{reserved}]|#{escaped})"
255
+ # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
256
+ # "&" | "=" | "+" | "$" | ","
257
+ ret[:URIC_NO_SLASH] = uric_no_slash = "(?:[#{unreserved};?:@&=+$,]|#{escaped})"
258
+ # query = *uric
259
+ ret[:QUERY] = query = "#{uric}*"
260
+ # fragment = *uric
261
+ ret[:FRAGMENT] = fragment = "#{uric}*"
262
+
263
+ # hostname = *( domainlabel "." ) toplabel [ "." ]
264
+ unless hostname
265
+ ret[:HOSTNAME] = hostname = "(?:#{domlabel}\\.)*#{toplabel}\\.?"
266
+ end
267
+
268
+ # RFC 2373, APPENDIX B:
269
+ # IPv6address = hexpart [ ":" IPv4address ]
270
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
271
+ # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
272
+ # hexseq = hex4 *( ":" hex4)
273
+ # hex4 = 1*4HEXDIG
274
+ #
275
+ # XXX: This definition has a flaw. "::" + IPv4address must be
276
+ # allowed too. Here is a replacement.
277
+ #
278
+ # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
279
+ ret[:IPV4ADDR] = ipv4addr = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
280
+ # hex4 = 1*4HEXDIG
281
+ hex4 = "[#{PATTERN::HEX}]{1,4}"
282
+ # lastpart = hex4 | IPv4address
283
+ lastpart = "(?:#{hex4}|#{ipv4addr})"
284
+ # hexseq1 = *( hex4 ":" ) hex4
285
+ hexseq1 = "(?:#{hex4}:)*#{hex4}"
286
+ # hexseq2 = *( hex4 ":" ) lastpart
287
+ hexseq2 = "(?:#{hex4}:)*#{lastpart}"
288
+ # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ]
289
+ ret[:IPV6ADDR] = ipv6addr = "(?:#{hexseq2}|(?:#{hexseq1})?::(?:#{hexseq2})?)"
290
+
291
+ # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT
292
+ # unused
293
+
294
+ # ipv6reference = "[" IPv6address "]" (RFC 2732)
295
+ ret[:IPV6REF] = ipv6ref = "\\[#{ipv6addr}\\]"
296
+
297
+ # host = hostname | IPv4address
298
+ # host = hostname | IPv4address | IPv6reference (RFC 2732)
299
+ ret[:HOST] = host = "(?:#{hostname}|#{ipv4addr}|#{ipv6ref})"
300
+ # port = *digit
301
+ port = '\d*'
302
+ # hostport = host [ ":" port ]
303
+ ret[:HOSTPORT] = hostport = "#{host}(?::#{port})?"
304
+
305
+ # userinfo = *( unreserved | escaped |
306
+ # ";" | ":" | "&" | "=" | "+" | "$" | "," )
307
+ ret[:USERINFO] = userinfo = "(?:[#{unreserved};:&=+$,]|#{escaped})*"
308
+
309
+ # pchar = unreserved | escaped |
310
+ # ":" | "@" | "&" | "=" | "+" | "$" | ","
311
+ pchar = "(?:[#{unreserved}:@&=+$,]|#{escaped})"
312
+ # param = *pchar
313
+ param = "#{pchar}*"
314
+ # segment = *pchar *( ";" param )
315
+ segment = "#{pchar}*(?:;#{param})*"
316
+ # path_segments = segment *( "/" segment )
317
+ ret[:PATH_SEGMENTS] = path_segments = "#{segment}(?:/#{segment})*"
318
+
319
+ # server = [ [ userinfo "@" ] hostport ]
320
+ server = "(?:#{userinfo}@)?#{hostport}"
321
+ # reg_name = 1*( unreserved | escaped | "$" | "," |
322
+ # ";" | ":" | "@" | "&" | "=" | "+" )
323
+ ret[:REG_NAME] = reg_name = "(?:[#{unreserved}$,;:@&=+]|#{escaped})+"
324
+ # authority = server | reg_name
325
+ authority = "(?:#{server}|#{reg_name})"
326
+
327
+ # rel_segment = 1*( unreserved | escaped |
328
+ # ";" | "@" | "&" | "=" | "+" | "$" | "," )
329
+ ret[:REL_SEGMENT] = rel_segment = "(?:[#{unreserved};@&=+$,]|#{escaped})+"
330
+
331
+ # scheme = alpha *( alpha | digit | "+" | "-" | "." )
332
+ ret[:SCHEME] = scheme = "[#{PATTERN::ALPHA}][-+.#{PATTERN::ALPHA}\\d]*"
333
+
334
+ # abs_path = "/" path_segments
335
+ ret[:ABS_PATH] = abs_path = "/#{path_segments}"
336
+ # rel_path = rel_segment [ abs_path ]
337
+ ret[:REL_PATH] = rel_path = "#{rel_segment}(?:#{abs_path})?"
338
+ # net_path = "//" authority [ abs_path ]
339
+ ret[:NET_PATH] = net_path = "//#{authority}(?:#{abs_path})?"
340
+
341
+ # hier_part = ( net_path | abs_path ) [ "?" query ]
342
+ ret[:HIER_PART] = hier_part = "(?:#{net_path}|#{abs_path})(?:\\?(?:#{query}))?"
343
+ # opaque_part = uric_no_slash *uric
344
+ ret[:OPAQUE_PART] = opaque_part = "#{uric_no_slash}#{uric}*"
345
+
346
+ # absoluteURI = scheme ":" ( hier_part | opaque_part )
347
+ ret[:ABS_URI] = abs_uri = "#{scheme}:(?:#{hier_part}|#{opaque_part})"
348
+ # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
349
+ ret[:REL_URI] = rel_uri = "(?:#{net_path}|#{abs_path}|#{rel_path})(?:\\?#{query})?"
350
+
351
+ # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
352
+ ret[:URI_REF] = uri_ref = "(?:#{abs_uri}|#{rel_uri})?(?:##{fragment})?"
353
+
354
+ ret[:X_ABS_URI] = "
355
+ (#{scheme}): (?# 1: scheme)
356
+ (?:
357
+ (#{opaque_part}) (?# 2: opaque)
358
+ |
359
+ (?:(?:
360
+ //(?:
361
+ (?:(?:(#{userinfo})@)? (?# 3: userinfo)
362
+ (?:(#{host})(?::(\\d*))?))? (?# 4: host, 5: port)
363
+ |
364
+ (#{reg_name}) (?# 6: registry)
365
+ )
366
+ |
367
+ (?!//)) (?# XXX: '//' is the mark for hostport)
368
+ (#{abs_path})? (?# 7: path)
369
+ )(?:\\?(#{query}))? (?# 8: query)
370
+ )
371
+ (?:\\#(#{fragment}))? (?# 9: fragment)
372
+ "
373
+
374
+ ret[:X_REL_URI] = "
375
+ (?:
376
+ (?:
377
+ //
378
+ (?:
379
+ (?:(#{userinfo})@)? (?# 1: userinfo)
380
+ (#{host})?(?::(\\d*))? (?# 2: host, 3: port)
381
+ |
382
+ (#{reg_name}) (?# 4: registry)
383
+ )
384
+ )
385
+ |
386
+ (#{rel_segment}) (?# 5: rel_segment)
387
+ )?
388
+ (#{abs_path})? (?# 6: abs_path)
389
+ (?:\\?(#{query}))? (?# 7: query)
390
+ (?:\\#(#{fragment}))? (?# 8: fragment)
391
+ "
392
+
393
+ ret
394
+ end
395
+
396
+ def initialize_regexp(pattern)
397
+ ret = {}
398
+
399
+ # for URI::split
400
+ ret[:ABS_URI] = Regexp.new('^' + pattern[:X_ABS_URI] + '$', Regexp::EXTENDED)
401
+ ret[:REL_URI] = Regexp.new('^' + pattern[:X_REL_URI] + '$', Regexp::EXTENDED)
402
+
403
+ # for URI::extract
404
+ ret[:URI_REF] = Regexp.new(pattern[:URI_REF])
405
+ ret[:ABS_URI_REF] = Regexp.new(pattern[:X_ABS_URI], Regexp::EXTENDED)
406
+ ret[:REL_URI_REF] = Regexp.new(pattern[:X_REL_URI], Regexp::EXTENDED)
407
+
408
+ # for URI::escape/unescape
409
+ ret[:ESCAPED] = Regexp.new(pattern[:ESCAPED])
410
+ ret[:UNSAFE] = Regexp.new("[^#{pattern[:UNRESERVED]}#{pattern[:RESERVED]}]")
411
+
412
+ # for Generic#initialize
413
+ ret[:SCHEME] = Regexp.new("^#{pattern[:SCHEME]}$")
414
+ ret[:USERINFO] = Regexp.new("^#{pattern[:USERINFO]}$")
415
+ ret[:HOST] = Regexp.new("^#{pattern[:HOST]}$")
416
+ ret[:PORT] = Regexp.new("^#{pattern[:PORT]}$")
417
+ ret[:OPAQUE] = Regexp.new("^#{pattern[:OPAQUE_PART]}$")
418
+ ret[:REGISTRY] = Regexp.new("^#{pattern[:REG_NAME]}$")
419
+ ret[:ABS_PATH] = Regexp.new("^#{pattern[:ABS_PATH]}$")
420
+ ret[:REL_PATH] = Regexp.new("^#{pattern[:REL_PATH]}$")
421
+ ret[:QUERY] = Regexp.new("^#{pattern[:QUERY]}$")
422
+ ret[:FRAGMENT] = Regexp.new("^#{pattern[:FRAGMENT]}$")
423
+
424
+ ret
425
+ end
426
+ end # class Parser
427
+
428
+ DEFAULT_PARSER = Parser.new
429
+ DEFAULT_PARSER.pattern.each_pair do |sym, str|
430
+ unless REGEXP::PATTERN.const_defined?(sym)
431
+ REGEXP::PATTERN.const_set(sym, str)
432
+ end
433
+ end
434
+ DEFAULT_PARSER.regexp.each_pair do |sym, str|
435
+ const_set(sym, str)
436
+ end
437
+
438
+ module Util # :nodoc:
439
+ def make_components_hash(klass, array_hash)
440
+ tmp = {}
441
+ if array_hash.kind_of?(Array) &&
442
+ array_hash.size == klass.component.size - 1
443
+ klass.component[1..-1].each_index do |i|
444
+ begin
445
+ tmp[klass.component[i + 1]] = array_hash[i].clone
446
+ rescue TypeError
447
+ tmp[klass.component[i + 1]] = array_hash[i]
448
+ end
449
+ end
450
+
451
+ elsif array_hash.kind_of?(Hash)
452
+ array_hash.each do |key, value|
453
+ begin
454
+ tmp[key] = value.clone
455
+ rescue TypeError
456
+ tmp[key] = value
457
+ end
458
+ end
459
+ else
460
+ raise ArgumentError,
461
+ "expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})"
462
+ end
463
+ tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase
464
+
465
+ return tmp
466
+ end
467
+ module_function :make_components_hash
468
+ end
469
+
470
+ module Escape
471
+ #
472
+ # == Synopsis
473
+ #
474
+ # URI.escape(str [, unsafe])
475
+ #
476
+ # == Args
477
+ #
478
+ # +str+::
479
+ # String to replaces in.
480
+ # +unsafe+::
481
+ # Regexp that matches all symbols that must be replaced with codes.
482
+ # By default uses <tt>REGEXP::UNSAFE</tt>.
483
+ # When this argument is a String, it represents a character set.
484
+ #
485
+ # == Description
486
+ #
487
+ # Escapes the string, replacing all unsafe characters with codes.
488
+ #
489
+ # == Usage
490
+ #
491
+ # require 'uri'
492
+ #
493
+ # enc_uri = URI.escape("http://example.com/?a=\11\15")
494
+ # p enc_uri
495
+ # # => "http://example.com/?a=%09%0D"
496
+ #
497
+ # p URI.unescape(enc_uri)
498
+ # # => "http://example.com/?a=\t\r"
499
+ #
500
+ # p URI.escape("@?@!", "!?")
501
+ # # => "@%3F@%21"
502
+ #
503
+ def escape(*arg)
504
+ DEFAULT_PARSER.escape(*arg)
505
+ end
506
+ alias encode escape
507
+ #
508
+ # == Synopsis
509
+ #
510
+ # URI.unescape(str)
511
+ #
512
+ # == Args
513
+ #
514
+ # +str+::
515
+ # Unescapes the string.
516
+ #
517
+ # == Usage
518
+ #
519
+ # require 'uri'
520
+ #
521
+ # enc_uri = URI.escape("http://example.com/?a=\11\15")
522
+ # p enc_uri
523
+ # # => "http://example.com/?a=%09%0D"
524
+ #
525
+ # p URI.unescape(enc_uri)
526
+ # # => "http://example.com/?a=\t\r"
527
+ #
528
+ def unescape(*arg)
529
+ DEFAULT_PARSER.unescape(*arg)
530
+ end
531
+ alias decode unescape
532
+ end
533
+
534
+ extend Escape
535
+ include REGEXP
536
+
537
+ @@schemes = {}
538
+ def self.scheme_list
539
+ @@schemes
540
+ end
541
+
542
+ #
543
+ # Base class for all URI exceptions.
544
+ #
545
+ class Error < StandardError; end
546
+ #
547
+ # Not a URI.
548
+ #
549
+ class InvalidURIError < Error; end
550
+ #
551
+ # Not a URI component.
552
+ #
553
+ class InvalidComponentError < Error; end
554
+ #
555
+ # URI is valid, bad usage is not.
556
+ #
557
+ class BadURIError < Error; end
558
+
559
+ #
560
+ # == Synopsis
561
+ #
562
+ # URI::split(uri)
563
+ #
564
+ # == Args
565
+ #
566
+ # +uri+::
567
+ # String with URI.
568
+ #
569
+ # == Description
570
+ #
571
+ # Splits the string on following parts and returns array with result:
572
+ #
573
+ # * Scheme
574
+ # * Userinfo
575
+ # * Host
576
+ # * Port
577
+ # * Registry
578
+ # * Path
579
+ # * Opaque
580
+ # * Query
581
+ # * Fragment
582
+ #
583
+ # == Usage
584
+ #
585
+ # require 'uri'
586
+ #
587
+ # p URI.split("http://www.ruby-lang.org/")
588
+ # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil]
589
+ #
590
+ def self.split(uri)
591
+ DEFAULT_PARSER.split(uri)
592
+ end
593
+
594
+ #
595
+ # == Synopsis
596
+ #
597
+ # URI::parse(uri_str)
598
+ #
599
+ # == Args
600
+ #
601
+ # +uri_str+::
602
+ # String with URI.
603
+ #
604
+ # == Description
605
+ #
606
+ # Creates one of the URI's subclasses instance from the string.
607
+ #
608
+ # == Raises
609
+ #
610
+ # URI::InvalidURIError
611
+ # Raised if URI given is not a correct one.
612
+ #
613
+ # == Usage
614
+ #
615
+ # require 'uri'
616
+ #
617
+ # uri = URI.parse("http://www.ruby-lang.org/")
618
+ # p uri
619
+ # # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>
620
+ # p uri.scheme
621
+ # # => "http"
622
+ # p uri.host
623
+ # # => "www.ruby-lang.org"
624
+ #
625
+ def self.parse(uri)
626
+ DEFAULT_PARSER.parse(uri)
627
+ end
628
+
629
+ #
630
+ # == Synopsis
631
+ #
632
+ # URI::join(str[, str, ...])
633
+ #
634
+ # == Args
635
+ #
636
+ # +str+::
637
+ # String(s) to work with
638
+ #
639
+ # == Description
640
+ #
641
+ # Joins URIs.
642
+ #
643
+ # == Usage
644
+ #
645
+ # require 'uri'
646
+ #
647
+ # p URI.join("http://localhost/","main.rbx")
648
+ # # => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>
649
+ #
650
+ def self.join(*str)
651
+ DEFAULT_PARSER.join(*str)
652
+ end
653
+
654
+ #
655
+ # == Synopsis
656
+ #
657
+ # URI::extract(str[, schemes][,&blk])
658
+ #
659
+ # == Args
660
+ #
661
+ # +str+::
662
+ # String to extract URIs from.
663
+ # +schemes+::
664
+ # Limit URI matching to a specific schemes.
665
+ #
666
+ # == Description
667
+ #
668
+ # Extracts URIs from a string. If block given, iterates through all matched URIs.
669
+ # Returns nil if block given or array with matches.
670
+ #
671
+ # == Usage
672
+ #
673
+ # require "uri"
674
+ #
675
+ # URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
676
+ # # => ["http://foo.example.com/bla", "mailto:test@example.com"]
677
+ #
678
+ def self.extract(str, schemes = nil, &block)
679
+ DEFAULT_PARSER.extract(str, schemes, &block)
680
+ end
681
+
682
+ #
683
+ # == Synopsis
684
+ #
685
+ # URI::regexp([match_schemes])
686
+ #
687
+ # == Args
688
+ #
689
+ # +match_schemes+::
690
+ # Array of schemes. If given, resulting regexp matches to URIs
691
+ # whose scheme is one of the match_schemes.
692
+ #
693
+ # == Description
694
+ # Returns a Regexp object which matches to URI-like strings.
695
+ # The Regexp object returned by this method includes arbitrary
696
+ # number of capture group (parentheses). Never rely on it's number.
697
+ #
698
+ # == Usage
699
+ #
700
+ # require 'uri'
701
+ #
702
+ # # extract first URI from html_string
703
+ # html_string.slice(URI.regexp)
704
+ #
705
+ # # remove ftp URIs
706
+ # html_string.sub(URI.regexp(['ftp'])
707
+ #
708
+ # # You should not rely on the number of parentheses
709
+ # html_string.scan(URI.regexp) do |*matches|
710
+ # p $&
711
+ # end
712
+ #
713
+ def self.regexp(schemes = nil)
714
+ DEFAULT_PARSER.make_regexp(schemes)
715
+ end
716
+
717
+ end
718
+
719
+ module Kernel
720
+ # alias for URI.parse.
721
+ #
722
+ # This method is introduced at 1.8.2.
723
+ def URI(uri_str) # :doc:
724
+ URI.parse(uri_str)
725
+ end
726
+ module_function :URI
727
+ end