DeepConnect 0.4.06

Sign up to get free protection for your applications and to get access to all the features.
@@ -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