"""
Copyright (C) 2007 Adolfo González Blázquez <code@infinicode.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
If you find any bugs or have any suggestions email: code@infinicode.org
"""
import struct
class Message:
def __init__(self):
NATIVE = '@'
BIG_ENDIAN = '>'
LITTLE_ENDIAN = '<'
NETWORK = '!'
self._order = LITTLE_ENDIAN
self.size = 0
self.code = 0
self.data = ''
def get_name(self):
values = {
0: "CoreProtocol",
1: "OptionsInfo",
3: "DefineSearches",
4: "ResultInfo",
5: "SearchResult",
9: "FileUpdateAvailability",
10: "FileAddSource",
12: "ServerUser",
13: "ServerState",
15: "ClientInfo",
16: "ClientState",
19: "ConsoleMessage",
20: "NetworkInfo",
21: "UserInfo",
22: "RoomInfo",
23: "RoomMessage",
24: "RoomAddUser",
26: "ServerInfo",
27: "MessageFromClient",
28: "ConnectedServers",
31: "RoomInfo",
34: "SharedFileUpload",
35: "SharedFileUnshared",
36: "AddSectionOption",
38: "AddPluginOption",
46: "FileDownloadUpdate",
47: "BadPassword",
33: "SharedFileInfo",
48: "SharedFileInfo",
25: "ClientStats",
37: "ClientStats",
39: "ClientStats",
49: "ClientStats",
50: "FileRemoveSource",
51: "CleanTables",
7: "FileInfo",
40: "FileInfo",
43: "FileInfo",
52: "FileInfo",
29: "DownloadingFiles",
41: "DownloadingFiles",
44: "DownloadingFiles",
53: "DownloadingFiles",
30: "DownloadingFiles",
42: "DownloadingFiles",
45: "DownloadingFiles",
54: "DownloadedFiles",
55: "Uploaders",
56: "Pending",
57: "Search",
58: "Version"
}
if self.code in values:
return values[self.code]
else:
return "Unknown"
class MessageSender(Message):
def __init__(self, socket, code):
Message.__init__(self)
self.size = 2
self.code = code
self.data = ''
self.socket = socket
def send(self):
size = struct.pack(self._order+'i', self.size)
code = struct.pack(self._order+'h', self.code)
self.socket.send(size + code + self.data)
def int8(self, value):
self.size += 1
self.data += struct.pack('b', value)
def uint8(self, value):
self.size += 1
self.data += struct.pack('B', value)
def int16(self, value):
self.size += 2
self.data += struct.pack(self._order+'h', value)
def uint16(self, value):
self.size += 2
self.data += struct.pack(self._order+'H', value)
def int32(self, value):
self.size += 4
self.data += struct.pack(self._order+'i', value)
def uint32(self, value):
self.size += 4
self.data += struct.pack(self._order+'I', value)
def int64(self, value):
self.size += 8
self.data += struct.pack(self._order+'q', value)
def uint64(self, value):
self.size += 8
self.data += struct.pack(self._order+'Q', value)
def char(self, value):
self.size += 1
self.data += struct.pack(self._order+'c', value)
def string(self, value):
length = len(value)
self.int16(length)
for i in range(length):
self.char(value[i])
class MessageReader(Message):
def __init__(self, socket):
Message.__init__(self)
self.socket = socket
self.index = 0
self.read_size()
self.read_code()
if self.size - 2 > 0:
self.read_data()
def read_random(self, size):
return self.socket.recv(size)
def read_data(self):
self.data = self.socket.recv(self.size - 2)
def read_size(self):
self.size = struct.unpack(self._order+'i', self.socket.recv(4))[0]
def read_code(self):
self.code = struct.unpack(self._order+'h', self.socket.recv(2))[0]
def int8(self):
data = struct.unpack('b', self.data[self.index:self.index+1])[0]
self.index += 1
return data
def uint8(self):
data = struct.unpack('B', self.data[self.index:self.index+1])[0]
self.index += 1
return data
def int16(self):
data = struct.unpack(self._order+'h', self.data[self.index:self.index+2])[0]
self.index += 2
return data
def uint16(self):
data = struct.unpack(self._order+'H', self.data[self.index:self.index+2])[0]
self.index += 2
return data
def int32(self):
data = struct.unpack(self._order+'i', self.data[self.index:self.index+4])[0]
self.index += 4
return data
def uint32(self):
data = struct.unpack(self._order+'I', self.data[self.index:self.index+4])[0]
self.index += 4
return data
def int64(self):
data = struct.unpack(self._order+'q', self.data[self.index:self.index+8])[0]
self.index += 8
return data
def uint64(self):
data = struct.unpack(self._order+'Q', self.data[self.index:self.index+8])[0]
self.index += 8
return data
def float(self):
length = self.int16()
data = ''
for i in range(length):
data += self.char()
return data
def char(self):
data = struct.unpack('c', self.data[self.index:self.index+1])[0]
self.index += 1
return data
def chararray(self, size):
val = ''
for i in range(size):
val += self.char()
return val
def string(self):
s = ''
length = self.int16()
for i in range(length):
s += self.char()
return s
"""
def list(self, type1, type2=None):
length = self.int16()
l = []
print "list of", length
for i in range(length):
v1 = getattr(self, type1)()
if type2 != None:
v2 = getattr(self, type2)()
l.append([v1,v2])
else:
l.append(v1)
return l
"""
def list(self, elems):
length = self.int16()
print " List of", length, "with", elems
l = []
if not isinstance(elems, list):
for i in range(length):
v = getattr(self, elems)()
l.append(v)
else:
for i in range(length):
ll = []
for t in range(len(elems)):
v = getattr(self, elems[t])()
ll.append(v)
l.append(l)
return l