Completed
Branch master (477316)
by Michael
08:56
created

thrift.protocol.TBinaryProtocol   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 265
Duplicated Lines 76.98 %

Importance

Changes 0
Metric Value
wmc 51
eloc 165
dl 204
loc 265
rs 7.92
c 0
b 0
f 0

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like thrift.protocol.TBinaryProtocol often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#
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
20
from .TProtocol import *
21
from struct import pack, unpack
22
23
24
class TBinaryProtocol(TProtocolBase):
25
  """Binary implementation of the Thrift protocol driver."""
26
27
  # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be
28
  # positive, converting this into a long. If we hardcode the int value
29
  # instead it'll stay in 32 bit-land.
30
31
  # VERSION_MASK = 0xffff0000
32
  VERSION_MASK = -65536
33
34
  # VERSION_1 = 0x80010000
35
  VERSION_1 = -2147418112
36
37
  TYPE_MASK = 0x000000ff
38
39
  def __init__(self, trans, strictRead=False, strictWrite=True):
40
    TProtocolBase.__init__(self, trans)
41
    self.strictRead = strictRead
42
    self.strictWrite = strictWrite
43
44
  def writeMessageBegin(self, name, type, seqid):
45
    if self.strictWrite:
46
      self.writeI32(TBinaryProtocol.VERSION_1 | type)
47
      self.writeString(name)
48
      self.writeI32(seqid)
49
    else:
50
      self.writeString(name)
51
      self.writeByte(type)
52
      self.writeI32(seqid)
53
54
  def writeMessageEnd(self):
55
    pass
56
57
  def writeStructBegin(self, name):
58
    pass
59
60
  def writeStructEnd(self):
61
    pass
62
63
  def writeFieldBegin(self, name, type, id):
64
    self.writeByte(type)
65
    self.writeI16(id)
66
67
  def writeFieldEnd(self):
68
    pass
69
70
  def writeFieldStop(self):
71
    self.writeByte(TType.STOP)
72
73
  def writeMapBegin(self, ktype, vtype, size):
74
    self.writeByte(ktype)
75
    self.writeByte(vtype)
76
    self.writeI32(size)
77
78
  def writeMapEnd(self):
79
    pass
80
81
  def writeListBegin(self, etype, size):
82
    self.writeByte(etype)
83
    self.writeI32(size)
84
85
  def writeListEnd(self):
86
    pass
87
88
  def writeSetBegin(self, etype, size):
89
    self.writeByte(etype)
90
    self.writeI32(size)
91
92
  def writeSetEnd(self):
93
    pass
94
95
  def writeBool(self, bool):
96
    if bool:
97
      self.writeByte(1)
98
    else:
99
      self.writeByte(0)
100
101
  def writeByte(self, byte):
102
    buff = pack("!b", byte)
103
    self.trans.write(buff)
104
105
  def writeI16(self, i16):
106
    buff = pack("!h", i16)
107
    self.trans.write(buff)
108
109
  def writeI32(self, i32):
110
    buff = pack("!i", i32)
111
    self.trans.write(buff)
112
113
  def writeI64(self, i64):
114
    buff = pack("!q", i64)
115
    self.trans.write(buff)
116
117
  def writeDouble(self, dub):
118
    buff = pack("!d", dub)
119
    self.trans.write(buff)
120
121
  def writeString(self, str):
122
    self.writeI32(len(str))
123
    self.trans.write(str)
124
125
  def readMessageBegin(self):
126
    sz = self.readI32()
127
    if sz < 0:
128
      version = sz & TBinaryProtocol.VERSION_MASK
129
      if version != TBinaryProtocol.VERSION_1:
130
        raise TProtocolException(
131
          type=TProtocolException.BAD_VERSION,
132
          message='Bad version in readMessageBegin: %d' % (sz))
133
      type = sz & TBinaryProtocol.TYPE_MASK
134
      name = self.readString()
135
      seqid = self.readI32()
136
    else:
137
      if self.strictRead:
138
        raise TProtocolException(type=TProtocolException.BAD_VERSION,
139
                                 message='No protocol version header')
140
      name = self.trans.readAll(sz)
141
      type = self.readByte()
142
      seqid = self.readI32()
143
    return (name, type, seqid)
144
145
  def readMessageEnd(self):
146
    pass
147
148
  def readStructBegin(self):
149
    pass
150
151
  def readStructEnd(self):
152
    pass
153
154
  def readFieldBegin(self):
155
    type = self.readByte()
156
    if type == TType.STOP:
157
      return (None, type, 0)
158
    id = self.readI16()
159
    return (None, type, id)
160
161
  def readFieldEnd(self):
162
    pass
163
164
  def readMapBegin(self):
165
    ktype = self.readByte()
166
    vtype = self.readByte()
167
    size = self.readI32()
168
    return (ktype, vtype, size)
169
170
  def readMapEnd(self):
171
    pass
172
173
  def readListBegin(self):
174
    etype = self.readByte()
175
    size = self.readI32()
176
    return (etype, size)
177
178
  def readListEnd(self):
179
    pass
180
181
  def readSetBegin(self):
182
    etype = self.readByte()
183
    size = self.readI32()
184
    return (etype, size)
185
186
  def readSetEnd(self):
187
    pass
188
189
  def readBool(self):
190
    byte = self.readByte()
191
    if byte == 0:
192
      return False
193
    return True
194
195
  def readByte(self):
196
    buff = self.trans.readAll(1)
197
    val, = unpack('!b', buff)
198
    return val
199
200
  def readI16(self):
201
    buff = self.trans.readAll(2)
202
    val, = unpack('!h', buff)
203
    return val
204
205
  def readI32(self):
206
    buff = self.trans.readAll(4)
207
    try:
208
      val, = unpack('!i', buff)
209
    except TypeError:
210
      #str does not support the buffer interface
211
      val, = unpack('!i', buff)
212
    return val
213
214
  def readI64(self):
215
    buff = self.trans.readAll(8)
216
    val, = unpack('!q', buff)
217
    return val
218
219
  def readDouble(self):
220
    buff = self.trans.readAll(8)
221
    val, = unpack('!d', buff)
222
    return val
223
224
  def readString(self):
225
    len = self.readI32()
226
    str = self.trans.readAll(len)
227
    return str
228
229
230
class TBinaryProtocolFactory:
231
  def __init__(self, strictRead=False, strictWrite=True):
232
    self.strictRead = strictRead
233
    self.strictWrite = strictWrite
234
235
  def getProtocol(self, trans):
236
    prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite)
237
    return prot
238
239
240
class TBinaryProtocolAccelerated(TBinaryProtocol):
241
  """C-Accelerated version of TBinaryProtocol.
242
243
  This class does not override any of TBinaryProtocol's methods,
244
  but the generated code recognizes it directly and will call into
245
  our C module to do the encoding, bypassing this object entirely.
246
  We inherit from TBinaryProtocol so that the normal TBinaryProtocol
247
  encoding can happen if the fastbinary module doesn't work for some
248
  reason.  (TODO(dreiss): Make this happen sanely in more cases.)
249
250
  In order to take advantage of the C module, just use
251
  TBinaryProtocolAccelerated instead of TBinaryProtocol.
252
253
  NOTE:  This code was contributed by an external developer.
254
         The internal Thrift team has reviewed and tested it,
255
         but we cannot guarantee that it is production-ready.
256
         Please feel free to report bugs and/or success stories
257
         to the public mailing list.
258
  """
259
  pass
260
261
262
class TBinaryProtocolAcceleratedFactory:
263
  def getProtocol(self, trans):
264
    return TBinaryProtocolAccelerated(trans)
265