protected virtual int SerializeBody(ref byte[] bytes, int offset, T instance, IFormatterResolver formatterResolver) { // [typeIndex, [members], [members], [members]] var startOffset = offset; var meta = DarkMeta.Get(instance.GetType()); if (meta.Flags.IsStatic()) { offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, meta.DeepLevel); } else { offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, meta.DeepLevel + 1); offset += MessagePackBinary.WriteInt32(ref bytes, offset, (int)meta.TypeIndex); if (meta.TypeIndex == TypeIndex.Invalid) { var message = String.Format("Type index is invalid at {0} ", instance.ToString()); Logger.Instance.Error(message); } } offset += meta.WriteMembers(Serializer.Instance.State.Settings.Flags, instance, ref bytes, offset, formatterResolver); return(offset - startOffset); }
public int SerializeBody(ref byte[] bytes, int offset, T instance, IFormatterResolver formatterResolver, bool fullSerialization, out bool dataWritten) { var startOffset = offset; var meta = DarkMeta.Get(instance.GetType()); var count = 2; if (fullSerialization) { count += meta.DeepLevel; if (!meta.Flags.IsSerializable()) { count--; } } offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, count); offset += MessagePackBinary.WriteInt32(ref bytes, offset, (int)meta.TypeIndex); offset += formatterResolver.GetFormatter <Guid>().Serialize(ref bytes, offset, instance.Guid, formatterResolver); dataWritten = false; if (fullSerialization) { var state = Serializer.Instance.State; state.StartLocalGroup(out int previousOffset); var writtenSize = meta.WriteMembers(state.Settings.Flags, instance, ref bytes, offset, formatterResolver); bool skipData = false; if (state.WriteOnlyChanged) { if (meta.Type == typeof(Entity) && FieldListFormatter.LastFieldWritten == 0) { var isArray16 = bytes[offset + writtenSize - 2] == MessagePackCode.Array16; var length = isArray16 ? writtenSize - 3 : writtenSize - 1; skipData = instance.OriginalBytes.BeginingEquals(bytes, offset, length); } else { skipData = instance.OriginalBytes.Equals(bytes, offset, writtenSize); } } if (skipData) { state.UnrollLocalGroup(); MessagePackBinary.ReWriteArrayHeaderDownwards(ref bytes, startOffset, count - 1); } else { offset += writtenSize; dataWritten = writtenSize > 1; } state.RestoreLocalGroup(previousOffset); } return(offset - startOffset); }
public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { if (MessagePackBinary.IsNil(bytes, offset)) { readSize = 1; return(null); } var startOffset = offset; var elementsCount = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); offset += readSize; object instance; if (MessagePackBinary.IsNil(bytes, offset)) { // reference: MessagePackBinary.ReadNil(bytes, offset, out readSize); offset += readSize; var reference = MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; instance = Serializer.Instance.State.GetInstance(reference); } else { // full deserialization: var meta = DarkMeta <T> .Value; if (!meta.Flags.IsStatic()) { var typeIndex = (TypeIndex)MessagePackBinary.ReadInt32(bytes, offset, out readSize); offset += readSize; if (typeIndex != meta.TypeIndex) { meta = DarkMeta.Get(typeIndex); if (meta == null) { Logger.Instance.Warning(String.Format("Can't find typeIndex {0}", typeIndex)); for (int i = 0; i < elementsCount - 1; i++) { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } readSize = offset - startOffset; return(null); } } } instance = DeserializeBody(meta.Type, elementsCount - 1, bytes, offset, formatterResolver, out readSize); offset += readSize; meta.OnDeserialized(instance); } readSize = offset - startOffset; return(instance as T); }
protected virtual T DeserializeBody(Type type, int elementsCount, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { // ...[members], [members], [members]... var meta = DarkMeta.Get(type); var instance = meta.CreateInstance(); Serializer.Instance.State.ObjectInstances.Add(instance); meta.ReadMembers(Serializer.Instance.State.Settings.Flags, ref instance, bytes, offset, formatterResolver, out readSize); return((T)instance); }
public static DarkMeta Get(Type type) { DarkMeta meta; if (!MetasByType.TryGetValue(type, out meta)) { meta = new DarkMeta(type); MetasByType[type] = meta; if (meta.TypeIndex != TypeIndex.Invalid) { MetasByIndex[meta.TypeIndex] = meta; } } return(meta); }
private void InitBaseMeta() { var baseType = Type.BaseType; while (baseType != null) { var attribute = baseType.GetCustomAttribute <DarkContractAttribute>(false); if (attribute != null && attribute.Flags.IsSerializable()) { BaseMeta = DarkMeta.Get(baseType); DeepLevel = !Flags.IsSkipWriting() ? BaseMeta.DeepLevel + 1 : BaseMeta.DeepLevel; return; } baseType = baseType.BaseType; } DeepLevel = !Flags.IsSkipWriting() ? 1 : 0; }
protected override T DeserializeBody(Type type, int elementsCount, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { var startOffset = offset; var guid = formatterResolver.GetFormatter <Guid>().Deserialize(bytes, offset, formatterResolver, out readSize); offset += readSize; DarkMeta meta = null; object instance = GuidStorage.Get(guid); if (instance == null) { meta = DarkMeta.Get(type); instance = meta.CreateInstance(guid); } Serializer.Instance.State.ObjectInstances.Add(instance); if (elementsCount > 1) { // full deserialization (only in one file) var state = Serializer.Instance.State; state.StartLocalGroup(out int previousOffset); meta = meta ?? DarkMeta.Get(type); meta.ReadMembers(state.Settings.Flags, ref instance, bytes, offset, formatterResolver, out readSize); (instance as GuidObject).OriginalBytes = new ByteSlice(offset, readSize); offset += readSize; state.RestoreLocalGroup(previousOffset); } readSize = offset - startOffset; return(instance as T); }