dde 0.2.9 → 0.2.11

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.
@@ -1,38 +1,38 @@
1
- # Quick and dirty DDE Library
2
-
3
- require 'ffi'
4
- require 'win/dde'
5
- require 'win/gui/message'
6
- require_relative 'exp_lib'
7
-
8
- module DDELib
9
- extend FFI::Library
10
- CP_WINANSI = 1004
11
- DNS_REGISTER = 1
12
- APPCLASS_STANDARD = 0
13
- CF_TEXT = 1
14
-
15
- XTYPF_NOBLOCK = 0x0002
16
- XCLASS_BOOL = 0x1000
17
- XCLASS_FLAGS = 0x4000
18
- XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK
19
- XTYP_POKE = 0x0090 | XCLASS_FLAGS
20
- XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS
21
- TIMEOUT_ASYNC = 0xFFFFFFFF
22
-
23
- DDE_FACK = 0x8000
24
-
25
- ffi_lib 'user32', 'kernel32' # Default library
26
- ffi_convention :stdcall
27
-
28
- callback :DdeCallback, [:uint, :uint, :ulong, :pointer, :pointer, :pointer, :pointer], :ulong
29
-
30
- attach_function(:DdeInitializeA, [:pointer, :DdeCallback, :uint32, :uint32], :uint)
31
- attach_function(:DdeCreateStringHandleA, [:uint32, :pointer, :int], :ulong)
32
- attach_function :DdeNameService, [:uint32, :ulong, :ulong, :uint], :ulong
33
- attach_function(:DdeConnect, [:uint32, :ulong, :ulong, :pointer], :ulong)
34
- attach_function :DdeDisconnect, [:ulong], :int
35
- attach_function(:DdeClientTransaction, [:pointer, :uint32, :ulong, :ulong, :uint, :uint, :uint32, :pointer], :pointer)
36
- attach_function :DdeGetLastError, [:uint32], :int
37
- end
38
-
1
+ # Quick and dirty DDE Library
2
+
3
+ require 'ffi'
4
+ require 'win/dde'
5
+ require 'win/gui/message'
6
+ require_relative 'exp_lib'
7
+
8
+ module DdeLib
9
+ extend FFI::Library
10
+ CP_WINANSI = 1004
11
+ DNS_REGISTER = 1
12
+ APPCLASS_STANDARD = 0
13
+ CF_TEXT = 1
14
+
15
+ XTYPF_NOBLOCK = 0x0002
16
+ XCLASS_BOOL = 0x1000
17
+ XCLASS_FLAGS = 0x4000
18
+ XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK
19
+ XTYP_POKE = 0x0090 | XCLASS_FLAGS
20
+ XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS
21
+ TIMEOUT_ASYNC = 0xFFFFFFFF
22
+
23
+ DDE_FACK = 0x8000
24
+
25
+ ffi_lib 'user32', 'kernel32' # Default library
26
+ ffi_convention :stdcall
27
+
28
+ callback :DdeCallback, [:uint, :uint, :ulong, :pointer, :pointer, :pointer, :pointer], :ulong
29
+
30
+ attach_function(:DdeInitializeA, [:pointer, :DdeCallback, :uint32, :uint32], :uint)
31
+ attach_function(:DdeCreateStringHandleA, [:uint32, :pointer, :int], :ulong)
32
+ attach_function :DdeNameService, [:uint32, :ulong, :ulong, :uint], :ulong
33
+ attach_function(:DdeConnect, [:uint32, :ulong, :ulong, :pointer], :ulong)
34
+ attach_function :DdeDisconnect, [:ulong], :int
35
+ attach_function(:DdeClientTransaction, [:pointer, :uint32, :ulong, :ulong, :uint, :uint, :uint32, :pointer], :pointer)
36
+ attach_function :DdeGetLastError, [:uint32], :int
37
+ end
38
+
@@ -1,44 +1,44 @@
1
- # Quick and dirty DDE Server (for experimentation)
2
-
3
- require 'win/gui/message'
4
- include Win::GUI::Message
5
-
6
- #require_relative 'exp_lib'
7
- #include DDELib
8
-
9
- require 'win/dde'
10
- include Win::DDE
11
-
12
- calls = []
13
- buffer = FFI::MemoryPointer.new(:long).write_long(0)
14
- buffer.address
15
-
16
- callback = lambda do |*args|
17
- calls << [*args]
18
- puts "#{Time.now.strftime('%T.%6N')} #{args.map{|e|e.respond_to?(:address) ? e.address : (Win::DDE::TYPES[e] || e)}}"
19
- args.first == XTYP_CONNECT ? 1 : DDE_FACK
20
- end
21
-
22
- status = DdeInitialize(buffer, callback, APPCLASS_STANDARD, 0)
23
- id = buffer.read_long
24
-
25
- service = FFI::MemoryPointer.from_string('test_service')
26
-
27
- p handle = DdeCreateStringHandle(id, service, CP_WINANSI)
28
-
29
- p DdeNameService(id, handle, 0, DNS_REGISTER)
30
-
31
- #p DdeDisconnect(conv_handle)
32
-
33
- msg = Msg.new # pointer to Msg FFI struct
34
-
35
- # Starting message loop (necessary for DDE processing)
36
- puts "Starting message loop\n"
37
- while msg = get_message()
38
- translate_message(msg)
39
- dispatch_message(msg)
40
- end
41
-
42
- p calls.map{|c| c.map{|e|e.respond_to?(:address) ? e.address : (Win::DDE::TYPES[e] || e)}}
43
-
44
- p Win::DDE::ERRORS[DdeGetLastError(id)]
1
+ # Quick and dirty DDE Server (for experimentation)
2
+
3
+ require 'win/gui/message'
4
+ include Win::GUI::Message
5
+
6
+ #require_relative 'exp_lib'
7
+ #include DdeLib
8
+
9
+ require 'win/dde'
10
+ include Win::Dde
11
+
12
+ calls = []
13
+ buffer = FFI::MemoryPointer.new(:long).write_long(0)
14
+ buffer.address
15
+
16
+ callback = lambda do |*args|
17
+ calls << [*args]
18
+ puts "#{Time.now.strftime('%T.%6N')} #{args.map{|e|e.respond_to?(:address) ? e.address : (Win::Dde::TYPES[e] || e)}}"
19
+ args.first == XTYP_CONNECT ? 1 : DDE_FACK
20
+ end
21
+
22
+ status = DdeInitialize(buffer, callback, APPCLASS_STANDARD, 0)
23
+ id = buffer.read_long
24
+
25
+ service = FFI::MemoryPointer.from_string('test_service')
26
+
27
+ p handle = DdeCreateStringHandle(id, service, CP_WINANSI)
28
+
29
+ p DdeNameService(id, handle, 0, DNS_REGISTER)
30
+
31
+ #p DdeDisconnect(conv_handle)
32
+
33
+ msg = Msg.new # pointer to Msg FFI struct
34
+
35
+ # Starting message loop (necessary for DDE processing)
36
+ puts "Starting message loop\n"
37
+ while msg = get_message()
38
+ translate_message(msg)
39
+ dispatch_message(msg)
40
+ end
41
+
42
+ p calls.map{|c| c.map{|e|e.respond_to?(:address) ? e.address : (Win::Dde::TYPES[e] || e)}}
43
+
44
+ p Win::Dde::ERRORS[DdeGetLastError(id)]
@@ -1,9 +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
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
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
- require 'dde'
3
-
4
- require 'spec/expectations'
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'dde'
3
+
4
+ require 'spec/expectations'
data/lib/dde.rb CHANGED
@@ -1,9 +1,9 @@
1
- # console output redirection (may need to wrap it in synchronization code, etc)
2
- require 'rubygems'
3
- require 'win/dde'
4
- require 'dde/dde_string'
5
- require 'dde/app'
6
- require 'dde/server'
7
- require 'dde/client'
8
- require 'dde/monitor'
9
- require 'dde/xl_server'
1
+ # console output redirection (may need to wrap it in synchronization code, etc)
2
+ require 'rubygems'
3
+ require 'win/dde'
4
+ require 'dde/dde_string'
5
+ require 'dde/app'
6
+ require 'dde/server'
7
+ require 'dde/client'
8
+ require 'dde/monitor'
9
+ require 'dde/xl_server'
@@ -1,92 +1,92 @@
1
- module DDE
2
-
3
- module Errors # :nodoc:
4
- def self.[](error_code)
5
- Win::DDE::ERRORS[error_code]
6
- end
7
-
8
- class InitError < RuntimeError # :nodoc:
9
- end
10
- class FormatError < RuntimeError # :nodoc:
11
- end
12
- class StringError < RuntimeError # :nodoc:
13
- end
14
- class ServiceError < RuntimeError # :nodoc:
15
- end
16
- class ClientError < RuntimeError # :nodoc:
17
- end
18
- end
19
-
20
- # Class encapsulates DDE application. DDE::App serves as a base for more specific types,
21
- # such as DDE::Server or DDE:: Client.
22
- class App
23
- include Win::DDE
24
-
25
- attr_reader :id, :init_flags
26
-
27
- # Creates new DDE application (and starts DDE instance if dde_callback block is attached)
28
- def initialize( init_flags=nil, &dde_callback )
29
- @init_flags = init_flags
30
-
31
- start_dde init_flags, &dde_callback if dde_callback
32
-
33
- end
34
- # # todo: Destructor to ensure Dde instance is uninitialized and string handles freed...
35
- # ObjectSpace.define_finalizer( self, self.class.finalize))
36
- # end
37
- #
38
- # # need to have class method, otherwise proc traps reference to instance (self) and the object
39
- # # is never garbage-collected (http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/)
40
- # def self.finalize()
41
- # proc { stop_dde } #does NOT work since stop_dde is instance method (depends on self)
42
- # end
43
-
44
- # (Re)Initialize application with DDEML library, providing attached dde callback
45
- # either preserved @init_flags or init_flags argument are used
46
- def start_dde( init_flags=nil, &dde_callback )
47
- @init_flags = init_flags || @init_flags || APPCLASS_STANDARD
48
-
49
- try "Starting DDE" do
50
- @id, status = dde_initialize @id, @init_flags, &dde_callback
51
- error(status) unless @id && status == DMLERR_NO_ERROR
52
- end
53
- end
54
-
55
- # (Re)Initialize application with DDEML library, providing attached dde callback
56
- def stop_dde
57
- try "Stopping DDE" do
58
- error "DDE not started" unless dde_active?
59
- error unless dde_uninitialize(@id) # Uninitialize app with DDEML library
60
- @id = nil # Clear instance id if uninitialization successful
61
- end
62
- end
63
-
64
- # Expects a block, yields to it inside a rescue block, raises given error_type with extended fail message.
65
- # Returns self in case of success (to enable method chaining).
66
- def try( action, error_type=DDE::Errors::InitError )
67
- begin
68
- yield
69
- rescue => e
70
- raise error_type, action + " failed with: #{e}"
71
- end
72
- self
73
- end
74
-
75
- # Raises Runtime error with message based on given message (DdeGetLastError message if no message given)
76
- def error( message = nil )
77
- raise case message
78
- when Integer
79
- DDE::Errors[message]
80
- when nil
81
- DDE::Errors[dde_get_last_error(@id)]
82
- else
83
- message
84
- end
85
- end
86
-
87
- def dde_active?
88
- !!@id
89
- end
90
-
91
- end
1
+ module Dde
2
+
3
+ module Errors # :nodoc:
4
+ def self.[](error_code)
5
+ Win::Dde::ERRORS[error_code]
6
+ end
7
+
8
+ class InitError < RuntimeError # :nodoc:
9
+ end
10
+ class FormatError < RuntimeError # :nodoc:
11
+ end
12
+ class StringError < RuntimeError # :nodoc:
13
+ end
14
+ class ServiceError < RuntimeError # :nodoc:
15
+ end
16
+ class ClientError < RuntimeError # :nodoc:
17
+ end
18
+ end
19
+
20
+ # Class encapsulates DDE application. Dde::App serves as a base for more specific types,
21
+ # such as Dde::Server or Dde:: Client.
22
+ class App
23
+ include Win::Dde
24
+
25
+ attr_reader :id, :init_flags
26
+
27
+ # Creates new DDE application (and starts DDE instance if dde_callback block is attached)
28
+ def initialize( init_flags=nil, &dde_callback )
29
+ @init_flags = init_flags
30
+
31
+ start_dde init_flags, &dde_callback if dde_callback
32
+
33
+ end
34
+ # # todo: Destructor to ensure Dde instance is uninitialized and string handles freed...
35
+ # ObjectSpace.define_finalizer( self, self.class.finalize))
36
+ # end
37
+ #
38
+ # # need to have class method, otherwise proc traps reference to instance (self) and the object
39
+ # # is never garbage-collected (http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/)
40
+ # def self.finalize()
41
+ # proc { stop_dde } #does NOT work since stop_dde is instance method (depends on self)
42
+ # end
43
+
44
+ # (Re)Initialize application with DDEML library, providing attached dde callback
45
+ # either preserved @init_flags or init_flags argument are used
46
+ def start_dde( init_flags=nil, &dde_callback )
47
+ @init_flags = init_flags || @init_flags || APPCLASS_STANDARD
48
+
49
+ try "Starting DDE" do
50
+ @id, status = dde_initialize @id, @init_flags, &dde_callback
51
+ error(status) unless @id && status == DMLERR_NO_ERROR
52
+ end
53
+ end
54
+
55
+ # (Re)Initialize application with DDEML library, providing attached dde callback
56
+ def stop_dde
57
+ try "Stopping DDE" do
58
+ error "DDE not started" unless dde_active?
59
+ error unless dde_uninitialize(@id) # Uninitialize app with DDEML library
60
+ @id = nil # Clear instance id if uninitialization successful
61
+ end
62
+ end
63
+
64
+ # Expects a block, yields to it inside a rescue block, raises given error_type with extended fail message.
65
+ # Returns self in case of success (to enable method chaining).
66
+ def try( action, error_type=Dde::Errors::InitError )
67
+ begin
68
+ yield
69
+ rescue => e
70
+ raise error_type, action + " failed with: #{e}"
71
+ end
72
+ self
73
+ end
74
+
75
+ # Raises Runtime error with message based on given message (DdeGetLastError message if no message given)
76
+ def error( message = nil )
77
+ raise case message
78
+ when Integer
79
+ Dde::Errors[message]
80
+ when nil
81
+ Dde::Errors[dde_get_last_error(@id)]
82
+ else
83
+ message
84
+ end
85
+ end
86
+
87
+ def dde_active?
88
+ !!@id
89
+ end
90
+
91
+ end
92
92
  end
@@ -1,103 +1,103 @@
1
- module DDE
2
-
3
- # Class encapsulates DDE Client that requests connection with DDE server and exchanges data with it via DDE
4
- class Client < App
5
-
6
- attr_reader :conversation, # active DDE conversation that client is engaged in
7
- :service, #service that the client is connected to
8
- :topic, # active DDE conversation topic
9
- :item # active DDE conversation item
10
-
11
- # # Creates new DDE client instance
12
- # def initialize(init_flags = nil, &dde_callback )
13
- # super init_flags, &dde_callback
14
- # end
15
-
16
- # Establish a conversation with a server application that supports the specified service
17
- # name and topic name pair.
18
- def start_conversation( service=nil, topic=nil )
19
- try "Starting conversation #{service} #{topic}", DDE::Errors::ClientError do
20
- error "DDE is not initialized" unless dde_active?
21
- error "Another conversation already established" if conversation_active?
22
-
23
- # Create DDE strings for service and topic unless they are omitted
24
- @service = DDE::DdeString.new(@id, service) if service
25
- @topic = DDE::DdeString.new(@id, topic) if topic
26
-
27
- # Initiate new DDE conversation, returns conversation handle or nil
28
- error unless @conversation = dde_connect(@id, @service.handle, @topic.handle)
29
- end
30
- end
31
-
32
- # Stops active conversation, raises error if no conversations active
33
- def stop_conversation
34
- try "Stopping conversation", DDE::Errors::ClientError do
35
- error "DDE not started" unless dde_active?
36
- error "Conversation not started" unless conversation_active?
37
-
38
- error unless dde_disconnect(@conversation) && # Stop DDE conversation
39
- dde_free_string_handle(@id, @service.handle) && # Free string handles for service name
40
- dde_free_string_handle(@id, @topic.handle) # Free string handles for topic name
41
-
42
- # Unset attributes for conversation, service and topic
43
- @conversation = nil
44
- @service = nil
45
- @topic = nil
46
- end
47
- end
48
-
49
- # Sends XTYP_POKE transaction to server if conversation was already established.
50
- # data:: data being sent (will be coerced to String unless is already a (packed) String)
51
- # format:: standard clipboard format of submitted data item (default CF_TEXT)
52
- def send_data( data, format = CF_TEXT, item = "" )
53
- data_pointer = FFI::MemoryPointer.from_string(data.to_s)
54
- result, trans_id = start_transaction(XTYP_POKE, data_pointer, data_pointer.size, format, item)
55
- result
56
- end
57
-
58
- # Initiates transaction to server if conversation was already established.
59
- # transaction_type:: XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_EXECUTE, XTYP_POKE, XTYP_REQUEST
60
- # data_pointer:: pointer to data being sent (either FFI::MemoryPointer or DDE data_handle)
61
- # cb:: data set size (or -1 to indicate that data_pointer is in fact DDE data_handle)
62
- # format:: standard clipboard format of submitted data item (default CF_TEXT)
63
- # item:: item to which transaction is related (String, DdeString or DDE string handle)
64
- # timeout:: timeout in milliseconds or TIMEOUT_ASYNC to indicate async transaction
65
- #
66
- # *Returns*:: A pair of [result, trans_id]. Result is nil for failed transactions,
67
- # DDE data handle for synchronous transactions in which the client expects data from the server,
68
- # nonzero for successful transactions where clients does not expect data from server.
69
- # Trans_id: for asynchronous transactions, a unique transaction identifier for use with the
70
- # DdeAbandonTransaction function and the XTYP_XACT_COMPLETE transaction. For synchronous transactions,
71
- # the low-order word of this variable contains any applicable DDE_ flags resulting from the transaction.
72
- #
73
- def start_transaction( transaction_type, data_pointer=nil, cb = data_pointer ? data_pointer.size : 0,
74
- format=CF_TEXT, item=0, timeout=1000)
75
-
76
- result = nil
77
- trans_id = FFI::MemoryPointer.new(:uint32).put_uint32(0,0)
78
-
79
- try "Sending data to server", DDE::Errors::ClientError do
80
- error "DDE not started" unless dde_active?
81
- error "Conversation not started" unless conversation_active?
82
-
83
- item_handle = case item
84
- when String
85
- DDE::DdeString.new(@id, service).handle
86
- when DdeString
87
- item.handle
88
- else
89
- item
90
- end
91
-
92
- error unless result = dde_client_transaction(data_pointer, cb, @conversation, item_handle,
93
- format, transaction_type, timeout, trans_id)
94
- end
95
- [result, trans_id.get_uint32(0)]
96
- end
97
-
98
- def conversation_active?
99
- !!@conversation
100
- end
101
-
102
- end
1
+ module Dde
2
+
3
+ # Class encapsulates DDE Client that requests connection with DDE server and exchanges data with it via DDE
4
+ class Client < App
5
+
6
+ attr_reader :conversation, # active DDE conversation that client is engaged in
7
+ :service, #service that the client is connected to
8
+ :topic, # active DDE conversation topic
9
+ :item # active DDE conversation item
10
+
11
+ # # Creates new DDE client instance
12
+ # def initialize(init_flags = nil, &dde_callback )
13
+ # super init_flags, &dde_callback
14
+ # end
15
+
16
+ # Establish a conversation with a server application that supports the specified service
17
+ # name and topic name pair.
18
+ def start_conversation( service=nil, topic=nil )
19
+ try "Starting conversation #{service} #{topic}", Dde::Errors::ClientError do
20
+ error "DDE is not initialized" unless dde_active?
21
+ error "Another conversation already established" if conversation_active?
22
+
23
+ # Create DDE strings for service and topic unless they are omitted
24
+ @service = Dde::DdeString.new(@id, service) if service
25
+ @topic = Dde::DdeString.new(@id, topic) if topic
26
+
27
+ # Initiate new DDE conversation, returns conversation handle or nil
28
+ error unless @conversation = dde_connect(@id, @service.handle, @topic.handle)
29
+ end
30
+ end
31
+
32
+ # Stops active conversation, raises error if no conversations active
33
+ def stop_conversation
34
+ try "Stopping conversation", Dde::Errors::ClientError do
35
+ error "DDE not started" unless dde_active?
36
+ error "Conversation not started" unless conversation_active?
37
+
38
+ error unless dde_disconnect(@conversation) && # Stop DDE conversation
39
+ dde_free_string_handle(@id, @service.handle) && # Free string handles for service name
40
+ dde_free_string_handle(@id, @topic.handle) # Free string handles for topic name
41
+
42
+ # Unset attributes for conversation, service and topic
43
+ @conversation = nil
44
+ @service = nil
45
+ @topic = nil
46
+ end
47
+ end
48
+
49
+ # Sends XTYP_POKE transaction to server if conversation was already established.
50
+ # data:: data being sent (will be coerced to String unless is already a (packed) String)
51
+ # format:: standard clipboard format of submitted data item (default CF_TEXT)
52
+ def send_data( data, format = CF_TEXT, item = "" )
53
+ data_pointer = FFI::MemoryPointer.from_string(data.to_s)
54
+ result, trans_id = start_transaction(XTYP_POKE, data_pointer, data_pointer.size, format, item)
55
+ result
56
+ end
57
+
58
+ # Initiates transaction to server if conversation was already established.
59
+ # transaction_type:: XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_EXECUTE, XTYP_POKE, XTYP_REQUEST
60
+ # data_pointer:: pointer to data being sent (either FFI::MemoryPointer or DDE data_handle)
61
+ # cb:: data set size (or -1 to indicate that data_pointer is in fact DDE data_handle)
62
+ # format:: standard clipboard format of submitted data item (default CF_TEXT)
63
+ # item:: item to which transaction is related (String, DdeString or DDE string handle)
64
+ # timeout:: timeout in milliseconds or TIMEOUT_ASYNC to indicate async transaction
65
+ #
66
+ # *Returns*:: A pair of [result, trans_id]. Result is nil for failed transactions,
67
+ # DDE data handle for synchronous transactions in which the client expects data from the server,
68
+ # nonzero for successful transactions where clients does not expect data from server.
69
+ # Trans_id: for asynchronous transactions, a unique transaction identifier for use with the
70
+ # DdeAbandonTransaction function and the XTYP_XACT_COMPLETE transaction. For synchronous transactions,
71
+ # the low-order word of this variable contains any applicable DDE_ flags resulting from the transaction.
72
+ #
73
+ def start_transaction( transaction_type, data_pointer=nil, cb = data_pointer ? data_pointer.size : 0,
74
+ format=CF_TEXT, item=0, timeout=1000)
75
+
76
+ result = nil
77
+ trans_id = FFI::MemoryPointer.new(:uint32).put_uint32(0,0)
78
+
79
+ try "Sending data to server", Dde::Errors::ClientError do
80
+ error "DDE not started" unless dde_active?
81
+ error "Conversation not started" unless conversation_active?
82
+
83
+ item_handle = case item
84
+ when String
85
+ Dde::DdeString.new(@id, service).handle
86
+ when DdeString
87
+ item.handle
88
+ else
89
+ item
90
+ end
91
+
92
+ error unless result = dde_client_transaction(data_pointer, cb, @conversation, item_handle,
93
+ format, transaction_type, timeout, trans_id)
94
+ end
95
+ [result, trans_id.get_uint32(0)]
96
+ end
97
+
98
+ def conversation_active?
99
+ !!@conversation
100
+ end
101
+
102
+ end
103
103
  end