/// <summary> /// Request the packet object write out all of its fields. /// </summary> /// <param name="packet"></param> /// <param name="writer"></param> internal void WriteFields(IPacket packet, IFieldWriter writer) { if (packet is GenericPacket) { //TODO: Update generic packet handling //packet.WriteFields(writer); } else { //We need all of our base classes to write out before us if (m_BasePacket != null) { m_BasePacket.WriteFields(packet, writer); } //and finally write out our information, if we have any. if (m_WriteMethod != null && m_Fields.Count > 0) { //we need to create a serialized packet for this new level so the write method can store information SerializedPacket serializedPacket = new SerializedPacket(this); m_WriteMethod.Invoke(packet, new object[] { this, serializedPacket }); //and now write out the fields to serialization. for (int curFieldIndex = 0; curFieldIndex < Fields.Count; curFieldIndex++) { FieldDefinition fieldDefinition = Fields[curFieldIndex]; writer.Write(serializedPacket.Values[curFieldIndex], fieldDefinition.FieldType); } } } }
/// <summary> /// Read back the field values for the current packet. /// </summary> /// <param name="definition">The definition that was used to persist the packet.</param> /// <param name="packet">The serialized packet to read data from</param> void IPacket.ReadFields(PacketDefinition definition, SerializedPacket packet) { throw new System.NotImplementedException(); }
/// <summary> /// Write out all of the fields for the current packet /// </summary> /// <param name="definition">The definition that was used to persist the packet.</param> /// <param name="packet">The serialized packet to populate with data</param> void IPacket.WriteFields(PacketDefinition definition, SerializedPacket packet) { if (m_BasePacket != null) { ((IPacket)m_BasePacket).WriteFields(definition, packet); } for (int index = 0; index < m_Definition.Fields.Count; index++) { FieldDefinition fieldDefinition = m_Definition.Fields[index]; switch (fieldDefinition.FieldType) { case FieldType.Bool: packet.SetField(fieldDefinition.Name, (bool)m_FieldValues[index]); break; case FieldType.BoolArray: packet.SetField(fieldDefinition.Name, (bool[])m_FieldValues[index]); break; case FieldType.String: packet.SetField(fieldDefinition.Name, (string)m_FieldValues[index]); break; case FieldType.StringArray: packet.SetField(fieldDefinition.Name, (string[])m_FieldValues[index]); break; case FieldType.Int32: packet.SetField(fieldDefinition.Name, (Int32)m_FieldValues[index]); break; case FieldType.Int32Array: packet.SetField(fieldDefinition.Name, (Int32[])m_FieldValues[index]); break; case FieldType.Int64: packet.SetField(fieldDefinition.Name, (Int64)m_FieldValues[index]); break; case FieldType.Int64Array: packet.SetField(fieldDefinition.Name, (Int64[])m_FieldValues[index]); break; case FieldType.UInt32: packet.SetField(fieldDefinition.Name, (UInt32)m_FieldValues[index]); break; case FieldType.UInt32Array: packet.SetField(fieldDefinition.Name, (UInt32[])m_FieldValues[index]); break; case FieldType.UInt64: packet.SetField(fieldDefinition.Name, (UInt64)m_FieldValues[index]); break; case FieldType.UInt64Array: packet.SetField(fieldDefinition.Name, (UInt64[])m_FieldValues[index]); break; case FieldType.Double: packet.SetField(fieldDefinition.Name, (double)m_FieldValues[index]); break; case FieldType.DoubleArray: packet.SetField(fieldDefinition.Name, (double[])m_FieldValues[index]); break; case FieldType.TimeSpan: packet.SetField(fieldDefinition.Name, (TimeSpan)m_FieldValues[index]); break; case FieldType.TimeSpanArray: packet.SetField(fieldDefinition.Name, (TimeSpan[])m_FieldValues[index]); break; case FieldType.DateTime: packet.SetField(fieldDefinition.Name, (DateTime)m_FieldValues[index]); break; case FieldType.DateTimeArray: packet.SetField(fieldDefinition.Name, (DateTime[])m_FieldValues[index]); break; case FieldType.Guid: packet.SetField(fieldDefinition.Name, (Guid)m_FieldValues[index]); break; case FieldType.GuidArray: packet.SetField(fieldDefinition.Name, (Guid[])m_FieldValues[index]); break; case FieldType.DateTimeOffset: packet.SetField(fieldDefinition.Name, (DateTimeOffset)m_FieldValues[index]); break; case FieldType.DateTimeOffsetArray: packet.SetField(fieldDefinition.Name, (DateTimeOffset[])m_FieldValues[index]); break; default: #if DEBUG if (Debugger.IsAttached) { Debugger.Break(); } #endif throw new InvalidOperationException(string.Format("The field type {0} is unknown so we can't serialize the packet ", definition.Fields[index].FieldType)); } } }
private void ReadFields(Type type, IPacket packet, IFieldReader reader) { Exception basePacketException = null; if (m_BasePacket != null) { try { m_BasePacket.ReadFields(type.GetTypeInfo().BaseType, packet, reader); } catch (Exception ex) { basePacketException = ex; // Remember this to wrap it in a new exception. } } if (!m_ReadMethodAssigned) { const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic; if (typeof(IPacket).IsAssignableFrom(type)) { // Even though the current type implements IPacket, it may not have a ReadFields at this level m_ReadMethod = GetIPacketMethod(type, "ReadFields", flags, new Type[] { typeof(PacketDefinition), typeof(SerializedPacket) }); } m_ReadMethodAssigned = true; } Exception firstException = null; FieldType firstFailedFieldType = FieldType.Unknown; string firstFailedFieldName = null; if (m_ReadMethod != null) { //we need to read back everything the definition says should be there into an array and then pass that //to the object for handling. object[] values = new object[Fields.Count]; for (int curFieldIndex = 0; curFieldIndex < Fields.Count; curFieldIndex++) { FieldDefinition fieldDefinition = Fields[curFieldIndex]; try { values[curFieldIndex] = reader.ReadField(fieldDefinition.FieldType); } catch (Exception ex) { if (basePacketException == null && firstException == null) { firstException = ex; // Only record the first one encountered in this packet. firstFailedFieldType = fieldDefinition.FieldType; firstFailedFieldName = fieldDefinition.Name; } } } // Now check for exceptions we may have encountered. We had to finish reading each field of each packet level // in order to keep the stream in sync, but now we have to throw a wrapping exception if there was an error. string message; if (basePacketException != null) // This happened earlier, so it takes precedence over field exceptions. { message = string.Format("Error reading base {0} of a {1}", m_BasePacket.QualifiedTypeName, QualifiedTypeName); throw new GibraltarSerializationException(message, basePacketException); } if (firstException != null) // Otherwise we can report our first exception from reading fields. { message = string.Format("Error reading ({0}) field \"{1}\" in a {2}", firstFailedFieldType, firstFailedFieldName, QualifiedTypeName); throw new GibraltarSerializationException(message, firstException); } SerializedPacket serializedPacket = new SerializedPacket(this, values); m_ReadMethod.Invoke(packet, new object[] { this, serializedPacket }); } }