private object ReadProperty(PropertyData prop, IPacketFormatter formatter) { switch (Type.GetTypeCode(prop.Property.PropertyType)) { case TypeCode.Boolean: if (Remaining < 1 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((bool)prop.Attribute.OptionalValue); } else { return(false); } } return(ReadBoolean()); case TypeCode.Byte: if (Remaining < 1 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((byte)prop.Attribute.OptionalValue); } else { return((byte)0); } } return(ReadByte()); case TypeCode.SByte: if (Remaining < 1 && prop.Attribute.Optional) { return((sbyte)0); } return(ReadSByte()); case TypeCode.Int16: if (Remaining < 2 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((short)prop.Attribute.OptionalValue); } else { return((short)0); } } return(ReadInt16()); case TypeCode.UInt16: if (Remaining < 2 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((ushort)prop.Attribute.OptionalValue); } else { return((ushort)0); } } return(ReadUInt16()); case TypeCode.Int32: if (Remaining < 4 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((int)prop.Attribute.OptionalValue); } else { return((int)0); } } return(ReadInt32()); case TypeCode.UInt32: if (Remaining < 4 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((uint)prop.Attribute.OptionalValue); } else { return((uint)0); } } return(ReadUInt32()); case TypeCode.Single: if (Remaining < 4 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((float)prop.Attribute.OptionalValue); } else { return((float)0); } } return(ReadSingle()); case TypeCode.Int64: if (Remaining < 8 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((long)prop.Attribute.OptionalValue); } else { return((long)0); } } return(ReadInt64()); case TypeCode.UInt64: if (Remaining < 8 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((ulong)prop.Attribute.OptionalValue); } else { return((ulong)0); } } return(ReadUInt64()); case TypeCode.Double: if (Remaining < 8 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((double)prop.Attribute.OptionalValue); } else { return((double)0); } } return(ReadDouble()); case TypeCode.Decimal: if (Remaining < 16 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((decimal)prop.Attribute.OptionalValue); } else { return((decimal)0); } } return(ReadDecimal()); case TypeCode.String: string ret; if (prop.Attribute.Length > 0) { ret = ReadString(prop.Attribute.Length); } else if (prop.Attribute.LengthPrefix) { ret = ReadString(ReadUInt16()); } else { ret = ReadString(); } if (prop.Attribute.MaxLength > 0) { byte[] b = Encoding.GetBytes(ret); ret = Encoding.GetString(b, 0, Math.Min(b.Length, prop.Attribute.MaxLength)); } return(ret); case TypeCode.Object: Type ptype = prop.Property.PropertyType; if (ptype == typeof(byte[])) { return(ReadBytes((int)Remaining)); } else if (ptype == typeof(Guid)) { if (Remaining < 16 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((Guid)prop.Attribute.OptionalValue); } else { return(Guid.Empty); } } return(ReadGuid()); } else if (ptype == typeof(IPAddress)) { if (Remaining < 4 && prop.Attribute.Optional) { if (prop.Attribute.OptionalValue != null) { return((IPAddress)prop.Attribute.OptionalValue); } else { return(IPAddress.Any); } } return(ReadIPAddress()); } else if (typeof(IPacket).IsAssignableFrom(ptype)) { return(ReadPacket(formatter, prop.Attribute.LengthPrefix)); } throw new NotSupportedException("This data type is not supported by the serializer"); } return(null); }
private void WriteProperty(object value, PropertyData prop) { object propvalue = prop.Property.GetValue(value, null); if (prop.Attribute.Optional) { Type t = prop.Property.PropertyType; object opt = prop.Attribute.OptionalValue; if (t.IsValueType && opt != null && propvalue.Equals(opt)) { return; } else if (!t.IsValueType && opt == null) { return; } } switch (Type.GetTypeCode(prop.Property.PropertyType)) { case TypeCode.Boolean: Write((bool)propvalue); break; case TypeCode.Byte: Write((byte)propvalue); break; case TypeCode.SByte: Write((sbyte)propvalue); break; case TypeCode.Int16: Write((short)propvalue); break; case TypeCode.UInt16: Write((ushort)propvalue); break; case TypeCode.Int32: Write((int)propvalue); break; case TypeCode.UInt32: Write((uint)propvalue); break; case TypeCode.Single: Write((float)propvalue); break; case TypeCode.Int64: Write((long)propvalue); break; case TypeCode.UInt64: Write((ulong)propvalue); break; case TypeCode.Double: Write((double)propvalue); break; case TypeCode.Decimal: Write((decimal)propvalue); break; case TypeCode.String: string tmp = (string)propvalue; byte[] b; if (!string.IsNullOrEmpty(tmp)) { b = Encoding.GetBytes(tmp); } else { b = new byte[0]; } if (prop.Attribute.MaxLength > 0) { Array.Resize(ref b, Math.Min(b.Length, prop.Attribute.MaxLength)); } if (prop.Attribute.LengthPrefix) { Write((ushort)b.Length); Write(b); } else { tmp = Encoding.GetString(b); Write(tmp, prop.Attribute.NullTerminated); } break; case TypeCode.Object: Type ptype = prop.Property.PropertyType; if (ptype == typeof(byte[])) { Write((byte[])propvalue); } else if (ptype == typeof(Guid)) { Write((Guid)propvalue); } else if (ptype == typeof(IPAddress)) { Write((IPAddress)propvalue); } else if (typeof(IPacket).IsAssignableFrom(ptype)) { WritePacket((IPacket)propvalue); } else { throw new NotSupportedException("This data type is not supported by the serializer"); } break; } }