copper-cti 2.2.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.
- checksums.yaml +7 -0
- data/src/code/CTI/Builder/FileBuilder.rb +36 -0
- data/src/code/CTI/Builder/NullBuilder.rb +29 -0
- data/src/code/CTI/Builder/StreamBuilder.rb +212 -0
- data/src/code/CTI/CTIP2/CTIP2.rb +396 -0
- data/src/code/CTI/CTIP2/Utils.rb +119 -0
- data/src/code/CTI/Driver.rb +70 -0
- data/src/code/CTI/Results/DirectoryResults.rb +31 -0
- data/src/code/CTI/Results/SingleResult.rb +36 -0
- data/src/code/CTI/Session.rb +566 -0
- data/src/code/CTI.rb +53 -0
- metadata +52 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5cdd69afbbde6d1d1b50191f409c57627960fe85190d4f86ec5c1f94c334e0fa
|
|
4
|
+
data.tar.gz: 76969132610a3b8cedc70ffd088d75792dbaf90e74031432c4f1914a96c21065
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0cc2ea939f18e9a8e9d281551b138e955845b13cb70fee2f90deadf375b9b411a3dfb186983a6d69bd91303405b54f597a1f9be4d574a18cd5f0b35cac675bf2
|
|
7
|
+
data.tar.gz: 212f9c76afe757de47d15c9efdc307354dd0e638d57385e8aa44300ac06297512ee2461c2e6012ca6899b6f6cbff883b7a53fd612d9e46fa4809d71cb4d17172
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require File.expand_path('StreamBuilder', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module CTI
|
|
4
|
+
module Builder
|
|
5
|
+
=begin rdoc
|
|
6
|
+
Version:: $Id: FileBuilder.rb 902 2013-04-23 05:07:04Z miyabe $
|
|
7
|
+
|
|
8
|
+
ファイルに対して結果を構築するオブジェクトです。
|
|
9
|
+
=end
|
|
10
|
+
class FileBuilder < StreamBuilder
|
|
11
|
+
=begin rdoc
|
|
12
|
+
結果構築オブジェクトを作成します。
|
|
13
|
+
|
|
14
|
+
file:: 結果ファイル
|
|
15
|
+
=end
|
|
16
|
+
def initialize(file)
|
|
17
|
+
super(nil)
|
|
18
|
+
@file = file
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def serial_write(data)
|
|
22
|
+
@out = File.open(@file, 'wb') unless @out
|
|
23
|
+
@out.write(data)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def finish
|
|
27
|
+
unless @out
|
|
28
|
+
@out = File.open(@file, 'wb')
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
@out.close
|
|
32
|
+
@out = nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module CTI
|
|
2
|
+
module Builder
|
|
3
|
+
=begin rdoc
|
|
4
|
+
このオブジェクトは結果を構築しません。
|
|
5
|
+
=end
|
|
6
|
+
class NullBuilder
|
|
7
|
+
def add_block
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def insert_block_before (anchor_id)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def write (id, data)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def close_block (id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def serial_write (data)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def finish
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def dispose
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
|
|
3
|
+
module CTI
|
|
4
|
+
=begin rdoc
|
|
5
|
+
このモジュールのクラスは、1つの出力結果を構築するためのものです。
|
|
6
|
+
=end
|
|
7
|
+
module Builder
|
|
8
|
+
class Fragment
|
|
9
|
+
def initialize(id)
|
|
10
|
+
@id = id
|
|
11
|
+
@prev = nil
|
|
12
|
+
@nxt = nil
|
|
13
|
+
@length = 0
|
|
14
|
+
@buffer = ''
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def id
|
|
18
|
+
@id
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prev=(prev)
|
|
22
|
+
@prev = prev
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def prev
|
|
26
|
+
@prev
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def nxt=(nxt)
|
|
30
|
+
@nxt = nxt
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def nxt
|
|
34
|
+
@nxt
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
=begin
|
|
38
|
+
フラグメントにデータを書き込みます。
|
|
39
|
+
|
|
40
|
+
tempFile:: 一時ファイル
|
|
41
|
+
onMemory:: メモリ上に置かれたデータの合計サイズ
|
|
42
|
+
segment:: セグメント番号シーケンス
|
|
43
|
+
bytes:: データ
|
|
44
|
+
|
|
45
|
+
戻り値:: 書き込んだバイト数
|
|
46
|
+
=end
|
|
47
|
+
|
|
48
|
+
def write(tempFile, onMemory, segment, bytes)
|
|
49
|
+
len = bytes.bytesize
|
|
50
|
+
if (!@segments &&
|
|
51
|
+
@length + len <= CTIP2::FRG_MEM_SIZE &&
|
|
52
|
+
onMemory + len <= CTIP2::ON_MEMORY)
|
|
53
|
+
@buffer += bytes
|
|
54
|
+
onMemory += len
|
|
55
|
+
else
|
|
56
|
+
if @buffer
|
|
57
|
+
segment, wlen = raf_write(tempFile, segment, @buffer)
|
|
58
|
+
onMemory -= wlen
|
|
59
|
+
@buffer = nil
|
|
60
|
+
end
|
|
61
|
+
segment, len = raf_write(tempFile, segment, bytes)
|
|
62
|
+
end
|
|
63
|
+
@length += len
|
|
64
|
+
return onMemory, segment, len
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
=begin
|
|
68
|
+
フラグメントの内容を吐き出して、フラグメントを破棄します。
|
|
69
|
+
|
|
70
|
+
tempFile:: 一時ファイル
|
|
71
|
+
out:: 出力先ストリーム( IO )
|
|
72
|
+
=end
|
|
73
|
+
|
|
74
|
+
def flush(tempFile, out)
|
|
75
|
+
unless @segments
|
|
76
|
+
out.write(@buffer)
|
|
77
|
+
@buffer = nil
|
|
78
|
+
else
|
|
79
|
+
segcount = @segments.size
|
|
80
|
+
for seg in @segments
|
|
81
|
+
tempFile.pos = seg * CTIP2::SEGMENT_SIZE
|
|
82
|
+
buff = tempFile.read(seg == @segments.last ? @segLen : CTIP2::SEGMENT_SIZE)
|
|
83
|
+
out.write(buff)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
=begin
|
|
90
|
+
一時ファイルに書き込みます。
|
|
91
|
+
|
|
92
|
+
tempFile:: 一時ファイル
|
|
93
|
+
segment:: セグメント番号シーケンス
|
|
94
|
+
bytes:: データ
|
|
95
|
+
|
|
96
|
+
戻り値:: 書き込んだバイト数
|
|
97
|
+
=end
|
|
98
|
+
|
|
99
|
+
def raf_write(tempFile, segment, bytes)
|
|
100
|
+
unless @segments
|
|
101
|
+
@segments = [segment]
|
|
102
|
+
segment += 1
|
|
103
|
+
@segLen = 0
|
|
104
|
+
end
|
|
105
|
+
written = 0
|
|
106
|
+
while (len = bytes.bytesize) > 0
|
|
107
|
+
if @segLen == CTIP2::SEGMENT_SIZE
|
|
108
|
+
@segments << segment
|
|
109
|
+
segment += 1
|
|
110
|
+
@segLen = 0
|
|
111
|
+
end
|
|
112
|
+
seg = @segments.last
|
|
113
|
+
wlen = [len, CTIP2::SEGMENT_SIZE - @segLen].min
|
|
114
|
+
wpos = seg * CTIP2::SEGMENT_SIZE + @segLen
|
|
115
|
+
tempFile.pos = wpos
|
|
116
|
+
data = bytes.slice!(0, wlen)
|
|
117
|
+
tempFile.write(data)
|
|
118
|
+
@segLen += wlen
|
|
119
|
+
written += wlen
|
|
120
|
+
end
|
|
121
|
+
return segment, written
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
=begin rdoc
|
|
125
|
+
Version:: $Id: StreamBuilder.rb 902 2013-04-23 05:07:04Z miyabe $
|
|
126
|
+
|
|
127
|
+
ストリームに対して結果を構築するオブジェクトです。
|
|
128
|
+
=end
|
|
129
|
+
|
|
130
|
+
class StreamBuilder
|
|
131
|
+
=begin rdoc
|
|
132
|
+
結果構築オブジェクトを作成します。
|
|
133
|
+
|
|
134
|
+
out:: 出力先ストリーム
|
|
135
|
+
&finish:: 結果を実際に出力する前に呼び出されるブロック。引数として結果のバイト数が渡されます
|
|
136
|
+
|
|
137
|
+
例:
|
|
138
|
+
SingleResult.new(StreamBuilder.new($stdout) do |length|
|
|
139
|
+
print "Content-Length: #{length}\r\n\r\n"
|
|
140
|
+
end) do |opts|
|
|
141
|
+
print "Content-Type: #{opts['mime_type']}\r\n"
|
|
142
|
+
end
|
|
143
|
+
=end
|
|
144
|
+
def initialize(out, &finish)
|
|
145
|
+
@tempFile = Tempfile.open(['cti', '.tmp'])
|
|
146
|
+
@tempFile.binmode
|
|
147
|
+
@out = out
|
|
148
|
+
@finish = finish
|
|
149
|
+
@frgs = []
|
|
150
|
+
@first = nil
|
|
151
|
+
@last = nil
|
|
152
|
+
@onMemory = 0
|
|
153
|
+
@length = 0
|
|
154
|
+
@segment = 0
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def add_block
|
|
158
|
+
id = @frgs.size
|
|
159
|
+
frg = Fragment.new(id)
|
|
160
|
+
@frgs[id] = frg
|
|
161
|
+
unless @first
|
|
162
|
+
@first = frg
|
|
163
|
+
else
|
|
164
|
+
@last.nxt = frg
|
|
165
|
+
frg.prev = @last
|
|
166
|
+
end
|
|
167
|
+
@last = frg
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def insert_block_before(anchor_id)
|
|
171
|
+
id = @frgs.size
|
|
172
|
+
anchor = @frgs[anchor_id]
|
|
173
|
+
frg = Fragment.new(id)
|
|
174
|
+
@frgs[id] = frg
|
|
175
|
+
frg.prev = anchor.prev
|
|
176
|
+
frg.nxt = anchor
|
|
177
|
+
anchor.prev.nxt = frg
|
|
178
|
+
anchor.prev = frg
|
|
179
|
+
@first = frg if @first.id == anchor.id
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def write(id, data)
|
|
183
|
+
frg = @frgs[id]
|
|
184
|
+
@onMemory, @segment, len = frg.write(@tempFile, @onMemory, @segment, data)
|
|
185
|
+
@length += len
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def close_block(id)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def serial_write(data)
|
|
192
|
+
@out.write(data)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def finish
|
|
196
|
+
begin
|
|
197
|
+
@finish.call(@length) if @finish
|
|
198
|
+
frg = @first
|
|
199
|
+
while frg
|
|
200
|
+
frg.flush(@tempFile, @out)
|
|
201
|
+
frg = frg.nxt
|
|
202
|
+
end
|
|
203
|
+
ensure
|
|
204
|
+
@tempFile.close
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def dispose
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
require File.expand_path('Utils', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module CTI
|
|
4
|
+
=begin rdoc
|
|
5
|
+
Version:: $Id: CTIP2.rb 902 2013-04-23 05:07:04Z miyabe $
|
|
6
|
+
|
|
7
|
+
通信プロトコルに関連する各操作です。
|
|
8
|
+
|
|
9
|
+
このモジュールに所属するメソッドは、 IO に対するものです。
|
|
10
|
+
=end
|
|
11
|
+
module CTIP2
|
|
12
|
+
REQ_PROPERTY = 0x01
|
|
13
|
+
REQ_START_MAIN = 0x02
|
|
14
|
+
REQ_SERVER_MAIN = 0x03
|
|
15
|
+
REQ_CLIENT_RESOURCE = 0x04
|
|
16
|
+
REQ_CONTINUOUS = 0x05
|
|
17
|
+
REQ_DATA = 0x11
|
|
18
|
+
REQ_START_RESOURCE = 0x21
|
|
19
|
+
REQ_MISSING_RESOURCE = 0x22
|
|
20
|
+
REQ_EOF = 0x31
|
|
21
|
+
REQ_ABORT = 0x32
|
|
22
|
+
REQ_JOIN = 0x33
|
|
23
|
+
REQ_RESET = 0x41
|
|
24
|
+
REQ_CLOSE = 0x42
|
|
25
|
+
REQ_SERVER_INFO = 0x51
|
|
26
|
+
|
|
27
|
+
RES_START_DATA = 0x01
|
|
28
|
+
RES_BLOCK_DATA = 0x11
|
|
29
|
+
RES_ADD_BLOCK = 0x12
|
|
30
|
+
RES_INSERT_BLOCK = 0x13
|
|
31
|
+
RES_MESSAGE = 0x14
|
|
32
|
+
RES_MAIN_LENGTH = 0x15
|
|
33
|
+
RES_MAIN_READ = 0x16
|
|
34
|
+
RES_DATA = 0x17
|
|
35
|
+
RES_CLOSE_BLOCK = 0x18
|
|
36
|
+
RES_RESOURCE_REQUEST = 0x21
|
|
37
|
+
RES_EOF = 0x31
|
|
38
|
+
RES_ABORT = 0x32
|
|
39
|
+
RES_NEXT = 0x33
|
|
40
|
+
|
|
41
|
+
=begin rdoc
|
|
42
|
+
パケットの送信に使うバッファのサイズです。
|
|
43
|
+
=end
|
|
44
|
+
CTI_BUFFER_SIZE = 1024
|
|
45
|
+
|
|
46
|
+
=begin rdoc
|
|
47
|
+
メモリ上のフラグメントの最大サイズです。
|
|
48
|
+
|
|
49
|
+
フラグメントがこの大きさを超えるとディスクに書き込みます。
|
|
50
|
+
=end
|
|
51
|
+
FRG_MEM_SIZE = 256
|
|
52
|
+
|
|
53
|
+
=begin rdoc
|
|
54
|
+
メモリ上に置かれるデータの最大サイズです。
|
|
55
|
+
|
|
56
|
+
メモリ上のデータがこのサイズを超えると、
|
|
57
|
+
FRG_MEM_SIZEとは無関係にディスクに書き込まれます。
|
|
58
|
+
=end
|
|
59
|
+
ON_MEMORY = 1024 * 1024
|
|
60
|
+
|
|
61
|
+
=begin rdoc
|
|
62
|
+
一時ファイルのセグメントサイズです。
|
|
63
|
+
=end
|
|
64
|
+
SEGMENT_SIZE = 8192
|
|
65
|
+
|
|
66
|
+
=begin rdoc
|
|
67
|
+
セッションを開始します。
|
|
68
|
+
|
|
69
|
+
encoding:: 通信に用いるエンコーディング
|
|
70
|
+
=end
|
|
71
|
+
def cti_connect(encoding)
|
|
72
|
+
self.write("CTIP/2.0 #{encoding}\n")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
=begin rdoc
|
|
76
|
+
サーバー情報を要求します。
|
|
77
|
+
|
|
78
|
+
uri:: URI
|
|
79
|
+
=end
|
|
80
|
+
|
|
81
|
+
def req_server_info(uri)
|
|
82
|
+
payload = 1 + 2 + uri.bytesize
|
|
83
|
+
self.write_int(payload)
|
|
84
|
+
self.write_byte(CTIP2::REQ_SERVER_INFO)
|
|
85
|
+
self.write_bytes(uri)
|
|
86
|
+
self.flush
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
=begin rdoc
|
|
90
|
+
サーバーからクライアントのリソースを要求するモードを切り替えます。
|
|
91
|
+
|
|
92
|
+
mode:: 0=off, 1=on
|
|
93
|
+
=end
|
|
94
|
+
|
|
95
|
+
def req_client_resource(mode)
|
|
96
|
+
payload = 2
|
|
97
|
+
self.write_int(payload)
|
|
98
|
+
self.write_byte(CTIP2::REQ_CLIENT_RESOURCE)
|
|
99
|
+
self.write_byte(mode)
|
|
100
|
+
self.flush
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
=begin rdoc
|
|
104
|
+
複数の結果を結合するモードを切り替えます。
|
|
105
|
+
|
|
106
|
+
mode:: 0=off, 1=on
|
|
107
|
+
=end
|
|
108
|
+
|
|
109
|
+
def req_continuous(mode)
|
|
110
|
+
payload = 2
|
|
111
|
+
self.write_int(payload)
|
|
112
|
+
self.write_byte(CTIP2::REQ_CONTINUOUS)
|
|
113
|
+
self.write_byte(mode)
|
|
114
|
+
self.flush
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
=begin rdoc
|
|
118
|
+
リソースの不存在を通知します。
|
|
119
|
+
|
|
120
|
+
uri:: URI
|
|
121
|
+
=end
|
|
122
|
+
|
|
123
|
+
def req_missing_resource(uri)
|
|
124
|
+
payload = 1 + 2 + uri.bytesize
|
|
125
|
+
self.write_int(payload)
|
|
126
|
+
self.write_byte(CTIP2::REQ_MISSING_RESOURCE)
|
|
127
|
+
self.write_bytes(uri)
|
|
128
|
+
self.flush
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
=begin rdoc
|
|
132
|
+
状態のリセットを要求します。
|
|
133
|
+
=end
|
|
134
|
+
|
|
135
|
+
def req_reset
|
|
136
|
+
payload = 1
|
|
137
|
+
self.write_int(payload)
|
|
138
|
+
self.write_byte(CTIP2::REQ_RESET)
|
|
139
|
+
self.flush
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
=begin rdoc
|
|
143
|
+
変換処理の中断を要求します。
|
|
144
|
+
|
|
145
|
+
mode:: 0=生成済みのデータを出力して中断, 1=即時中断
|
|
146
|
+
=end
|
|
147
|
+
|
|
148
|
+
def req_abort(mode)
|
|
149
|
+
payload = 2
|
|
150
|
+
self.write_int(payload)
|
|
151
|
+
self.write_byte(CTIP2::REQ_ABORT)
|
|
152
|
+
self.write_byte(mode)
|
|
153
|
+
self.flush
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
=begin rdoc
|
|
157
|
+
変換結果を結合します。
|
|
158
|
+
=end
|
|
159
|
+
|
|
160
|
+
def req_join
|
|
161
|
+
payload = 1
|
|
162
|
+
self.write_int(payload)
|
|
163
|
+
self.write_byte(CTIP2::REQ_JOIN)
|
|
164
|
+
self.flush
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
=begin rdoc
|
|
168
|
+
終了を通知します。
|
|
169
|
+
=end
|
|
170
|
+
|
|
171
|
+
def req_eof
|
|
172
|
+
payload = 1
|
|
173
|
+
self.write_int(payload)
|
|
174
|
+
self.write_byte(CTIP2::REQ_EOF)
|
|
175
|
+
self.flush
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
=begin rdoc
|
|
179
|
+
プロパティを送ります。
|
|
180
|
+
|
|
181
|
+
name:: 名前
|
|
182
|
+
value:: 値
|
|
183
|
+
=end
|
|
184
|
+
|
|
185
|
+
def req_property(name, value)
|
|
186
|
+
payload = name.bytesize + value.bytesize + 5
|
|
187
|
+
self.write_int(payload)
|
|
188
|
+
self.write_byte(CTIP2::REQ_PROPERTY)
|
|
189
|
+
self.write_bytes(name)
|
|
190
|
+
self.write_bytes(value)
|
|
191
|
+
self.flush
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
=begin rdoc
|
|
195
|
+
サーバー側データの変換を要求します。
|
|
196
|
+
|
|
197
|
+
uri:: URI
|
|
198
|
+
=end
|
|
199
|
+
|
|
200
|
+
def req_server_main(uri)
|
|
201
|
+
payload = uri.bytesize + 3
|
|
202
|
+
self.write_int(payload)
|
|
203
|
+
self.write_byte(CTIP2::REQ_SERVER_MAIN)
|
|
204
|
+
self.write_bytes(uri)
|
|
205
|
+
self.flush
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
=begin rdoc
|
|
209
|
+
リソースの開始を通知します。
|
|
210
|
+
|
|
211
|
+
uri:: URI
|
|
212
|
+
mime_type:: MIME型
|
|
213
|
+
encoding:: エンコーディング
|
|
214
|
+
length:: 長さ
|
|
215
|
+
=end
|
|
216
|
+
|
|
217
|
+
def req_resource(uri, mime_type = 'text/css', encoding = '', length = -1)
|
|
218
|
+
payload = uri.bytesize + mime_type.bytesize + encoding.bytesize + 7 + 8
|
|
219
|
+
self.write_int(payload)
|
|
220
|
+
self.write_byte(CTIP2::REQ_START_RESOURCE)
|
|
221
|
+
self.write_bytes(uri)
|
|
222
|
+
self.write_bytes(mime_type)
|
|
223
|
+
self.write_bytes(encoding)
|
|
224
|
+
self.write_long(length)
|
|
225
|
+
self.flush
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
=begin rdoc
|
|
229
|
+
本体の開始を通知します。
|
|
230
|
+
|
|
231
|
+
uri:: URI
|
|
232
|
+
mime_type:: MIME型
|
|
233
|
+
encoding:: エンコーディング
|
|
234
|
+
length:: 長さ
|
|
235
|
+
=end
|
|
236
|
+
|
|
237
|
+
def req_start_main(uri, mime_type = 'text/html', encoding = '', length = -1)
|
|
238
|
+
payload = uri.bytesize + mime_type.bytesize + encoding.bytesize + 7 + 8
|
|
239
|
+
self.write_int(payload)
|
|
240
|
+
self.write_byte(CTIP2::REQ_START_MAIN)
|
|
241
|
+
self.write_bytes(uri)
|
|
242
|
+
self.write_bytes(mime_type)
|
|
243
|
+
self.write_bytes(encoding)
|
|
244
|
+
self.write_long(length)
|
|
245
|
+
self.flush
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
=begin rdoc
|
|
249
|
+
データを送ります。
|
|
250
|
+
|
|
251
|
+
b:: データ
|
|
252
|
+
=end
|
|
253
|
+
|
|
254
|
+
def req_write(b)
|
|
255
|
+
payload = b.bytesize + 1
|
|
256
|
+
self.write_int(payload)
|
|
257
|
+
self.write_byte(CTIP2::REQ_DATA)
|
|
258
|
+
self.write(b)
|
|
259
|
+
self.flush
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
=begin rdoc
|
|
263
|
+
通信を終了します。
|
|
264
|
+
=end
|
|
265
|
+
|
|
266
|
+
def req_close
|
|
267
|
+
payload = 1
|
|
268
|
+
self.write_int(payload)
|
|
269
|
+
self.write_byte(CTIP2::REQ_CLOSE)
|
|
270
|
+
self.flush
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
=begin rdoc
|
|
274
|
+
次のレスポンスを取得します。
|
|
275
|
+
|
|
276
|
+
結果ハッシュには次のデータが含まれます。
|
|
277
|
+
|
|
278
|
+
- 'type' レスポンスタイプ
|
|
279
|
+
- 'anchorId' 挿入する場所の直後のフラグメントID
|
|
280
|
+
- 'level' エラーレベル
|
|
281
|
+
- 'error' エラーメッセージ
|
|
282
|
+
- 'id' 断片ID
|
|
283
|
+
- 'progress' 処理済バイト数
|
|
284
|
+
- 'bytes' データのバイト列
|
|
285
|
+
|
|
286
|
+
戻り値:: レスポンス
|
|
287
|
+
=end
|
|
288
|
+
|
|
289
|
+
def res_next
|
|
290
|
+
payload = self.read_int
|
|
291
|
+
type = self.read_byte
|
|
292
|
+
|
|
293
|
+
case type
|
|
294
|
+
when CTIP2::RES_ADD_BLOCK, CTIP2::RES_EOF, CTIP2::RES_NEXT
|
|
295
|
+
return {
|
|
296
|
+
'type' => type,
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
when CTIP2::RES_START_DATA
|
|
300
|
+
uri = self.read_bytes
|
|
301
|
+
mime_type = self.read_bytes
|
|
302
|
+
encoding = self.read_bytes
|
|
303
|
+
length = self.read_long
|
|
304
|
+
return {
|
|
305
|
+
'type' => type,
|
|
306
|
+
'uri' => uri,
|
|
307
|
+
'mime_type' => mime_type,
|
|
308
|
+
'encoding' => encoding,
|
|
309
|
+
'length' => length
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
when CTIP2::RES_MAIN_LENGTH, CTIP2::RES_MAIN_READ
|
|
313
|
+
length = self.read_long
|
|
314
|
+
return {
|
|
315
|
+
'type' => type,
|
|
316
|
+
'length' => length
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
when CTIP2::RES_INSERT_BLOCK, CTIP2::RES_CLOSE_BLOCK
|
|
320
|
+
block_id = self.read_int
|
|
321
|
+
return {
|
|
322
|
+
'type' => type,
|
|
323
|
+
'block_id' => block_id
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
when CTIP2::RES_MESSAGE
|
|
327
|
+
code = self.read_short
|
|
328
|
+
payload -= 1 + 2
|
|
329
|
+
message = self.read_bytes
|
|
330
|
+
payload -= 2 + message.bytesize
|
|
331
|
+
args = []
|
|
332
|
+
while payload > 0
|
|
333
|
+
arg = self.read_bytes
|
|
334
|
+
payload -= 2 + arg.bytesize
|
|
335
|
+
args << arg
|
|
336
|
+
end
|
|
337
|
+
return {
|
|
338
|
+
'type' => type,
|
|
339
|
+
'code' => code,
|
|
340
|
+
'message' => message,
|
|
341
|
+
'args' => args
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
when CTIP2::RES_BLOCK_DATA
|
|
345
|
+
length = payload - 5
|
|
346
|
+
block_id = self.read_int
|
|
347
|
+
bytes = self.read(length)
|
|
348
|
+
return {
|
|
349
|
+
'type' => type,
|
|
350
|
+
'block_id' => block_id,
|
|
351
|
+
'bytes' => bytes,
|
|
352
|
+
'length' => length
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
when CTIP2::RES_DATA
|
|
356
|
+
length = payload - 1
|
|
357
|
+
bytes = self.read(length)
|
|
358
|
+
return {
|
|
359
|
+
'type' => type,
|
|
360
|
+
'bytes' => bytes,
|
|
361
|
+
'length' => length
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
when CTIP2::RES_RESOURCE_REQUEST
|
|
365
|
+
uri = self.read_bytes
|
|
366
|
+
return {
|
|
367
|
+
'type' => type,
|
|
368
|
+
'uri' => uri
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
when CTIP2::RES_ABORT
|
|
372
|
+
mode = self.read_byte
|
|
373
|
+
code = self.read_short
|
|
374
|
+
payload -= 1 + 1 + 2
|
|
375
|
+
message = self.read_bytes
|
|
376
|
+
payload -= 2 + message.bytesize
|
|
377
|
+
args = []
|
|
378
|
+
while payload > 0
|
|
379
|
+
arg = self.read_bytes
|
|
380
|
+
payload -= 2 + arg.bytesize
|
|
381
|
+
args << arg
|
|
382
|
+
end
|
|
383
|
+
return {
|
|
384
|
+
'type' => type,
|
|
385
|
+
'mode' => mode,
|
|
386
|
+
'code' => code,
|
|
387
|
+
'message' => message,
|
|
388
|
+
'args' => args
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
else
|
|
392
|
+
raise "Bad response type:#{type}"
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
end
|