3
# Drizzle Client & Protocol Library
5
# Copyright (C) 2008 Eric Day (eday@oddments.org)
8
# Use and distribution licensed under the BSD license. See
9
# the COPYING.BSD file in the root source directory for full text.
12
MySQL Protocol Packet Objects
18
class PacketException(Exception):
22
'''This class represents a packet header.'''
24
def __init__(self, packed=None, size=0, sequence=0):
27
self.sequence = sequence
29
data = struct.unpack('4B', packed)
30
self.size = data[0] | (data[1] << 8) | (data[2] << 16)
31
self.sequence = data[3]
37
return struct.pack('4B',
39
(self.size >> 8) & 0xFF,
40
(self.size >> 16) & 0xFF,
44
if self.size >= 16777216:
45
raise PacketException('Packet size cannot exceed 16777215 bytes (%d)' %
52
''' % (self.size, self.sequence)
54
class TestPacket(unittest.TestCase):
56
def testDefaultInit(self):
58
self.assertEqual(packet.size, 0)
59
self.assertEqual(packet.sequence, 0)
62
def testKeywordInit(self):
63
packet = Packet(size=1234, sequence=5)
64
self.assertEqual(packet.size, 1234)
65
self.assertEqual(packet.sequence, 5)
68
def testUnpackInit(self):
69
packet = Packet(struct.pack('4B', 210, 4, 0, 5))
70
self.assertEqual(packet.size, 1234)
71
self.assertEqual(packet.sequence, 5)
74
packet = Packet(Packet(size=1234, sequence=5).pack())
75
self.assertEqual(packet.size, 1234)
77
def testPackRange(self):
78
for x in range(0, 300):
79
packet = Packet(Packet(size=x, sequence=x).pack())
80
self.assertEqual(packet.size, x)
81
self.assertEqual(packet.sequence, x % 256)
83
# 997 is a random prime number so we hit various increments
84
for x in range(300, 16777216, 997):
85
packet = Packet(Packet(size=x, sequence=x).pack())
86
self.assertEqual(packet.size, x)
87
self.assertEqual(packet.sequence, x % 256)
89
packet = Packet(Packet(size=16777215).pack())
90
self.assertEqual(packet.size, 16777215)
91
self.assertEqual(packet.sequence, 0)
93
self.assertRaises(PacketException, Packet, size=16777216)
94
self.assertRaises(PacketException, Packet, size=16777217)
95
self.assertRaises(PacketException, Packet, size=4294967295)
96
self.assertRaises(PacketException, Packet, size=4294967296)
97
self.assertRaises(PacketException, Packet, size=4294967297)
99
def parse_row(count, data):
103
if ord(data[0]) == 251:
107
(size, packed_size) = parse_encoded_size(data)
108
row.append(data[packed_size:packed_size+size])
109
data = data[packed_size+size:]
112
class BadSize(Exception):
115
def parse_encoded_size(data):
119
size = struct.unpack('<H', data[1:3])[0]
122
data = struct.unpack('<HB', data[1:4])
123
size = data[0] | (data[1] << 16)
126
data = struct.unpack('<II', data[1:9])
127
size = data[0] | (data[1] << 32)
130
raise BadSize(str(size))
132
return (size, packed_size)
134
if __name__ == '__main__':