def __new__(cls, name, parents, dict): for attr in cls.REQUIRED_ATTRIBUTES: if attr not in dict: raise AttributeError("Missing required attribute %s" % attr) if cls.ENCODER_ATTRIBUTE not in dict: defaultEncoder = cls.getInheritedAttr(parents, cls.ENCODER_ATTRIBUTE, DefaultPacketEncoder) dict[cls.ENCODER_ATTRIBUTE] = defaultEncoder if cls.SILO_NAME not in dict: siloName = cls.getInheritedAttr(parents, cls.SILO_NAME, "__current_silo__") dict[cls.SILO_NAME] = siloName identifier = dict[cls.IDENTIFIER_ATTRIBUTE] version = PacketDefinitionVersion.FromString( dict[cls.VERSION_ATTRIBUTE]) packetStore = PacketDefinitionSilo.GetSiloByName(siloName) dict[cls.DEFINITIONS_STORE] = packetStore if not cls.PermitDuplicateRegistrations and packetStore.hasDefinition( identifier, version): raise ValueError( "Duplicate registration {} v {}. Existing version is {}". format(identifier, version, packetStore.getDefinition(identifier, version))) definitionCls = super().__new__(cls, name, parents, dict) packetStore.registerDefinition(identifier, version, definitionCls) return definitionCls
def decodeIterator(self, stream, complexType, topEncoder): packetStartPosition = stream.tell() packetLength = yield from stream.unpackIterator("!Q") packetLengthCompare = yield from stream.unpackIterator("!Q") packetLengthCompare ^= 0xFFFFFFFFFFFFFFFF if packetLength != packetLengthCompare: raise Exception("Packet Length Mismatch {}!={}".format( packetLength, packetLengthCompare)) stream.set_max_size(packetLength) nameLen = yield from stream.unpackIterator("!B") name = yield from stream.unpackIterator("!{}s".format(nameLen)) name = name.decode(UNICODE_ENCODING) versionLen = yield from stream.unpackIterator("!B") version = yield from stream.unpackIterator("!{}s".format(versionLen)) version = version.decode(UNICODE_ENCODING) version = PacketDefinitionVersion.FromString(version) basePacketType = complexType.dataType() packetDefinitions = basePacketType.DEFINITIONS_STORE packetType = packetDefinitions.getDefinition(name, version) if not packetType: # uh oh. We don't have the definition of this packet. # The encoder assumes an underlying "reliable" stream # so this should mean a misnamed packet, or a packet for # which we do not have a definition. So, we're going to skip # ahead until we can find something. pass # Do nothing. Let unreadBytes cleanup. TODO: logging/error else: packet = packetType() complexType.setData(packet) yield from PacketFieldsEncoder().decodeIterator( stream, complexType, topEncoder) bytesUsed = stream.tell() - packetStartPosition unreadBytes = packetLength - bytesUsed if unreadBytes: # uh oh. We have a mismatch between bytes read expected and actual. # read the remaining bytes. stream.read(unreadBytes) # raise an exception so that other parts of the system can identify # that we lost a packet. We've advanced the stream, so the system # should be able to pick up where it left off. raise Exception( "Packet deserialization error. Packet Type={}, Expected Size={}, Actual Size={}" .format(packetType, packetLength, bytesUsed)) if not packetType: # We didn't have unused bytes, but we didn't have a packetType. Still an error raise Exception( "Packet deserialization error. Packet Type={}".format( packetType))
def decodeIterator(self, stream, complexType, topEncoder): nameLen = yield from stream.unpackIterator("!B") name = yield from stream.unpackIterator("!{}s".format(nameLen)) name = name.decode(UNICODE_ENCODING) versionLen = yield from stream.unpackIterator("!B") version = yield from stream.unpackIterator("!{}s".format(versionLen)) version = version.decode(UNICODE_ENCODING) version = PacketDefinitionVersion.FromString(version) basePacketType = complexType.dataType() packetDefinitions = basePacketType.DEFINITIONS_STORE packetType = packetDefinitions.getDefinition(name, version) packet = packetType() complexType.setData(packet) yield from PacketFieldsEncoder().decodeIterator(stream, complexType, topEncoder)
def __new__(cls, name, parents, dict): for attr in cls.REQUIRED_ATTRIBUTES: if attr not in dict: raise AttributeError("Missing required attribute %s" % attr) if cls.ENCODER_ATTRIBUTE not in dict: dict[cls.ENCODER_ATTRIBUTE] = DefaultPacketEncoder if cls.DEFINITIONS_STORE not in dict: dict[cls.DEFINITIONS_STORE] = g_DefaultPacketDefinitions identifier = dict[cls.IDENTIFIER_ATTRIBUTE] version = PacketDefinitionVersion.FromString( dict[cls.VERSION_ATTRIBUTE]) packetStore = dict[cls.DEFINITIONS_STORE] if not cls.PermitDuplicateRegistrations and packetStore.hasDefinition( identifier, version): raise ValueError("Duplicate registration {} v {}".format( identifier, version)) definitionCls = super().__new__(cls, name, parents, dict) packetStore.registerDefinition(identifier, version, definitionCls) return definitionCls
def forceReload(cls, packetType): packetStore = packetType.DEFINITIONS_STORE identifier = packetType.DEFINITION_IDENTIFIER version = PacketDefinitionVersion.FromString( packetType.DEFINITION_VERSION) packetStore.registerDefinition(identifier, version, packetType)