blob: 84ae3ecf2c0ee215aa92507171329e40097f6a51 [file] [log] [blame]
Roger Meier6cf0ffc2014-04-05 00:45:42 +02001--
2-- Licensed to the Apache Software Foundation (ASF) under one
3-- or more contributor license agreements. See the NOTICE file
4-- distributed with this work for additional information
5-- regarding copyright ownership. The ASF licenses this file
6-- to you under the Apache License, Version 2.0 (the
7-- "License"); you may not use this file except in compliance
8-- with the License. You may obtain a copy of the License at
9--
10-- http://www.apache.org/licenses/LICENSE-2.0
11--
12-- Unless required by applicable law or agreed to in writing,
13-- software distributed under the License is distributed on an
14-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15-- KIND, either express or implied. See the License for the
16-- specific language governing permissions and limitations
17-- under the License.
18--
19
20require 'TTransport'
21require 'libluabpack'
22
23TFramedTransport = TTransportBase:new{
24 __type = 'TFramedTransport',
25 doRead = true,
26 doWrite = true,
27 wBuf = '',
28 rBuf = ''
29}
30
31function TFramedTransport:new(obj)
32 if ttype(obj) ~= 'table' then
33 error(ttype(self) .. 'must be initialized with a table')
34 end
35
36 -- Ensure a transport is provided
37 if not obj.trans then
38 error('You must provide ' .. ttype(self) .. ' with a trans')
39 end
40
41 return TTransportBase:new(obj)
42end
43
44function TFramedTransport:isOpen()
45 return self.trans:isOpen()
46end
47
48function TFramedTransport:open()
49 return self.trans:open()
50end
51
52function TFramedTransport:close()
53 return self.trans:close()
54end
55
56function TFramedTransport:read(len)
57 if string.len(self.rBuf) == 0 then
58 self:__readFrame()
59 end
60
61 if self.doRead == false then
62 return self.trans:read(len)
63 end
64
65 if len > string.len(self.rBuf) then
66 local val = self.rBuf
67 self.rBuf = ''
68 return val
69 end
70
71 local val = string.sub(self.rBuf, 0, len)
72 self.rBuf = string.sub(self.rBuf, len)
73 return val
74end
75
76function TFramedTransport:__readFrame()
77 local buf = self.trans:readAll(4)
78 local frame_len = libluabpack.bunpack('i', buf)
79 self.rBuf = self.trans:readAll(frame_len)
80end
81
82function TFramedTransport:readAll(len)
83 return self.trans:readAll(len)
84end
85
86function TFramedTransport:write(buf, len)
87 if self.doWrite == false then
88 return self.trans:write(buf, len)
89 end
90
91 if len and len < string.len(buf) then
92 buf = string.sub(buf, 0, len)
93 end
94 self.wBuf = self.wBuf + buf
95end
96
97function TFramedTransport:flush()
98 if self.doWrite == false then
99 return self.trans:flush()
100 end
101
102 -- If the write fails we still want wBuf to be clear
103 local tmp = self.wBuf
104 self.wBuf = ''
105 self.trans:write(tmp)
106 self.trans:flush()
107end
108
109TFramedTransportFactory = TTransportFactoryBase:new{
110 __type = 'TFramedTransportFactory'
111}
112function TFramedTransportFactory:getTransport(trans)
113 if not trans then
114 terror(TProtocolException:new{
115 message = 'Must supply a transport to ' .. ttype(self)
116 })
117 end
118 return TFramedTransport:new{trans = trans}
119end