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 BERTEncoder(object): def __init__(self, encoding="utf-8"): self.encoding = encoding self.erlang_encoder = ErlangTermEncoder() def encode(self, obj): bert = self.convert(obj) return self.erlang_encoder.encode(bert) def convert(self, obj): if obj is True: return (Atom("bert"), Atom("true")) elif obj is False: return (Atom("bert"), Atom("false")) elif obj is None: return (Atom("bert"), Atom("nil")) elif isinstance(obj, basestring) and not self.__is_ascii(obj): return (Atom("bert"), Atom("string"), Atom(self.encoding.upper()), obj.encode(self.encoding)) elif isinstance(obj, dict): return (Atom("bert"), Atom("dict"), [ (self.convert(k), self.convert(v)) for k, v in obj.items() ]) elif isinstance(obj, datetime.datetime): seconds, microseconds = datetime_to_utc(obj) megaseconds = seconds // 1000000 seconds = seconds % 1000000 return (Atom("bert"), Atom("time"), megaseconds, seconds, microseconds) elif isinstance(obj, list): return [self.convert(item) for item in obj] elif isinstance(obj, tuple): return tuple(self.convert(item) for item in obj) elif type(obj) == RE_TYPE: options = [] if obj.flags & re.VERBOSE: options.append(Atom('extended')) if obj.flags & re.IGNORECASE: options.append(Atom('caseless')) if obj.flags & re.MULTILINE: options.append(Atom('multiline')) if obj.flags & re.DOTALL: options.append(Atom('dotall')) return (Atom("bert"), Atom("regex"), obj.pattern, tuple(options)) return obj def __is_ascii(self, s): return all(ord(c) < 128 for c in s)
class BERTEncoder(object): def __init__(self, encoding="utf-8"): self.encoding = encoding self.erlang_encoder = ErlangTermEncoder() def encode(self, obj): bert = self.convert(obj) return self.erlang_encoder.encode(bert) def convert(self, obj): if obj is True: return (Atom("bert"), Atom("true")) elif obj is False: return (Atom("bert"), Atom("false")) elif obj is None: return (Atom("bert"), Atom("nil")) elif isinstance(obj, basestring) and not self.__is_ascii(obj): return (Atom("bert"), Atom("string"), Atom(self.encoding.upper()), obj.encode(self.encoding)) elif isinstance(obj, dict): return (Atom("bert"), Atom("dict"), [(self.convert(k), self.convert(v)) for k, v in obj.items()]) elif isinstance(obj, datetime.datetime): seconds, microseconds = datetime_to_utc(obj) megaseconds = seconds // 1000000 seconds = seconds % 1000000 return (Atom("bert"), Atom("time"), megaseconds, seconds, microseconds) elif isinstance(obj, list): return [self.convert(item) for item in obj] elif isinstance(obj, tuple): return tuple(self.convert(item) for item in obj) elif type(obj) == RE_TYPE: options = [] if obj.flags & re.VERBOSE: options.append(Atom('extended')) if obj.flags & re.IGNORECASE: options.append(Atom('caseless')) if obj.flags & re.MULTILINE: options.append(Atom('multiline')) if obj.flags & re.DOTALL: options.append(Atom('dotall')) return (Atom("bert"), Atom("regex"), obj.pattern, tuple(options)) return obj def __is_ascii(self, s): return all(ord(c) < 128 for c in s)
def __init__(self, encoding="utf-8"): self.encoding = encoding self.erlang_encoder = ErlangTermEncoder()
def __init__(self, socket): self.socket = socket self.decoder = ErlangTermDecoder() self.encoder = ErlangTermEncoder()