blob: 437b701379864afb90ae9ecc806ab054e762978b [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
zzn9815c192015-06-04 19:05:55 +080041 return TTransportBase.new(self, obj)
Roger Meier6cf0ffc2014-04-05 00:45:42 +020042end
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)
zzn9815c192015-06-04 19:05:55 +080072 self.rBuf = string.sub(self.rBuf, len+1)
Roger Meier6cf0ffc2014-04-05 00:45:42 +020073 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
Roger Meier6cf0ffc2014-04-05 00:45:42 +020082
83function TFramedTransport:write(buf, len)
84 if self.doWrite == false then
85 return self.trans:write(buf, len)
86 end
87
88 if len and len < string.len(buf) then
89 buf = string.sub(buf, 0, len)
90 end
zzn9815c192015-06-04 19:05:55 +080091 self.wBuf = self.wBuf .. buf
Roger Meier6cf0ffc2014-04-05 00:45:42 +020092end
93
94function TFramedTransport:flush()
95 if self.doWrite == false then
96 return self.trans:flush()
97 end
98
99 -- If the write fails we still want wBuf to be clear
100 local tmp = self.wBuf
101 self.wBuf = ''
zzn9815c192015-06-04 19:05:55 +0800102 local frame_len_buf = libluabpack.bpack("i", string.len(tmp))
103 self.trans:write(frame_len_buf)
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200104 self.trans:write(tmp)
105 self.trans:flush()
106end
107
108TFramedTransportFactory = TTransportFactoryBase:new{
109 __type = 'TFramedTransportFactory'
110}
111function TFramedTransportFactory:getTransport(trans)
112 if not trans then
113 terror(TProtocolException:new{
114 message = 'Must supply a transport to ' .. ttype(self)
115 })
116 end
117 return TFramedTransport:new{trans = trans}
118end