diff options
| author | 2015-04-07 22:22:18 +0200 | |
|---|---|---|
| committer | 2015-04-07 22:22:18 +0200 | |
| commit | d2fe85670726901da627490da4155af972c1a62e (patch) | |
| tree | b8931d070a51b6d8b1dabe881f54504f9d9ef6de /lib/thrift/protocol | |
| parent | Update user-agent (diff) | |
| parent | fix gui (diff) | |
| download | pyload-d2fe85670726901da627490da4155af972c1a62e.tar.xz | |
Merge branch 'pr/n1_ardi69' into 0.4.10
Diffstat (limited to 'lib/thrift/protocol')
| -rw-r--r-- | lib/thrift/protocol/TBase.py | 72 | ||||
| -rw-r--r-- | lib/thrift/protocol/TBinaryProtocol.py | 259 | ||||
| -rw-r--r-- | lib/thrift/protocol/TCompactProtocol.py | 395 | ||||
| -rw-r--r-- | lib/thrift/protocol/TProtocol.py | 404 | ||||
| -rw-r--r-- | lib/thrift/protocol/__init__.py | 20 | 
5 files changed, 1150 insertions, 0 deletions
diff --git a/lib/thrift/protocol/TBase.py b/lib/thrift/protocol/TBase.py new file mode 100644 index 000000000..e675c7dc0 --- /dev/null +++ b/lib/thrift/protocol/TBase.py @@ -0,0 +1,72 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +#   http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from thrift.Thrift import * +from thrift.protocol import TBinaryProtocol +from thrift.transport import TTransport + +try: +  from thrift.protocol import fastbinary +except: +  fastbinary = None + +class TBase(object): +  __slots__ = [] + +  def __repr__(self): +    L = ['%s=%r' % (key, getattr(self, key)) +              for key in self.__slots__ ] +    return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + +  def __eq__(self, other): +    if not isinstance(other, self.__class__): +      return False +    for attr in self.__slots__: +      my_val = getattr(self, attr) +      other_val = getattr(other, attr) +      if my_val != other_val: +        return False +    return True +     +  def __ne__(self, other): +    return not (self == other) +   +  def read(self, iprot): +    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: +      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) +      return +    iprot.readStruct(self, self.thrift_spec) + +  def write(self, oprot): +    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: +      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) +      return +    oprot.writeStruct(self, self.thrift_spec) + +class TExceptionBase(Exception): +  # old style class so python2.4 can raise exceptions derived from this +  #  This can't inherit from TBase because of that limitation. +  __slots__ = [] +   +  __repr__ = TBase.__repr__.im_func +  __eq__ = TBase.__eq__.im_func +  __ne__ = TBase.__ne__.im_func +  read = TBase.read.im_func +  write = TBase.write.im_func +   diff --git a/lib/thrift/protocol/TBinaryProtocol.py b/lib/thrift/protocol/TBinaryProtocol.py new file mode 100644 index 000000000..50c6aa896 --- /dev/null +++ b/lib/thrift/protocol/TBinaryProtocol.py @@ -0,0 +1,259 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +#   http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from TProtocol import * +from struct import pack, unpack + +class TBinaryProtocol(TProtocolBase): + +  """Binary implementation of the Thrift protocol driver.""" + +  # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be +  # positive, converting this into a long. If we hardcode the int value +  # instead it'll stay in 32 bit-land. + +  # VERSION_MASK = 0xffff0000 +  VERSION_MASK = -65536 + +  # VERSION_1 = 0x80010000 +  VERSION_1 = -2147418112 + +  TYPE_MASK = 0x000000ff + +  def __init__(self, trans, strictRead=False, strictWrite=True): +    TProtocolBase.__init__(self, trans) +    self.strictRead = strictRead +    self.strictWrite = strictWrite + +  def writeMessageBegin(self, name, type, seqid): +    if self.strictWrite: +      self.writeI32(TBinaryProtocol.VERSION_1 | type) +      self.writeString(name) +      self.writeI32(seqid) +    else: +      self.writeString(name) +      self.writeByte(type) +      self.writeI32(seqid) + +  def writeMessageEnd(self): +    pass + +  def writeStructBegin(self, name): +    pass + +  def writeStructEnd(self): +    pass + +  def writeFieldBegin(self, name, type, id): +    self.writeByte(type) +    self.writeI16(id) + +  def writeFieldEnd(self): +    pass + +  def writeFieldStop(self): +    self.writeByte(TType.STOP); + +  def writeMapBegin(self, ktype, vtype, size): +    self.writeByte(ktype) +    self.writeByte(vtype) +    self.writeI32(size) + +  def writeMapEnd(self): +    pass + +  def writeListBegin(self, etype, size): +    self.writeByte(etype) +    self.writeI32(size) + +  def writeListEnd(self): +    pass + +  def writeSetBegin(self, etype, size): +    self.writeByte(etype) +    self.writeI32(size) + +  def writeSetEnd(self): +    pass + +  def writeBool(self, bool): +    if bool: +      self.writeByte(1) +    else: +      self.writeByte(0) + +  def writeByte(self, byte): +    buff = pack("!b", byte) +    self.trans.write(buff) + +  def writeI16(self, i16): +    buff = pack("!h", i16) +    self.trans.write(buff) + +  def writeI32(self, i32): +    buff = pack("!i", i32) +    self.trans.write(buff) + +  def writeI64(self, i64): +    buff = pack("!q", i64) +    self.trans.write(buff) + +  def writeDouble(self, dub): +    buff = pack("!d", dub) +    self.trans.write(buff) + +  def writeString(self, str): +    self.writeI32(len(str)) +    self.trans.write(str) + +  def readMessageBegin(self): +    sz = self.readI32() +    if sz < 0: +      version = sz & TBinaryProtocol.VERSION_MASK +      if version != TBinaryProtocol.VERSION_1: +        raise TProtocolException(type=TProtocolException.BAD_VERSION, message='Bad version in readMessageBegin: %d' % (sz)) +      type = sz & TBinaryProtocol.TYPE_MASK +      name = self.readString() +      seqid = self.readI32() +    else: +      if self.strictRead: +        raise TProtocolException(type=TProtocolException.BAD_VERSION, message='No protocol version header') +      name = self.trans.readAll(sz) +      type = self.readByte() +      seqid = self.readI32() +    return (name, type, seqid) + +  def readMessageEnd(self): +    pass + +  def readStructBegin(self): +    pass + +  def readStructEnd(self): +    pass + +  def readFieldBegin(self): +    type = self.readByte() +    if type == TType.STOP: +      return (None, type, 0) +    id = self.readI16() +    return (None, type, id) + +  def readFieldEnd(self): +    pass + +  def readMapBegin(self): +    ktype = self.readByte() +    vtype = self.readByte() +    size = self.readI32() +    return (ktype, vtype, size) + +  def readMapEnd(self): +    pass + +  def readListBegin(self): +    etype = self.readByte() +    size = self.readI32() +    return (etype, size) + +  def readListEnd(self): +    pass + +  def readSetBegin(self): +    etype = self.readByte() +    size = self.readI32() +    return (etype, size) + +  def readSetEnd(self): +    pass + +  def readBool(self): +    byte = self.readByte() +    if byte == 0: +      return False +    return True + +  def readByte(self): +    buff = self.trans.readAll(1) +    val, = unpack('!b', buff) +    return val + +  def readI16(self): +    buff = self.trans.readAll(2) +    val, = unpack('!h', buff) +    return val + +  def readI32(self): +    buff = self.trans.readAll(4) +    val, = unpack('!i', buff) +    return val + +  def readI64(self): +    buff = self.trans.readAll(8) +    val, = unpack('!q', buff) +    return val + +  def readDouble(self): +    buff = self.trans.readAll(8) +    val, = unpack('!d', buff) +    return val + +  def readString(self): +    len = self.readI32() +    str = self.trans.readAll(len) +    return str + + +class TBinaryProtocolFactory: +  def __init__(self, strictRead=False, strictWrite=True): +    self.strictRead = strictRead +    self.strictWrite = strictWrite + +  def getProtocol(self, trans): +    prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite) +    return prot + + +class TBinaryProtocolAccelerated(TBinaryProtocol): + +  """C-Accelerated version of TBinaryProtocol. + +  This class does not override any of TBinaryProtocol's methods, +  but the generated code recognizes it directly and will call into +  our C module to do the encoding, bypassing this object entirely. +  We inherit from TBinaryProtocol so that the normal TBinaryProtocol +  encoding can happen if the fastbinary module doesn't work for some +  reason.  (TODO(dreiss): Make this happen sanely in more cases.) + +  In order to take advantage of the C module, just use +  TBinaryProtocolAccelerated instead of TBinaryProtocol. + +  NOTE:  This code was contributed by an external developer. +         The internal Thrift team has reviewed and tested it, +         but we cannot guarantee that it is production-ready. +         Please feel free to report bugs and/or success stories +         to the public mailing list. +  """ + +  pass + + +class TBinaryProtocolAcceleratedFactory: +  def getProtocol(self, trans): +    return TBinaryProtocolAccelerated(trans) diff --git a/lib/thrift/protocol/TCompactProtocol.py b/lib/thrift/protocol/TCompactProtocol.py new file mode 100644 index 000000000..016a33171 --- /dev/null +++ b/lib/thrift/protocol/TCompactProtocol.py @@ -0,0 +1,395 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +#   http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from TProtocol import * +from struct import pack, unpack + +__all__ = ['TCompactProtocol', 'TCompactProtocolFactory'] + +CLEAR = 0 +FIELD_WRITE = 1 +VALUE_WRITE = 2 +CONTAINER_WRITE = 3 +BOOL_WRITE = 4 +FIELD_READ = 5 +CONTAINER_READ = 6 +VALUE_READ = 7 +BOOL_READ = 8 + +def make_helper(v_from, container): +  def helper(func): +    def nested(self, *args, **kwargs): +      assert self.state in (v_from, container), (self.state, v_from, container) +      return func(self, *args, **kwargs) +    return nested +  return helper +writer = make_helper(VALUE_WRITE, CONTAINER_WRITE) +reader = make_helper(VALUE_READ, CONTAINER_READ) + +def makeZigZag(n, bits): +  return (n << 1) ^ (n >> (bits - 1)) + +def fromZigZag(n): +  return (n >> 1) ^ -(n & 1) + +def writeVarint(trans, n): +  out = [] +  while True: +    if n & ~0x7f == 0: +      out.append(n) +      break +    else: +      out.append((n & 0xff) | 0x80) +      n = n >> 7 +  trans.write(''.join(map(chr, out))) + +def readVarint(trans): +  result = 0 +  shift = 0 +  while True: +    x = trans.readAll(1) +    byte = ord(x) +    result |= (byte & 0x7f) << shift +    if byte >> 7 == 0: +      return result +    shift += 7 + +class CompactType: +  STOP = 0x00 +  TRUE = 0x01 +  FALSE = 0x02 +  BYTE = 0x03 +  I16 = 0x04 +  I32 = 0x05 +  I64 = 0x06 +  DOUBLE = 0x07 +  BINARY = 0x08 +  LIST = 0x09 +  SET = 0x0A +  MAP = 0x0B +  STRUCT = 0x0C + +CTYPES = {TType.STOP: CompactType.STOP, +          TType.BOOL: CompactType.TRUE, # used for collection +          TType.BYTE: CompactType.BYTE, +          TType.I16: CompactType.I16, +          TType.I32: CompactType.I32, +          TType.I64: CompactType.I64, +          TType.DOUBLE: CompactType.DOUBLE, +          TType.STRING: CompactType.BINARY, +          TType.STRUCT: CompactType.STRUCT, +          TType.LIST: CompactType.LIST, +          TType.SET: CompactType.SET, +          TType.MAP: CompactType.MAP +          } + +TTYPES = {} +for k, v in CTYPES.items(): +  TTYPES[v] = k +TTYPES[CompactType.FALSE] = TType.BOOL +del k +del v + +class TCompactProtocol(TProtocolBase): +  "Compact implementation of the Thrift protocol driver." + +  PROTOCOL_ID = 0x82 +  VERSION = 1 +  VERSION_MASK = 0x1f +  TYPE_MASK = 0xe0 +  TYPE_SHIFT_AMOUNT = 5 + +  def __init__(self, trans): +    TProtocolBase.__init__(self, trans) +    self.state = CLEAR +    self.__last_fid = 0 +    self.__bool_fid = None +    self.__bool_value = None +    self.__structs = [] +    self.__containers = [] + +  def __writeVarint(self, n): +    writeVarint(self.trans, n) + +  def writeMessageBegin(self, name, type, seqid): +    assert self.state == CLEAR +    self.__writeUByte(self.PROTOCOL_ID) +    self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT)) +    self.__writeVarint(seqid) +    self.__writeString(name) +    self.state = VALUE_WRITE + +  def writeMessageEnd(self): +    assert self.state == VALUE_WRITE +    self.state = CLEAR + +  def writeStructBegin(self, name): +    assert self.state in (CLEAR, CONTAINER_WRITE, VALUE_WRITE), self.state +    self.__structs.append((self.state, self.__last_fid)) +    self.state = FIELD_WRITE +    self.__last_fid = 0 + +  def writeStructEnd(self): +    assert self.state == FIELD_WRITE +    self.state, self.__last_fid = self.__structs.pop() + +  def writeFieldStop(self): +    self.__writeByte(0) + +  def __writeFieldHeader(self, type, fid): +    delta = fid - self.__last_fid +    if 0 < delta <= 15: +      self.__writeUByte(delta << 4 | type) +    else: +      self.__writeByte(type) +      self.__writeI16(fid) +    self.__last_fid = fid + +  def writeFieldBegin(self, name, type, fid): +    assert self.state == FIELD_WRITE, self.state +    if type == TType.BOOL: +      self.state = BOOL_WRITE +      self.__bool_fid = fid +    else: +      self.state = VALUE_WRITE +      self.__writeFieldHeader(CTYPES[type], fid) + +  def writeFieldEnd(self): +    assert self.state in (VALUE_WRITE, BOOL_WRITE), self.state +    self.state = FIELD_WRITE + +  def __writeUByte(self, byte): +    self.trans.write(pack('!B', byte)) + +  def __writeByte(self, byte): +    self.trans.write(pack('!b', byte)) + +  def __writeI16(self, i16): +    self.__writeVarint(makeZigZag(i16, 16)) + +  def __writeSize(self, i32): +    self.__writeVarint(i32) + +  def writeCollectionBegin(self, etype, size): +    assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state +    if size <= 14: +      self.__writeUByte(size << 4 | CTYPES[etype]) +    else: +      self.__writeUByte(0xf0 | CTYPES[etype]) +      self.__writeSize(size) +    self.__containers.append(self.state) +    self.state = CONTAINER_WRITE +  writeSetBegin = writeCollectionBegin +  writeListBegin = writeCollectionBegin + +  def writeMapBegin(self, ktype, vtype, size): +    assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state +    if size == 0: +      self.__writeByte(0) +    else: +      self.__writeSize(size) +      self.__writeUByte(CTYPES[ktype] << 4 | CTYPES[vtype]) +    self.__containers.append(self.state) +    self.state = CONTAINER_WRITE + +  def writeCollectionEnd(self): +    assert self.state == CONTAINER_WRITE, self.state +    self.state = self.__containers.pop() +  writeMapEnd = writeCollectionEnd +  writeSetEnd = writeCollectionEnd +  writeListEnd = writeCollectionEnd + +  def writeBool(self, bool): +    if self.state == BOOL_WRITE: +        if bool: +            ctype = CompactType.TRUE +        else: +            ctype = CompactType.FALSE +        self.__writeFieldHeader(ctype, self.__bool_fid) +    elif self.state == CONTAINER_WRITE: +       if bool: +           self.__writeByte(CompactType.TRUE) +       else: +           self.__writeByte(CompactType.FALSE) +    else: +      raise AssertionError, "Invalid state in compact protocol" + +  writeByte = writer(__writeByte) +  writeI16 = writer(__writeI16) + +  @writer +  def writeI32(self, i32): +    self.__writeVarint(makeZigZag(i32, 32)) + +  @writer +  def writeI64(self, i64): +    self.__writeVarint(makeZigZag(i64, 64)) + +  @writer +  def writeDouble(self, dub): +    self.trans.write(pack('!d', dub)) + +  def __writeString(self, s): +    self.__writeSize(len(s)) +    self.trans.write(s) +  writeString = writer(__writeString) + +  def readFieldBegin(self): +    assert self.state == FIELD_READ, self.state +    type = self.__readUByte() +    if type & 0x0f == TType.STOP: +      return (None, 0, 0) +    delta = type >> 4 +    if delta == 0: +      fid = self.__readI16() +    else: +      fid = self.__last_fid + delta +    self.__last_fid = fid +    type = type & 0x0f +    if type == CompactType.TRUE: +      self.state = BOOL_READ +      self.__bool_value = True +    elif type == CompactType.FALSE: +      self.state = BOOL_READ +      self.__bool_value = False +    else: +      self.state = VALUE_READ +    return (None, self.__getTType(type), fid) + +  def readFieldEnd(self): +    assert self.state in (VALUE_READ, BOOL_READ), self.state +    self.state = FIELD_READ + +  def __readUByte(self): +    result, = unpack('!B', self.trans.readAll(1)) +    return result + +  def __readByte(self): +    result, = unpack('!b', self.trans.readAll(1)) +    return result + +  def __readVarint(self): +    return readVarint(self.trans) + +  def __readZigZag(self): +    return fromZigZag(self.__readVarint()) + +  def __readSize(self): +    result = self.__readVarint() +    if result < 0: +      raise TException("Length < 0") +    return result + +  def readMessageBegin(self): +    assert self.state == CLEAR +    proto_id = self.__readUByte() +    if proto_id != self.PROTOCOL_ID: +      raise TProtocolException(TProtocolException.BAD_VERSION, +          'Bad protocol id in the message: %d' % proto_id) +    ver_type = self.__readUByte() +    type = (ver_type & self.TYPE_MASK) >> self.TYPE_SHIFT_AMOUNT +    version = ver_type & self.VERSION_MASK +    if version != self.VERSION: +      raise TProtocolException(TProtocolException.BAD_VERSION, +          'Bad version: %d (expect %d)' % (version, self.VERSION)) +    seqid = self.__readVarint() +    name = self.__readString() +    return (name, type, seqid) + +  def readMessageEnd(self): +    assert self.state == CLEAR +    assert len(self.__structs) == 0 + +  def readStructBegin(self): +    assert self.state in (CLEAR, CONTAINER_READ, VALUE_READ), self.state +    self.__structs.append((self.state, self.__last_fid)) +    self.state = FIELD_READ +    self.__last_fid = 0 + +  def readStructEnd(self): +    assert self.state == FIELD_READ +    self.state, self.__last_fid = self.__structs.pop() + +  def readCollectionBegin(self): +    assert self.state in (VALUE_READ, CONTAINER_READ), self.state +    size_type = self.__readUByte() +    size = size_type >> 4 +    type = self.__getTType(size_type) +    if size == 15: +      size = self.__readSize() +    self.__containers.append(self.state) +    self.state = CONTAINER_READ +    return type, size +  readSetBegin = readCollectionBegin +  readListBegin = readCollectionBegin + +  def readMapBegin(self): +    assert self.state in (VALUE_READ, CONTAINER_READ), self.state +    size = self.__readSize() +    types = 0 +    if size > 0: +      types = self.__readUByte() +    vtype = self.__getTType(types) +    ktype = self.__getTType(types >> 4) +    self.__containers.append(self.state) +    self.state = CONTAINER_READ +    return (ktype, vtype, size) + +  def readCollectionEnd(self): +    assert self.state == CONTAINER_READ, self.state +    self.state = self.__containers.pop() +  readSetEnd = readCollectionEnd +  readListEnd = readCollectionEnd +  readMapEnd = readCollectionEnd + +  def readBool(self): +    if self.state == BOOL_READ: +      return self.__bool_value == CompactType.TRUE +    elif self.state == CONTAINER_READ: +      return self.__readByte() == CompactType.TRUE +    else: +      raise AssertionError, "Invalid state in compact protocol: %d" % self.state + +  readByte = reader(__readByte) +  __readI16 = __readZigZag +  readI16 = reader(__readZigZag) +  readI32 = reader(__readZigZag) +  readI64 = reader(__readZigZag) + +  @reader +  def readDouble(self): +    buff = self.trans.readAll(8) +    val, = unpack('!d', buff) +    return val + +  def __readString(self): +    len = self.__readSize() +    return self.trans.readAll(len) +  readString = reader(__readString) + +  def __getTType(self, byte): +    return TTYPES[byte & 0x0f] + + +class TCompactProtocolFactory: +  def __init__(self): +    pass + +  def getProtocol(self, trans): +    return TCompactProtocol(trans) diff --git a/lib/thrift/protocol/TProtocol.py b/lib/thrift/protocol/TProtocol.py new file mode 100644 index 000000000..7338ff68a --- /dev/null +++ b/lib/thrift/protocol/TProtocol.py @@ -0,0 +1,404 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +#   http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from thrift.Thrift import * + +class TProtocolException(TException): + +  """Custom Protocol Exception class""" + +  UNKNOWN = 0 +  INVALID_DATA = 1 +  NEGATIVE_SIZE = 2 +  SIZE_LIMIT = 3 +  BAD_VERSION = 4 + +  def __init__(self, type=UNKNOWN, message=None): +    TException.__init__(self, message) +    self.type = type + +class TProtocolBase: + +  """Base class for Thrift protocol driver.""" + +  def __init__(self, trans): +    self.trans = trans + +  def writeMessageBegin(self, name, type, seqid): +    pass + +  def writeMessageEnd(self): +    pass + +  def writeStructBegin(self, name): +    pass + +  def writeStructEnd(self): +    pass + +  def writeFieldBegin(self, name, type, id): +    pass + +  def writeFieldEnd(self): +    pass + +  def writeFieldStop(self): +    pass + +  def writeMapBegin(self, ktype, vtype, size): +    pass + +  def writeMapEnd(self): +    pass + +  def writeListBegin(self, etype, size): +    pass + +  def writeListEnd(self): +    pass + +  def writeSetBegin(self, etype, size): +    pass + +  def writeSetEnd(self): +    pass + +  def writeBool(self, bool): +    pass + +  def writeByte(self, byte): +    pass + +  def writeI16(self, i16): +    pass + +  def writeI32(self, i32): +    pass + +  def writeI64(self, i64): +    pass + +  def writeDouble(self, dub): +    pass + +  def writeString(self, str): +    pass + +  def readMessageBegin(self): +    pass + +  def readMessageEnd(self): +    pass + +  def readStructBegin(self): +    pass + +  def readStructEnd(self): +    pass + +  def readFieldBegin(self): +    pass + +  def readFieldEnd(self): +    pass + +  def readMapBegin(self): +    pass + +  def readMapEnd(self): +    pass + +  def readListBegin(self): +    pass + +  def readListEnd(self): +    pass + +  def readSetBegin(self): +    pass + +  def readSetEnd(self): +    pass + +  def readBool(self): +    pass + +  def readByte(self): +    pass + +  def readI16(self): +    pass + +  def readI32(self): +    pass + +  def readI64(self): +    pass + +  def readDouble(self): +    pass + +  def readString(self): +    pass + +  def skip(self, type): +    if type == TType.STOP: +      return +    elif type == TType.BOOL: +      self.readBool() +    elif type == TType.BYTE: +      self.readByte() +    elif type == TType.I16: +      self.readI16() +    elif type == TType.I32: +      self.readI32() +    elif type == TType.I64: +      self.readI64() +    elif type == TType.DOUBLE: +      self.readDouble() +    elif type == TType.STRING: +      self.readString() +    elif type == TType.STRUCT: +      name = self.readStructBegin() +      while True: +        (name, type, id) = self.readFieldBegin() +        if type == TType.STOP: +          break +        self.skip(type) +        self.readFieldEnd() +      self.readStructEnd() +    elif type == TType.MAP: +      (ktype, vtype, size) = self.readMapBegin() +      for i in range(size): +        self.skip(ktype) +        self.skip(vtype) +      self.readMapEnd() +    elif type == TType.SET: +      (etype, size) = self.readSetBegin() +      for i in range(size): +        self.skip(etype) +      self.readSetEnd() +    elif type == TType.LIST: +      (etype, size) = self.readListBegin() +      for i in range(size): +        self.skip(etype) +      self.readListEnd() + +  # tuple of: ( 'reader method' name, is_container boolean, 'writer_method' name ) +  _TTYPE_HANDLERS = ( +       (None, None, False), # 0 == TType,STOP +       (None, None, False), # 1 == TType.VOID # TODO: handle void? +       ('readBool', 'writeBool', False), # 2 == TType.BOOL +       ('readByte',  'writeByte', False), # 3 == TType.BYTE and I08 +       ('readDouble', 'writeDouble', False), # 4 == TType.DOUBLE +       (None, None, False), # 5, undefined +       ('readI16', 'writeI16', False), # 6 == TType.I16 +       (None, None, False), # 7, undefined +       ('readI32', 'writeI32', False), # 8 == TType.I32 +       (None, None, False), # 9, undefined +       ('readI64', 'writeI64', False), # 10 == TType.I64 +       ('readString', 'writeString', False), # 11 == TType.STRING and UTF7 +       ('readContainerStruct', 'writeContainerStruct', True), # 12 == TType.STRUCT +       ('readContainerMap', 'writeContainerMap', True), # 13 == TType.MAP +       ('readContainerSet', 'writeContainerSet', True), # 14 == TType.SET +       ('readContainerList', 'writeContainerList', True), # 15 == TType.LIST +       (None, None, False), # 16 == TType.UTF8 # TODO: handle utf8 types? +       (None, None, False)# 17 == TType.UTF16 # TODO: handle utf16 types? +      ) + +  def readFieldByTType(self, ttype, spec): +    try: +      (r_handler, w_handler, is_container) = self._TTYPE_HANDLERS[ttype] +    except IndexError: +      raise TProtocolException(type=TProtocolException.INVALID_DATA, +                               message='Invalid field type %d' % (ttype)) +    if r_handler is None: +      raise TProtocolException(type=TProtocolException.INVALID_DATA, +                               message='Invalid field type %d' % (ttype)) +    reader = getattr(self, r_handler) +    if not is_container: +      return reader() +    return reader(spec) + +  def readContainerList(self, spec): +    results = [] +    ttype, tspec = spec[0], spec[1] +    r_handler = self._TTYPE_HANDLERS[ttype][0] +    reader = getattr(self, r_handler) +    (list_type, list_len) = self.readListBegin() +    if tspec is None: +      # list values are simple types +      for idx in xrange(list_len): +        results.append(reader()) +    else: +      # this is like an inlined readFieldByTType +      container_reader = self._TTYPE_HANDLERS[list_type][0] +      val_reader = getattr(self, container_reader) +      for idx in xrange(list_len): +        val = val_reader(tspec) +        results.append(val) +    self.readListEnd() +    return results + +  def readContainerSet(self, spec): +    results = set() +    ttype, tspec = spec[0], spec[1] +    r_handler = self._TTYPE_HANDLERS[ttype][0] +    reader = getattr(self, r_handler) +    (set_type, set_len) = self.readSetBegin() +    if tspec is None: +      # set members are simple types +      for idx in xrange(set_len): +        results.add(reader()) +    else: +      container_reader = self._TTYPE_HANDLERS[set_type][0] +      val_reader = getattr(self, container_reader) +      for idx in xrange(set_len): +        results.add(val_reader(tspec))  +    self.readSetEnd() +    return results + +  def readContainerStruct(self, spec): +    (obj_class, obj_spec) = spec +    obj = obj_class() +    obj.read(self) +    return obj +   +  def readContainerMap(self, spec): +    results = dict() +    key_ttype, key_spec = spec[0], spec[1] +    val_ttype, val_spec = spec[2], spec[3] +    (map_ktype, map_vtype, map_len) = self.readMapBegin() +    # TODO: compare types we just decoded with thrift_spec and abort/skip if types disagree +    key_reader = getattr(self, self._TTYPE_HANDLERS[key_ttype][0]) +    val_reader = getattr(self, self._TTYPE_HANDLERS[val_ttype][0]) +    # list values are simple types +    for idx in xrange(map_len): +      if key_spec is None: +        k_val = key_reader() +      else: +        k_val = self.readFieldByTType(key_ttype, key_spec) +      if val_spec is None: +        v_val = val_reader() +      else: +        v_val = self.readFieldByTType(val_ttype, val_spec) +      # this raises a TypeError with unhashable keys types. i.e. d=dict(); d[[0,1]] = 2 fails +      results[k_val] = v_val +    self.readMapEnd() +    return results + +  def readStruct(self, obj, thrift_spec): +    self.readStructBegin() +    while True: +      (fname, ftype, fid) = self.readFieldBegin() +      if ftype == TType.STOP: +        break +      try: +        field = thrift_spec[fid] +      except IndexError: +        self.skip(ftype) +      else: +        if field is not None and ftype == field[1]: +          fname = field[2] +          fspec = field[3] +          val = self.readFieldByTType(ftype, fspec) +          setattr(obj, fname, val) +        else: +          self.skip(ftype) +      self.readFieldEnd() +    self.readStructEnd() + +  def writeContainerStruct(self, val, spec): +    val.write(self) + +  def writeContainerList(self, val, spec): +    self.writeListBegin(spec[0], len(val)) +    r_handler, w_handler, is_container  = self._TTYPE_HANDLERS[spec[0]] +    e_writer = getattr(self, w_handler) +    if not is_container: +      for elem in val: +        e_writer(elem) +    else: +      for elem in val: +        e_writer(elem, spec[1]) +    self.writeListEnd() + +  def writeContainerSet(self, val, spec): +    self.writeSetBegin(spec[0], len(val)) +    r_handler, w_handler, is_container = self._TTYPE_HANDLERS[spec[0]] +    e_writer = getattr(self, w_handler) +    if not is_container: +      for elem in val: +        e_writer(elem) +    else: +      for elem in val: +        e_writer(elem, spec[1]) +    self.writeSetEnd() + +  def writeContainerMap(self, val, spec): +    k_type = spec[0] +    v_type = spec[2] +    ignore, ktype_name, k_is_container = self._TTYPE_HANDLERS[k_type] +    ignore, vtype_name, v_is_container = self._TTYPE_HANDLERS[v_type] +    k_writer = getattr(self, ktype_name) +    v_writer = getattr(self, vtype_name) +    self.writeMapBegin(k_type, v_type, len(val)) +    for m_key, m_val in val.iteritems(): +      if not k_is_container: +        k_writer(m_key) +      else: +        k_writer(m_key, spec[1]) +      if not v_is_container: +        v_writer(m_val) +      else: +        v_writer(m_val, spec[3]) +    self.writeMapEnd() + +  def writeStruct(self, obj, thrift_spec): +    self.writeStructBegin(obj.__class__.__name__) +    for field in thrift_spec: +      if field is None: +        continue +      fname = field[2] +      val = getattr(obj, fname) +      if val is None: +        # skip writing out unset fields +        continue +      fid = field[0] +      ftype = field[1] +      fspec = field[3] +      # get the writer method for this value +      self.writeFieldBegin(fname, ftype, fid) +      self.writeFieldByTType(ftype, val, fspec) +      self.writeFieldEnd() +    self.writeFieldStop() +    self.writeStructEnd() + +  def writeFieldByTType(self, ttype, val, spec): +    r_handler, w_handler, is_container = self._TTYPE_HANDLERS[ttype] +    writer = getattr(self, w_handler) +    if is_container: +      writer(val, spec) +    else: +      writer(val) + +class TProtocolFactory: +  def getProtocol(self, trans): +    pass + diff --git a/lib/thrift/protocol/__init__.py b/lib/thrift/protocol/__init__.py new file mode 100644 index 000000000..d53359b28 --- /dev/null +++ b/lib/thrift/protocol/__init__.py @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +#   http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +__all__ = ['TProtocol', 'TBinaryProtocol', 'fastbinary', 'TBase']  | 
