p2ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +27 -0
  2. data/HISTORY +7 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +24 -0
  5. data/Rakefile +42 -0
  6. data/VERSION +1 -0
  7. data/bin/olegen.rb +368 -0
  8. data/features/p2ruby.feature +9 -0
  9. data/features/step_definitions/p2ruby_steps.rb +0 -0
  10. data/features/support/env.rb +10 -0
  11. data/features/support/world.rb +12 -0
  12. data/lib/extension.rb +19 -0
  13. data/lib/ole20110223-013209.rb +1677 -0
  14. data/lib/p2ruby/application.rb +111 -0
  15. data/lib/p2ruby/base.rb +59 -0
  16. data/lib/p2ruby/connection.rb +250 -0
  17. data/lib/p2ruby/data_stream.rb +215 -0
  18. data/lib/p2ruby/library.rb +24 -0
  19. data/lib/p2ruby/message.rb +150 -0
  20. data/lib/p2ruby/message_factory.rb +70 -0
  21. data/lib/p2ruby/record.rb +104 -0
  22. data/lib/p2ruby/router.rb +45 -0
  23. data/lib/p2ruby/table_set.rb +166 -0
  24. data/lib/p2ruby.rb +156 -0
  25. data/lib/version.rb +8 -0
  26. data/lib/win32ole-pr.rb +5540 -0
  27. data/spec/encoding_spec.rb +15 -0
  28. data/spec/p2ruby/application_spec.rb +35 -0
  29. data/spec/p2ruby/connection_spec.rb +293 -0
  30. data/spec/p2ruby/data_stream_spec.rb +218 -0
  31. data/spec/p2ruby/library_spec.rb +42 -0
  32. data/spec/p2ruby/message_factory_spec.rb +69 -0
  33. data/spec/p2ruby/message_spec.rb +159 -0
  34. data/spec/p2ruby/record_spec.rb +85 -0
  35. data/spec/p2ruby/router_spec.rb +54 -0
  36. data/spec/p2ruby/table_set_spec.rb +132 -0
  37. data/spec/p2ruby_spec.rb +46 -0
  38. data/spec/spec_helper.rb +78 -0
  39. data/tasks/common.rake +18 -0
  40. data/tasks/doc.rake +14 -0
  41. data/tasks/gem.rake +40 -0
  42. data/tasks/git.rake +34 -0
  43. data/tasks/spec.rake +16 -0
  44. data/tasks/version.rake +71 -0
  45. metadata +149 -0
data/.gitignore ADDED
@@ -0,0 +1,27 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ config
19
+ rdoc
20
+ pkg
21
+ log
22
+ tmp
23
+ .idea
24
+ .bundle
25
+
26
+ ## PROJECT::SPECIFIC
27
+ *.db
data/HISTORY ADDED
@@ -0,0 +1,7 @@
1
+ == 0.0.0 / 2011-02-14
2
+
3
+ * Birthday!
4
+
5
+ == 0.1.0 / 2011-03-19
6
+
7
+ * OLE wrappers functional
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Arvicco
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ = p2ruby
2
+ by:: Arvicco
3
+ url:: http://github.com/arvicco/p2ruby
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ruby bindings and wrapper classes for P2ClientGate.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ All implemented COM classes wrapped except for CP2DataBuffer. Most event interfaces work,
12
+ except for IP2AsyncEvent* since they are not implemented anywhere.
13
+
14
+ == REQUIREMENTS:
15
+
16
+ * Plaza 2 gateway account
17
+ * P2ClientGate installed and connected to Plaza 2 gateway
18
+
19
+ == INSTALL:
20
+
21
+ $ sudo gem install p2ruby
22
+
23
+ == LICENSE:
24
+ Copyright (c) 2010 Arvicco. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ begin
2
+ require 'rake'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rake', '~> 0.8.3.1'
6
+ require 'rake'
7
+ end
8
+
9
+ require 'pathname'
10
+
11
+ BASE_PATH = Pathname.new(__FILE__).dirname
12
+ LIB_PATH = BASE_PATH + 'lib'
13
+ PKG_PATH = BASE_PATH + 'pkg'
14
+ DOC_PATH = BASE_PATH + 'rdoc'
15
+ P2_PATH = BASE_PATH + 'p2'
16
+
17
+ $LOAD_PATH.unshift LIB_PATH.to_s
18
+ require 'version'
19
+
20
+ NAME = 'p2ruby'
21
+ CLASS_NAME = P2
22
+
23
+ # Load rakefile tasks
24
+ Dir['tasks/*.rake'].sort.each { |file| load file }
25
+
26
+ # Project-specific tasks
27
+
28
+ namespace :ole do
29
+ desc "Register P2ClientGate.dll COM/OLE objects with Windows"
30
+ task :register do
31
+ cd P2_PATH
32
+ system 'regsvr32 P2ClientGate.dll'
33
+ cd BASE_PATH
34
+ end
35
+
36
+ desc "Generate OLE class stubs from typelib"
37
+ task :generate do
38
+ puts "Generate P2 OLE classes"
39
+ filename = Time.now.strftime "ole%Y%m%d-%H%M%S"
40
+ system "ruby bin/olegen.rb > lib/#{filename}.rb"
41
+ end
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/olegen.rb ADDED
@@ -0,0 +1,368 @@
1
+ # View of /branches/ruby_1_9_2/ext/win32ole/sample/olegen.rb
2
+ #
3
+ # Parent Directory Parent Directory | Revision Log Revision Log
4
+ # Revision 27657 - (download) (annotate)
5
+ # Fri May 7 09:08:53 2010 UTC (9 months, 1 week ago) by yugui
6
+ # File size: 8428 byte(s)
7
+ #
8
+ # branches ruby_1_9_2 from r27656 on the trunk for release process of Ruby 1.9.2.
9
+ #
10
+ #-----------------------------
11
+ # olegen.rb
12
+ #-----------------------------
13
+
14
+ require 'win32ole'
15
+
16
+ class String
17
+ # returns snake_case representation of string
18
+ def snake_case
19
+ gsub(/([a-z])([A-Z0-9])/, '\1_\2').downcase
20
+ end
21
+ end
22
+
23
+ class WIN32COMGen
24
+ def initialize(typelib)
25
+ @typelib = typelib
26
+ @reciever = ""
27
+ end
28
+
29
+ attr_reader :typelib
30
+
31
+ def ole_classes(typelib)
32
+ begin
33
+ @ole = WIN32OLE.new(typelib)
34
+ [@ole.ole_obj_help]
35
+ rescue
36
+ WIN32OLE_TYPE.ole_classes(typelib)
37
+ end
38
+ end
39
+
40
+ def generate_args(method)
41
+ args = []
42
+ if method.size_opt_params >= 0
43
+ size_required_params = method.size_params - method.size_opt_params
44
+ else
45
+ size_required_params = method.size_params - 1
46
+ end
47
+ size_required_params.times do |i|
48
+ if method.params[i]
49
+ param = method.params[i].name.snake_case || "arg#{i}"
50
+ param += "=nil" if method.params[i].optional?
51
+ args.push param
52
+ end
53
+ end
54
+ if method.size_opt_params >= 0
55
+ method.size_opt_params.times do |i|
56
+ if method.params[i]
57
+ param = method.params[i].name.snake_case || "arg#{i}" + "=nil"
58
+ else
59
+ param = "arg#{i + size_required_params}=nil"
60
+ end
61
+ args.push param
62
+ end
63
+ else
64
+ args.push "*args"
65
+ end
66
+ args.push "val" if method.invoke_kind == 'PROPERTYPUT'
67
+ args.join(", ")
68
+ end
69
+
70
+ def generate_argtype(typedetails)
71
+ ts = ''
72
+ typedetails.each do |t|
73
+ case t
74
+ when 'CARRAY', 'VOID', 'UINT', 'RESULT', 'DECIMAL' #, 'I8', 'UI8'
75
+ ts << "\"??? NOT SUPPORTED TYPE:`#{t}'\""
76
+ when 'USERDEFINED', 'Unknown Type 9'
77
+ ts << 'VT_DISPATCH'
78
+ break;
79
+ when 'SAFEARRAY'
80
+ ts << 'VT_ARRAY|'
81
+ when 'PTR'
82
+ ts << 'VT_BYREF|'
83
+ when 'INT'
84
+ ts << 'VT_I4'
85
+ else
86
+ if String === t
87
+ ts << 'VT_' + t
88
+ end
89
+ end
90
+ end
91
+ if ts.empty?
92
+ ts = 'VT_VARIANT'
93
+ elsif ts[-1] == ?|
94
+ ts += 'VT_VARIANT'
95
+ end
96
+ ts
97
+ end
98
+
99
+ def generate_argtypes(method, proptypes)
100
+ types = method.params.collect { |param|
101
+ generate_argtype(param.ole_type_detail)
102
+ }.join(", ")
103
+ if proptypes
104
+ types += ", " if types.size > 0
105
+ types += generate_argtype(proptypes)
106
+ end
107
+ types
108
+ end
109
+
110
+ def generate_method_body(method, disptype, types=nil)
111
+ # Check if we need to keep WIN32OLE::ARGV to access OUT args...
112
+ args = generate_method_args_help(method)
113
+ (args && args['OUT'] ? " keep_lastargs " : " ") +
114
+ "#{@reciever}#{disptype}(#{method.dispid}, " +
115
+ "[#{generate_args(method).gsub('=nil', '')}], " +
116
+ "[#{generate_argtypes(method, types)}])"
117
+ end
118
+
119
+ def generate_method_help(method, type = nil)
120
+ str = " # "
121
+ typed_name = "#{type || method.return_type} #{method.name}"
122
+ if method.helpstring && method.helpstring != ""
123
+ if method.helpstring[method.name]
124
+ str += method.helpstring.sub(method.name, typed_name)
125
+ else
126
+ str += typed_name + ': ' + method.helpstring
127
+ end
128
+ else
129
+ str += typed_name
130
+ end
131
+ str += " - EVENT in #{method.event_interface}" if method.event?
132
+ args_help = generate_method_args_help(method)
133
+ str += "\n#{args_help}" if args_help
134
+ str
135
+ end
136
+
137
+ def generate_method_args_help(method)
138
+ args = []
139
+ method.params.each_with_index { |param, i|
140
+ h = " # #{param.ole_type} #{param.name.snake_case}"
141
+ inout = []
142
+ inout.push "IN" if param.input?
143
+ inout.push "OUT" if param.output?
144
+ h += " [#{inout.join('/')}]"
145
+ h += " ( = #{param.default})" if param.default
146
+ args.push h
147
+ }
148
+ if args.size > 0
149
+ args.join("\n")
150
+ else
151
+ nil
152
+ end
153
+ end
154
+
155
+ def generate_method(method, disptype, io = STDOUT, types = nil)
156
+ io.puts "\n"
157
+ io.puts generate_method_help(method)
158
+ if method.invoke_kind == 'PROPERTYPUT'
159
+ io.print " def #{method.name}=("
160
+ else
161
+ io.print " def #{method.name}("
162
+ end
163
+ io.print generate_args(method)
164
+ io.puts ")"
165
+ io.puts generate_method_body(method, disptype, types)
166
+ io.puts " end"
167
+ end
168
+
169
+ def generate_propputref_methods(klass, io = STDOUT)
170
+ klass.ole_methods.select { |method|
171
+ method.invoke_kind == 'PROPERTYPUTREF' && method.visible?
172
+ }.each do |method|
173
+ generate_method(method, io)
174
+ end
175
+ end
176
+
177
+ def generate_properties_with_args(klass, io = STDOUT)
178
+ klass.ole_methods.select { |method|
179
+ method.invoke_kind == 'PROPERTYGET' &&
180
+ method.visible? &&
181
+ method.size_params > 0
182
+ }.each do |method|
183
+ types = method.return_type_detail
184
+ io.puts "\n"
185
+ io.puts generate_method_help(method, types[0])
186
+ io.puts " def #{method.name}"
187
+ if klass.ole_type == "Class"
188
+ io.print " @_#{method.name} ||= OLEProperty.new(@ole, #{method.dispid}, ["
189
+ else
190
+ io.print " @_#{method.name} ||= OLEProperty.new(self, #{method.dispid}, ["
191
+ end
192
+ io.print generate_argtypes(method, nil)
193
+ io.print "], ["
194
+ io.print generate_argtypes(method, types)
195
+ io.puts "])"
196
+ io.puts " end"
197
+ end
198
+ end
199
+
200
+ def generate_propput_methods(klass, io = STDOUT)
201
+ klass.ole_methods.select { |method|
202
+ method.invoke_kind == 'PROPERTYPUT' && method.visible? &&
203
+ method.size_params == 1
204
+ }.each do |method|
205
+ ms = klass.ole_methods.select { |m|
206
+ m.invoke_kind == 'PROPERTYGET' &&
207
+ m.dispid == method.dispid
208
+ }
209
+ types = []
210
+ if ms.size == 1
211
+ types = ms[0].return_type_detail
212
+ end
213
+ generate_method(method, '_setproperty', io, types)
214
+ end
215
+ end
216
+
217
+ def generate_propget_methods(klass, io = STDOUT)
218
+ klass.ole_methods.select { |method|
219
+ method.invoke_kind == 'PROPERTYGET' && method.visible? &&
220
+ method.size_params == 0
221
+ }.each do |method|
222
+ generate_method(method, '_getproperty', io)
223
+ end
224
+ end
225
+
226
+ def generate_func_methods(klass, io = STDOUT)
227
+ klass.ole_methods.select { |method|
228
+ method.invoke_kind == "FUNC" && method.visible?
229
+ }.each do |method|
230
+ generate_method(method, '_invoke', io)
231
+ end
232
+ end
233
+
234
+ def generate_methods(klass, io = STDOUT)
235
+ generate_propget_methods(klass, io)
236
+ generate_propput_methods(klass, io)
237
+ generate_properties_with_args(klass, io)
238
+ generate_func_methods(klass, io)
239
+ # generate_propputref_methods(klass, io)
240
+ end
241
+
242
+ def generate_constants(klass, io = STDOUT)
243
+ klass.variables.select { |v|
244
+ v.visible? && v.variable_kind == 'CONSTANT'
245
+ }.each do |v|
246
+ io.print " "
247
+ io.print v.name.sub(/^./) { $&.upcase }
248
+ io.print " = "
249
+ io.puts v.value
250
+ end
251
+ end
252
+
253
+ def class_name(klass)
254
+ klass_name = klass.name
255
+ if klass.ole_type == "Class" &&
256
+ klass.guid &&
257
+ klass.progid
258
+ klass_name = klass.progid.gsub(/\./, '_')
259
+ end
260
+ if /^[A-Z]/ !~ klass_name || Module.constants.include?(klass_name)
261
+ klass_name = 'OLE' + klass_name
262
+ end
263
+ klass_name
264
+ end
265
+
266
+ def define_initialize(klass)
267
+ <<STR
268
+
269
+ def initialize opts = {}
270
+ super PROGID, opts
271
+ end
272
+ STR
273
+ end
274
+
275
+ def define_include
276
+ " include WIN32OLE::VARIANT"
277
+ end
278
+
279
+ def define_instance_variables
280
+ " attr_reader :lastargs"
281
+ end
282
+
283
+ def define_common_methods
284
+ <<STR
285
+
286
+ def method_missing(cmd, *args)
287
+ @ole.method_missing(cmd, *args)
288
+ end
289
+
290
+ def keep_lastargs(return_value)
291
+ @lastargs = WIN32OLE::ARGV
292
+ return_value
293
+ end
294
+
295
+ def clsid
296
+ CLSID
297
+ end
298
+
299
+ def progid
300
+ PROGID
301
+ end
302
+ STR
303
+ end
304
+
305
+ def define_class(klass, io = STDOUT)
306
+ io.puts "class #{klass.name} < Base # #{class_name(klass)}"
307
+ io.puts " CLSID = '#{klass.guid}'"
308
+ io.puts " PROGID = '#{klass.progid}'"
309
+ io.puts define_include
310
+ io.puts define_instance_variables
311
+ io.puts " attr_reader :ole"
312
+ io.puts define_initialize(klass)
313
+ io.puts define_common_methods
314
+ end
315
+
316
+ def define_module(klass, io = STDOUT)
317
+ io.puts "module #{class_name(klass)}"
318
+ io.puts define_include
319
+ io.puts define_instance_variables
320
+ end
321
+
322
+ def generate_class(klass, io = STDOUT)
323
+ io.puts "\n# #{klass.helpstring}"
324
+ if klass.ole_type == "Class" &&
325
+ klass.guid &&
326
+ klass.progid
327
+ @reciever = "@ole."
328
+ define_class(klass, io)
329
+ else
330
+ @reciever = ""
331
+ define_module(klass, io)
332
+ end
333
+ generate_constants(klass, io)
334
+ generate_methods(klass, io)
335
+ io.puts "end"
336
+ end
337
+
338
+ def generate(io = STDOUT)
339
+ io.puts "require 'win32ole'"
340
+ io.puts "require 'win32ole/property'"
341
+
342
+ ole_classes(typelib).select { |klass|
343
+ klass.visible? &&
344
+ (klass.ole_type == "Class" ||
345
+ klass.ole_type == "Interface" ||
346
+ klass.ole_type == "Dispatch" ||
347
+ klass.ole_type == "Enum")
348
+ }.each do |klass|
349
+ generate_class(klass, io)
350
+ end
351
+ begin
352
+ @ole.quit if @ole
353
+ rescue
354
+ end
355
+ end
356
+ end
357
+
358
+ if __FILE__ == $0
359
+ # if ARGV.size == 0
360
+ # $stderr.puts "usage: #{$0} Type Library [...]"
361
+ # exit 1
362
+ # end
363
+ # ARGV.each do |typelib|
364
+ typelib = WIN32OLE_TYPELIB.typelibs.find { |t| t.name =~ /P2ClientGate / }
365
+ comgen = WIN32COMGen.new(typelib.guid)
366
+ comgen.generate
367
+ # end
368
+ end
@@ -0,0 +1,9 @@
1
+ Feature: something something
2
+ In order to something something
3
+ A user something something
4
+ something something something
5
+
6
+ Scenario: something something
7
+ Given inspiration
8
+ When I create a sweet new gem
9
+ Then everyone should see how awesome I am
File without changes
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+
3
+ require 'pathname'
4
+ require 'bundler'
5
+ Bundler.setup
6
+ Bundler.require :cucumber
7
+
8
+ require 'p2ruby'
9
+
10
+ BASE_PATH = Pathname.new(__FILE__).dirname + '../..'
@@ -0,0 +1,12 @@
1
+ module SystemHelper
2
+
3
+ def windows?
4
+ RUBY_PLATFORM =~ /mswin|windows|mingw/ || cygwin?
5
+ end
6
+
7
+ def cygwin?
8
+ RUBY_PLATFORM =~ /cygwin/
9
+ end
10
+ end
11
+
12
+ World(WinGui, SystemHelper)
data/lib/extension.rb ADDED
@@ -0,0 +1,19 @@
1
+ class String
2
+ # returns snake_case representation of string
3
+ def snake_case
4
+ gsub(/([a-z])([A-Z0-9])/, '\1_\2' ).downcase
5
+ end
6
+
7
+ # returns camel_case representation of string
8
+ def camel_case
9
+ if self.include? '_'
10
+ self.split('_').map{|e| e.capitalize}.join
11
+ else
12
+ unless self =~ (/^[A-Z]/)
13
+ self.capitalize
14
+ else
15
+ self
16
+ end
17
+ end
18
+ end
19
+ end