DeepConnect 0.4.06

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.
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # deep-connect.rb -
4
+ # Copyright (C) 1996-2010 Keiju ISHITSUKA
5
+ # (Penta Advanced Labrabries, Co.,Ltd)
6
+ #
7
+
8
+ require "forwardable"
9
+
10
+ require "deep-connect/conf"
11
+
12
+ module DeepConnect
13
+ @RCS_ID='-$Id: $-'
14
+
15
+ # DC is a internal using short cut of DeepConnect .
16
+ DC = DeepConnect
17
+ Conf = Config.new
18
+ end
19
+
20
+ require "deep-connect/organizer"
21
+
22
+ module DeepConnect
23
+ class DeepConnect
24
+ extend Forwardable
25
+
26
+ def self.start(service=0)
27
+ dc = new
28
+ dc.start(service)
29
+ dc
30
+ end
31
+
32
+ def initialize
33
+ @organizer = Organizer.new
34
+ end
35
+
36
+ def_delegator :@organizer, :start
37
+ def_delegator :@organizer, :stop
38
+
39
+ def_delegator :@organizer, :open_deep_space
40
+ def_delegator :@organizer, :open_deepspace
41
+ def_delegator :@organizer, :close_deep_space
42
+ def_delegator :@organizer, :close_deepspace
43
+ def_delegator :@organizer, :when_connected
44
+ def_delegator :@organizer, :when_disconnected
45
+
46
+ def_delegator :@organizer, :export
47
+ def_delegator :@organizer, :register_service
48
+
49
+ def_delegator :@organizer, :export_mq
50
+
51
+ def_delegator :@organizer, :release_object
52
+
53
+ def_delegator :@organizer, :local_id
54
+
55
+ end
56
+
57
+ def DC.start(service = nil)
58
+ DeepConnect.start(service)
59
+ end
60
+
61
+ def DC.def_method_spec(*opts)
62
+ Organizer.def_method_spec(*opts)
63
+ end
64
+
65
+ def DC.def_single_method_spec(*opts)
66
+ Organizer.def_single_method_spec(*opts)
67
+ end
68
+
69
+ def DC.def_interface(*opts)
70
+ Organizer.def_interface(*opts)
71
+ end
72
+
73
+ def DC.def_single_interface(*opts)
74
+ Organizer.def_single_interface(*opts)
75
+ end
76
+ end
77
+
78
+ require "deep-connect/serialize"
79
+
80
+
81
+
82
+
83
+
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # accepter.rb -
4
+ # Copyright (C) 1996-2010 Keiju ISHITSUKA
5
+ # (Penta Advanced Labrabries, Co.,Ltd)
6
+ #
7
+
8
+
9
+ require "socket"
10
+ require "ipaddr"
11
+
12
+ require "deep-connect/event"
13
+
14
+ module DeepConnect
15
+ class Accepter
16
+ def initialize(org)
17
+ @organizer = org
18
+ @probe = nil
19
+ end
20
+
21
+ def port_number
22
+ @probe.addr[1]
23
+ end
24
+
25
+ def open(service = 0)
26
+ @probe = TCPServer.open("", service)
27
+ end
28
+
29
+ def start
30
+ @probe_thread = Thread.start {
31
+ loop do
32
+ sock = @probe.accept
33
+ Thread.start do
34
+ port = Port.new(sock)
35
+ begin
36
+ unless (ev = port.import).kind_of?(Event::InitSessionEvent)
37
+ puts "WARN: 接続初期化エラー: [#{port.peeraddr}]"
38
+ end
39
+ begin
40
+ @organizer.connect_deep_space_with_port port, ev.local_id
41
+ rescue ConnectCancel
42
+ puts "INFO: クライアント(#{ev.local_id}からの接続を拒否しました."
43
+ rescue ConnectionRefused
44
+ puts "WARN: クライアント(#{ev.local_id}への接続が拒否されました"
45
+ rescue ProtocolError, IOError
46
+ puts "WARN: 接続初期化エラー: [#{port.peeraddr}]"
47
+
48
+ end
49
+ rescue EOFError
50
+ puts "WARN: 接続初期化中に[#{port.peeraddr}]との接続が切れました"
51
+ end
52
+ end
53
+ end
54
+ }
55
+ end
56
+
57
+ def stop
58
+ @probe_thread.exit
59
+ @probe.close
60
+ end
61
+ end
62
+ end
63
+
64
+
@@ -0,0 +1,652 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # class-spec-space.rb -
4
+ # Copyright (C) 1996-2010 Keiju ISHITSUKA
5
+ # (Penta Advanced Labrabries, Co.,Ltd)
6
+ #
7
+
8
+ require "thread"
9
+ require "e2mmap"
10
+
11
+ module DeepConnect
12
+
13
+ class ClassSpecSpace
14
+ NULL = :NULL
15
+
16
+ def initialize(remote = :remote)
17
+ case remote
18
+ when :remote
19
+ @class_specs = nil
20
+ when :local
21
+ @class_specs = {}
22
+ end
23
+
24
+ @class_specs_mutex = Mutex.new
25
+ @class_specs_cv = ConditionVariable.new
26
+
27
+ @method_spec_cache = {}
28
+ end
29
+
30
+ def class_spec_id_of(obj)
31
+ ancestors = obj.class.ancestors
32
+ begin
33
+ single = (class<<obj;self;end)
34
+ ancestors.unshift single
35
+ rescue
36
+ end
37
+ #p ancestors
38
+ # p ancestors.collect{|e| e.object_id}
39
+ klass = ancestors.find{|kls|
40
+ @class_specs[kls.object_id]
41
+ }
42
+ if klass
43
+ klass.object_id
44
+ else
45
+ nil
46
+ end
47
+ end
48
+
49
+ def method_spec(ref_or_obj, method)
50
+ puts "method_spec(#{ref_or_obj}, #{method})" if Conf.DISPLAY_METHOD_SPEC
51
+ if ref_or_obj.__deep_connect_reference?
52
+ csid = ref_or_obj.csid
53
+ else
54
+ csid = class_spec_id_of(ref_or_obj)
55
+ end
56
+ return nil unless csid
57
+
58
+ # mid = [csid, method]
59
+ # mid = sprintf("%X-%s", csid, method)
60
+ mid = "#{csid}-#{method}"
61
+ case mspec = @method_spec_cache[mid]
62
+ when nil
63
+ # pass
64
+ when NULL
65
+ return nil
66
+ else
67
+ return mspec
68
+ end
69
+
70
+ class_spec_ancestors(csid) do |cspec|
71
+ if mspec = cspec.method_spec(method)
72
+ return mspec
73
+ end
74
+ end
75
+ @method_spec_cache[mid] = NULL
76
+ return nil
77
+ end
78
+
79
+ def def_method_spec(klass, *method_spec)
80
+ csid = klass.object_id
81
+ unless cspec = @class_specs[csid]
82
+ cspec = ClassSpec.new(klass)
83
+ @class_specs[csid] = cspec
84
+ end
85
+
86
+ if method_spec.size == 1 and method_spec.first.kind_of?(MethodSpec)
87
+ mspec = method_spec.first
88
+ else
89
+ mspec = MethodSpec.spec(*method_spec)
90
+ end
91
+ cspec.add_method_spec(mspec)
92
+ end
93
+
94
+ def def_single_method_spec(obj, method_spec)
95
+ klass = class<<obj;self;end
96
+ def_method_spec(klass, method_spec)
97
+ end
98
+
99
+ def def_interface(klass, method)
100
+ mspec = MethodSpec.new
101
+ mspec.method = method
102
+ mspec.interface = true
103
+ def_method_spec(klass, mspec)
104
+ end
105
+
106
+ def def_single_interface(obj, method)
107
+ klass = class<<obj;self;end
108
+ def_interface(klass, method)
109
+ end
110
+
111
+ def class_specs=(cspecs)
112
+ @class_specs_mutex.synchronize do
113
+ @class_specs = cspecs
114
+ @class_specs_cv.broadcast
115
+ end
116
+ end
117
+
118
+ def class_specs
119
+ @class_specs_mutex.synchronize do
120
+ while !@class_specs
121
+ @class_specs_cv.wait(@class_specs_mutex)
122
+ end
123
+ @class_specs
124
+ end
125
+ end
126
+
127
+ def class_spec_ancestors(csid, &block)
128
+ @class_specs_mutex.synchronize do
129
+ while !@class_specs
130
+ @class_specs_cv.wait(@class_specs_mutex)
131
+ end
132
+ end
133
+
134
+ class_spec = @class_specs[csid]
135
+
136
+ class_spec.ancestors.select{|anc| @class_specs[anc]}.each{|anc|
137
+ yield @class_specs[anc]
138
+ }
139
+ end
140
+
141
+ end
142
+
143
+ class ClassSpec
144
+ def initialize(klass)
145
+ @name = klass.name
146
+ @csid = klass.object_id
147
+ ancestors = klass.ancestors
148
+ ancestors.unshift klass
149
+ @ancestors = ancestors.collect{|k| k.object_id}
150
+ @method_specs = {}
151
+ end
152
+
153
+ attr_reader :name
154
+ attr_reader :csid
155
+ attr_reader :ancestors
156
+
157
+ def add_method_spec(mspec)
158
+ if sp = @method_specs[mspec.method]
159
+ @method_specs[mspec.method].override(mspec)
160
+ else
161
+ @method_specs[mspec.method] = mspec
162
+ end
163
+ end
164
+
165
+ def method_spec(method)
166
+ @method_specs[method]
167
+ end
168
+
169
+ end
170
+
171
+ class MethodSpec
172
+ extend Exception2MessageMapper
173
+
174
+ def_exception :UnrecognizedError, "パーズできません(%s)"
175
+
176
+ # method(arg_spec, ..., *arg_spec)
177
+ # ret_spec, ... method()
178
+ # ret_spec, ... method(arg_spec, ..., *arg_spec)
179
+ # ret_spec, ... method() block_ret, ... {}
180
+ # ret_spec, ... method() {arg_spec, ...}
181
+ # ret_spec, ... method() block_ret, ... {arg_spec, ...}
182
+ # ret_spec, ... method(arg_spec, ..., *arg_spec) block_ret, ... {arg_spec, ...}
183
+
184
+ # *****method が記号の時できてない
185
+
186
+ ARG_SPEC = ["DEFAULT", "REF", "VAL", "DVAL"]
187
+ # VALができるのは, Array, Hash のみ, Structは相手にも同一クラスがあれば可能
188
+
189
+ def self.spec(spec)
190
+ mspec = MethodSpec.new
191
+ case spec
192
+ when String
193
+ mspec.parse(spec)
194
+ when Hash
195
+ mspec.direct_setting(spec)
196
+ else
197
+ raise "スペック指定は文字列もしくはキーワード指定です"
198
+ end
199
+ mspec
200
+ end
201
+
202
+ def initialize
203
+ @rets = nil
204
+ @method = nil
205
+ @args = nil
206
+ @block_rets = nil
207
+ @block_args = nil
208
+
209
+ @interface = nil
210
+ end
211
+
212
+ attr_accessor :rets
213
+ attr_accessor :method
214
+ attr_accessor :args
215
+ attr_accessor :block_rets
216
+ attr_accessor :block_args
217
+ attr_accessor :interface
218
+ alias interface? interface
219
+
220
+ def has_block?
221
+ @block_rets || @block_args
222
+ end
223
+
224
+ def override(mspec)
225
+ if mspec.rets
226
+ @rets = mspec.rets
227
+ end
228
+ if mspec.args
229
+ @args = mspec.args
230
+ end
231
+ if mspec.block_rets
232
+ @block_rets = mspec.block.rets
233
+ end
234
+ if mspec.block_args
235
+ @block_args = mspec.block_args
236
+ end
237
+ if mspec.interface
238
+ @interface = mspec.interface
239
+ end
240
+ end
241
+
242
+ class ArgSpecs
243
+ include Enumerable
244
+ def initialize(arg_specs)
245
+ @arg_specs = arg_specs.dup
246
+ end
247
+
248
+ def each
249
+ while arg_spec = @arg_specs.shift
250
+ if arg_spec.mult?
251
+ @arg_specs.unshift arg_spec
252
+ end
253
+ yield arg_spec
254
+ end
255
+ end
256
+
257
+ def succ
258
+ if (ret = @arg_specs.shift) && ret.mult?
259
+ @arg_specs.unshift ret
260
+ end
261
+ ret
262
+ end
263
+
264
+ end
265
+
266
+ def rets_zip(rets, &block)
267
+ retspecs = ArgSpecs.new(@rets)
268
+ begin
269
+ param_zip(retspecs, rets, &block)
270
+ rescue ArgumentError
271
+ raise ArgumentError,
272
+ "argument spec mismatch rets: #{@rets}"
273
+ end
274
+ end
275
+
276
+ def arg_zip(args, &block)
277
+ argspecs = ArgSpecs.new(@args)
278
+ begin
279
+ param_zip(argspecs, args, &block)
280
+ rescue ArgumentError
281
+ raise ArgumentError,
282
+ "argument spec mismatch args: #{@args}"
283
+ end
284
+ end
285
+
286
+ def block_arg_zip(args, &block)
287
+ argspecs = ArgSpecs.new(@block_args)
288
+ begin
289
+ param_zip(argspecs, args, &block)
290
+ rescue ArgumentError
291
+ raise ArgumentError,
292
+ "argument spec mismatch block args: #{@block_args}"
293
+ end
294
+ end
295
+
296
+ def param_zip(arg_specs, args, &block)
297
+ ary = []
298
+ args.each do |arg|
299
+ spec = arg_specs.succ
300
+ unless spec
301
+ raise ArgumentError
302
+ end
303
+ ary.push yield(spec, arg)
304
+ end
305
+ ary
306
+ end
307
+
308
+ def to_s
309
+ spec = ""
310
+ case @rets
311
+ when nil
312
+ when Array
313
+ spec.concat(@rets.join(", "))
314
+ spec.concat(" ")
315
+ when
316
+ spec.concat(@rets.to_s)
317
+ spec.concat(" ")
318
+ end
319
+
320
+ if @method
321
+ spec.concat(@method.to_s)
322
+ else
323
+ spec.concat("(missing)")
324
+ end
325
+ if @args
326
+ spec.concat("("+@args.join(", ")+")")
327
+ end
328
+ if has_block?
329
+ if @block_rets
330
+ spec.concat(@block_rets.join(", "))
331
+ end
332
+ if @block_args
333
+ spec.concat("{"+@block_args.join(", ")+"}")
334
+ else
335
+ spec.concat("{}")
336
+ end
337
+ end
338
+ "#<#{self.class} #{spec} >"
339
+ end
340
+
341
+ class ParamSpec
342
+ def self.identifier(token, *opts)
343
+ case token
344
+ when String
345
+ name = token
346
+ if /^\*(.*)/ =~ token
347
+ name = $1
348
+ opts.push :mult
349
+ end
350
+ when Token
351
+ name = token.name
352
+ end
353
+
354
+ klass = Name2ParamSpec[name]
355
+ unless klass
356
+ MethodSpec.Raise UnrecognizedError, name
357
+ end
358
+ pspec = klass.new(name)
359
+ if opts.include?(:mult)
360
+ pspec.mult = true
361
+ end
362
+ pspec
363
+ end
364
+
365
+ def self.param_specs(string_ary)
366
+ case string_ary
367
+ when nil
368
+ nil
369
+ when Array
370
+ string_ary.collect{|e| ParamSpec.identifier(e)}
371
+ else
372
+ [ParamSpec.identifier(string_ary)]
373
+ end
374
+ end
375
+
376
+ def initialize(name)
377
+ @type = name
378
+
379
+ @mult = nil
380
+ end
381
+
382
+ attr_reader :type
383
+ attr_accessor :mult
384
+ alias mult? mult
385
+
386
+ def to_s
387
+ if mult
388
+ "*"+@type
389
+ else
390
+ @type
391
+ end
392
+ end
393
+ end
394
+
395
+ class DefaultParamSpec<ParamSpec;end
396
+ class RefParamSpec<ParamSpec;end
397
+ class ValParamSpec<ParamSpec;end
398
+ class DValParamSpec<ParamSpec;end
399
+
400
+ Name2ParamSpec = {
401
+ "DEFAULT"=>DefaultParamSpec,
402
+ "REF" => RefParamSpec,
403
+ "VAL" => ValParamSpec,
404
+ "DVAL" => DValParamSpec
405
+ }
406
+
407
+ def direct_setting(opts)
408
+ if opts[:rets]
409
+ @rets = ParamSpec.param_specs(opts[:rets])
410
+ if @rets.size == 1
411
+ @rets = @rets.first
412
+ end
413
+ end
414
+
415
+ @method = opts[:method]
416
+ @method = @method.intern unless @method.kind_of?(Symbol)
417
+
418
+ if opts[:args]
419
+ @args = ParamSpec.param_specs(opts[:args])
420
+ end
421
+
422
+ if opts[:block_rets]
423
+ @block_rets = ParamSpec.param_specs(opts[:block_rets])
424
+ if @block_rets.size == 1
425
+ @block_rets = @block_rets.first
426
+ end
427
+ end
428
+ if opts[:block_args]
429
+ @block_args = ParamSpec.param_specs(opts[:block_args])
430
+ end
431
+ end
432
+
433
+ # private method
434
+ def parse(spec)
435
+ tokener = Tokener.new(spec)
436
+
437
+ tk1, tk2 = tokener.next, tokener.peek
438
+ tokener.unget tk1
439
+ case tk1
440
+ when TkIdentifier
441
+ case tk2
442
+ when nil
443
+ when TkIdentifier, TkCOMMA, TkMULT
444
+ parse_rets(tokener, spec)
445
+ when TkLPAREN, TkLBRACE
446
+ else
447
+ MethodSpec.Raise UnrecognizedError, spec
448
+ end
449
+ when TkMULTI
450
+ parse_rets(tokener, spec)
451
+ else
452
+ MethodSpec.Raise UnrecognizedError, spec
453
+ end
454
+
455
+ parse_method(tokener, spec)
456
+ parse_args(tokener, spec)
457
+ parse_block(tokener, spec)
458
+ end
459
+
460
+ def parse_rets(tokener, spec)
461
+ @rets = parse_params(tokener, spec)
462
+ if @rets && @rets.size == 1
463
+ @rets = @rets.first
464
+ end
465
+ end
466
+
467
+ def parse_method(tokener, spec)
468
+ tk = tokener.next
469
+ case tk
470
+ when TkIdentifier
471
+ @method = tk.name.intern
472
+ else
473
+ MethodSpec.Raise UnrecognizedError, tk.to_s+ " in " +spec
474
+ end
475
+ end
476
+
477
+ def parse_args(tokener, spec)
478
+ tk = tokener.next
479
+ case tk
480
+ when TkLPAREN
481
+ @args = parse_params(tokener, spec)
482
+ tk2 = tokener.next
483
+ unless tk2 == TkRPAREN
484
+ MethodSpec.Raise UnrecognizedError, tk2 + " in " +spec
485
+ end
486
+ else
487
+ # パラメータなし
488
+ end
489
+ end
490
+
491
+ def parse_block(tokener, spec)
492
+ parse_block_rets(tokener, spec)
493
+ tk = tokener.peek
494
+ unless tk == TkLBRACE
495
+ if @block_rets
496
+ MethodSpec.Raise UnrecognizedError, "ブロック定義では`{'が必要です(#{tk.to_s}, #{spec})"
497
+ else
498
+ return
499
+ end
500
+ end
501
+ parse_block_args(tokener, spec)
502
+ end
503
+
504
+ def parse_block_rets(tokner, spec)
505
+ @block_rets = parse_params(tokner, spec)
506
+ if @block_rets
507
+ if @block_rets && @block_rets.size == 1
508
+ @block_rets = @block_rets.first
509
+ end
510
+ end
511
+ end
512
+
513
+ def parse_block_args(tokener, spec)
514
+ tk = tokener.next
515
+ case tk
516
+ when TkLBRACE
517
+ @block_args = parse_params(tokener, spec)
518
+ @args = parse_params(tokener, spec)
519
+ tk2 = tokener.next
520
+ unless tk2 == TkRBRACE
521
+ MethodSpec.Raise UnrecognizedError, tk2 +" in " +spec
522
+ end
523
+ else
524
+ # パラメータなし
525
+ end
526
+ end
527
+
528
+ def parse_params(tokener, spec)
529
+ args = []
530
+ while token = tokener.next
531
+ case token
532
+ when TkIdentifier
533
+ case tk2 = tokener.peek
534
+ when nil
535
+ args.push ArgSpec.identifier(token)
536
+ break
537
+ when TkMULT
538
+ MethodSpec.Raise UnrecognizedError, token
539
+ when TkCOMMA
540
+ tokener.next
541
+ args.push ParamSpec.identifier(token)
542
+ when TkIdentifier, TkRPAREN, TkRBRACE
543
+ args.push ParamSpec.identifier(token)
544
+ break
545
+ when TkLPAREN, TkLBRACE
546
+ args.push ParamSpec.identifier(token)
547
+ break
548
+ else
549
+ MethodSpec.Raise UnrecognizedError, "不正な文字#{tk2}が入っています"
550
+ end
551
+ when TkMULT
552
+ case token2 = tokener.next
553
+ when nil
554
+ MethodSpec.Raise UnrecognizedError, "*で終わっています"
555
+ when TkIdentifier
556
+ args.push ParamSpec.identifier(token2, :mult)
557
+ break
558
+ else
559
+ MethodSpec.Raise UnrecognizedError, "*の後に#{token2}が入っています"
560
+ end
561
+ else # TkRPAREN, TkRBRACE
562
+ tokener.unget token
563
+ break
564
+ end
565
+ end
566
+ if args.empty?
567
+ nil
568
+ else
569
+ args
570
+ end
571
+ end
572
+
573
+ class Token; end
574
+ class TkIdentifier<Token
575
+ def initialize(name)
576
+ @name = name
577
+ end
578
+ attr_reader :name
579
+
580
+ def to_s
581
+ "#<#{self.class} #{@name}>"
582
+ end
583
+ end
584
+
585
+ TkMULT = "*"
586
+ TkLPAREN = "("
587
+ TkLBRACE = "{"
588
+ TkRPAREN = ")"
589
+ TkRBRACE = "}"
590
+ TkCOMMA = ","
591
+
592
+ class Tokener
593
+ def initialize(src)
594
+ @src = src.split(//)
595
+ @tokens = []
596
+ end
597
+
598
+ def next
599
+ return @tokens.shift unless @tokens.empty?
600
+
601
+ while /\s/ =~ @src[0]; @src.shift; end
602
+
603
+ case @src[0]
604
+ when nil
605
+ nil
606
+ when ",", "(", ")", "{", "}", "*"
607
+ reading = @src.shift
608
+ when /\w/
609
+ identify_identifier
610
+ else
611
+ MethodSpec.Raise UnrecognizedError, @src.join("")
612
+ end
613
+ end
614
+
615
+ def peek
616
+ @tokens.first unless @tokens.empty?
617
+
618
+ token = self.next
619
+ @tokens.push(token) if token
620
+ token
621
+ end
622
+
623
+ def unget(token)
624
+ @tokens.unshift token
625
+ end
626
+
627
+ def identify_identifier
628
+ toks = []
629
+ while s = @src.shift
630
+ if /[\w]/ =~ s
631
+ toks.push s
632
+ else
633
+ @src.unshift s
634
+ break
635
+ end
636
+ end
637
+ reading = toks.join("")
638
+ TkIdentifier.new(reading)
639
+ end
640
+ end
641
+
642
+ def self.mkkey(receiver, method_name)
643
+ if receiver.__deep_connect_reference?
644
+ receiver.class.name+"#"+method_name.to_s
645
+ elsif receiver.kind_of?(Class)
646
+ receiver.name+"."+method_name.to_s
647
+ else
648
+ receiver.class.name+"#"+method_name.to_s
649
+ end
650
+ end
651
+ end
652
+ end