void SerializeObject(object value, Type type = null) { ushort valueNr; if (!values.TryGetValue(value, out valueNr)) { AltType altType; List <FieldInfo> fields; Writer.Write((byte)0); values.Add(value, (UInt16)(values.Count + 1)); if (type == null) { type = value.GetType(); SerializeType(type); } altType = AltType.GetAltType(AltTypes, type, value); altType.SerializeValueFields(value, this); fields = altType.AllRefFields; if (fields.Count == 0) { return; } #if USE_NULL_MAP // Prepare null map int bitNr = 0; byte bitInByte; object[] fieldValues = altType.AllRefValues.Take(); for (int i = 0; i < fields.Count; i++) { fieldValue = fields[i].GetValue(value); fieldValues[i] = fieldValue; bitInByte = (byte)(0x1 << (bitNr % 8)); if (fieldValue != null) { nullMap[bitNr / 8] |= bitInByte; } else { nullMap[bitNr / 8] &= (byte)(0xFF ^ bitInByte); } bitNr++; } Writer.Write(nullMap, 0, 1 + (fields.Count - 1) / 8); bitNr = 0; #endif // write non null reference values for (int i = 0; i < fields.Count; i++) { Type itemType = null; #if USE_NULL_MAP fieldValue = fieldValues[i]; if (fieldValue == null) { continue; } if (ALL_SEALED || fields[i].FieldType.IsSealed) { itemType = fields[i].FieldType; } #else fieldValue = fields[i].GetValue(value); #endif #if TRACE field = fields[i]; #endif Serialize(fieldValue, itemType); } #if USE_NULL_MAP altType.AllRefValues.Return(fieldValues); #endif } else { Writer.Write((byte)(valueNr & 0xFF)); Writer.Write((byte)(valueNr >> 8)); } }
object DeserializeObject(Type type = null) { UInt16 valueNr = Reader.ReadByte(); if (valueNr == 0) { object value; AltType altType; List <FieldInfo> fields; if (type == null) { type = DeserializeType(); } //var constructor = type.GetConstructor(Type.EmptyTypes); //if (constructor != null) // value = constructor.Invoke(null); //else value = FormatterServices.GetSafeUninitializedObject(type); valueList.Add(value); altType = AltType.GetAltType(AltTypes, type, value); altType.DeserializeValueFields(value, this); fields = altType.AllRefFields; if (fields.Count == 0) { return(value); } #if USE_NULL_MAP int bitNr = 0; byte bitInByte; var nullMap = new byte[1 + (fields.Count - 1) / 8]; Reader.Read(nullMap, 0, 1 + (fields.Count - 1) / 8); #endif object fieldValue; for (int i = 0; i < fields.Count; i++) { Type itemType = null; #if USE_NULL_MAP bitInByte = (byte)(0x1 << (bitNr % 8)); if ((nullMap[bitNr++ / 8] & bitInByte) == 0) { continue; } if (ALL_SEALED || fields[i].FieldType.IsSealed) { itemType = fields[i].FieldType; } #endif #if TRACE field = fields[i]; #endif fieldValue = Deserialize(itemType); fields[i].SetValue(value, fieldValue); } return(value); } else { valueNr |= (ushort)(Reader.ReadByte() << 8); return(valueList[valueNr - 1]); } }