class Connection(object): def __init__(self, socket): self.socket = socket self.decoder = ErlangTermDecoder() self.encoder = ErlangTermEncoder() def send_packet4(self, msg): msg = struct.pack('>L', len(msg)) + msg berp_len = 4 + len(msg) self.socket.sendall(msg) def recv_packet4(self): # print 'recv_packet4 0' data = self.socket.recv(4) if data == '': raise IOError('Connection closed') # print 'recv_packet4 1', data msg_size, = struct.unpack('>L', data) if msg_size == 0: return None # print 'recv_packet4 2', msg_size msg = [] received = 0 while received < msg_size: left = msg_size - received if left > 4096: data = self.socket.recv(4096) else: data = self.socket.recv(left) if len(data) == 0: raise IOError('Connection closed') msg.append(data) received += len(data) msg = b''.join(msg) # print 'recv_packet4 3', repr(msg), ord(msg[0]) return (msg_size, msg) def call(self, module, function, args=[]): msg = self.encoder.encode((Atom('call'), Atom(module), Atom(function), args)) # print "Send ", repr(msg) self.send_packet4(msg) size, data = self.recv_packet4() msg = self.decoder.decode(data) return msg[1] def cast(self, module, function, args=[]): msg = self.encoder.encode((Atom('cast'), Atom(module), Atom(function), args)) self.send_packet4(msg) def info(self, command, options): msg = self.encoder.encode((Atom('info'), Atom(command), options)) self.send_packet4(msg)
class BERTDecoder(object): def __init__(self, encoding="utf-8"): self.encoding = encoding self.erlang_decoder = ErlangTermDecoder() def decode(self, bytes, offset=0): obj = self.erlang_decoder.decode(bytes, offset) return self.convert(obj) def convert(self, item): if isinstance(item, tuple): if item and item[0] == "bert": return self.convert_bert(item) return tuple(self.convert(i) for i in item) elif isinstance(item, list): if item and item[0] == "bert": return self.convert_bert(item) return [self.convert(i) for i in item] return item def convert_bert(self, item): bert_type = item[1] if bert_type == "nil": return None elif bert_type == "string": return item[3].decode(Atom(item[2])) elif bert_type == "dict": return dict((self.convert(k), self.convert(v)) for k, v in item[2]) elif bert_type in ("true", True): return True elif bert_type in ("false", False): return False elif bert_type == "time": return utc_to_datetime(item[2] * 1000000 + item[3], item[4]) elif bert_type == "regex": flags = 0 if 'extended' in item[3]: flags |= re.VERBOSE if 'caseless' in item[3]: flags |= re.IGNORECASE if 'multiline' in item[3]: flags |= re.MULTILINE if 'dotall' in item[3]: flags |= re.DOTALL return re.compile(item[2], flags) raise NotImplementedError("Unknown BERT type %s" % item[1])
def __init__(self, encoding="utf-8"): self.encoding = encoding self.erlang_decoder = ErlangTermDecoder()
def __init__(self, socket): self.socket = socket self.decoder = ErlangTermDecoder() self.encoder = ErlangTermEncoder()