def _deserialize(string): """ Converts a string to a readable packet Args: string: a serialized packet (in a string form) Returns: The deserialized packet. Raises: PacketException: If the packet header is corrupt, a PacketException will be raised. """ # Read the packet header (packetType, _comma, tail) = string.partition(",") try : packetType = int(packetType) # Check if the packet type has an invalid value. If so, an exception will be raised. Packet_TYPE.reverse_mapping[packetType] except Exception : raise PacketException("Invalid packet string: Unknown packet type") (priority, _comma, tail) = tail.partition(",") try : priority = int(priority) except Exception : raise PacketException("Invalid packet string: packet priority must be an integer") # Create the packet p = _Packet(packetType, priority) p._setData(tail) # Return the readable packet return p
def __commonReadCode(self, typeLabel, returnType): """ Code shared by all read operations Args: typeLabel: The type label (i.e. int for integer values, string for strings, and so on) returnType: The value type to return (i.e. str for strings, int for integers, and so on). Returns: A value read from the packet. Raises: PacketException: this exceptions will be raised when the packet's current value does not match with the type label and when the packet value and the type label do not match. """ (label, _dot, tail) = self.__data.partition("·") if (typeLabel != label): raise PacketException("Can't read a " + self.__extractTypeName(returnType) + " value") (value, _dot, tail) = tail.partition("·") try: returnValue = returnType(value) except Exception: raise PacketException( "Invalid packet string: label and data types do not match") # Everything went OK => discard the read data self.__data = tail # Return the read value return returnValue
def __commonWriteCode(self, value, dataType, field, checkType): """ Code shared by all write operations Args: value: the value to write into the packet dataType: the expected value datatype (i.e. integer, boolean, float,...) field: the label to use in the data string checkType: when True, the value's data type will be checked. When False, the value will be written directly into the data string. Returns: Nothing Raises: PacketException: these exceptions will be raised when type errors are detected and when the packet has not enough room to hold the value. """ if checkType and not isinstance(value, dataType): raise PacketException("The given value is not an " + self.__extractTypeName(str(dataType)) + " instance") dataToAdd = str(value) newLength = len(self.__data) + len(field) + len(dataToAdd) + 2 if (newLength > 65000): # The maximum TCP segment length is 65536 bytes. 536 bytes are reserved for the packet header. raise PacketException("There\'s not enough space to hold a " + self.__extractTypeName(str(dataType))\ + " value") self.__data += field + '·' + dataToAdd + '·'
def writeString(self, value): """ Writes a string into the packet Args: value: a string Raises: PacketException: these exceptions will be raised when type errors are detected and when the packet has not enough room to hold the value. """ if not (isinstance(value, str) or isinstance(value, unicode)): raise PacketException("The given value is not an " + self.__extractTypeName(str) + " instance") if '$' in value : raise PacketException('Strings cannot contain the \'$\' character') self.__commonWriteCode(value, str, _DATA_TYPE.STRING, False)
def writeBool(self, value): """ Writes a boolean value into the packet. Args: value: a bool value Raises: PacketException: these exceptions will be raised when type errors are detected and when the packet has not enough room to hold the value. """ if not isinstance(value, bool) : raise PacketException("The given value is not a " + self.__extractTypeName(str(bool)) + " instance") if (value) : self.writeInt(1) else : self.writeInt(0)