p2ruby 0.1.0

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 (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