public void Deserialize(byte[] buffer, ref int offset, ref RectOffset value) { value.left = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.right = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.top = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.bottom = SerializerBinary.ReadInt32Fixed(buffer, ref offset); }
public void Deserialize(byte[] buffer, ref int offset, ref AnimationCurve value) { // Read length var length = SerializerBinary.ReadInt32(buffer, ref offset); // Deserialize individual keyframes again var keys = new Keyframe[length]; for (int i = 0; i < length; i++) { _keyframeFormatter.Deserialize(buffer, ref offset, ref keys[i]); } // Create or update the given AnimationCurve if (value == null) { value = new AnimationCurve(keys); } else { value.keys = keys; } // Set the wrap modes var wrap = default(WrapMode); _wrapModeFormatter.Deserialize(buffer, ref offset, ref wrap); value.preWrapMode = wrap; _wrapModeFormatter.Deserialize(buffer, ref offset, ref wrap); value.postWrapMode = wrap; }
public void Serialize(ref byte[] buffer, ref int offset, RectOffset value) { SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, value.left); SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, value.right); SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, value.top); SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, value.bottom); }
public void Deserialize <T>(ref T value, byte[] buffer, ref int offset, int expectedReadLength = -1) { if (buffer == null) { throw new ArgumentNullException("Must provide a buffer to deserialize from!"); } EnterRecursive(RecursionMode.Deserialization); try { var formatter = (IFormatter <T>)GetGenericFormatter(typeof(T)); int offsetBeforeRead = offset; if (Config.EmbedChecksum) { var checksum = SerializerBinary.ReadInt32Fixed(buffer, ref offset); if (checksum != ProtocolChecksum.Checksum) { throw new InvalidOperationException($"Checksum does not match embedded checksum (Serializer={ProtocolChecksum.Checksum}, Data={checksum})"); } } formatter.Deserialize(buffer, ref offset, ref value); if (expectedReadLength != -1) { int bytesActuallyRead = offset - offsetBeforeRead; if (bytesActuallyRead != expectedReadLength) { throw new UnexpectedBytesConsumedException("The deserialization has completed, but not all of the given bytes were consumed. " + " Maybe you tried to deserialize something directly from a larger byte-array?", expectedReadLength, bytesActuallyRead, offsetBeforeRead, offset); } } // todo: instead of clearing and re-adding the known types, the type-cache should have a fallback cache inside it // todo: .. that gets used when the ID is out of range. So outside is the dynamic stuff (with an offset of where IDs will start), and inside are the // todo: .. known elements, and if we're given an ID that is too low, we defer to the inner cache. // Very important to clear out caches and stuff that is only valid for this call if (!Config.PersistTypeCache) { InstanceData.TypeCache.ClearDeserializationCache(); foreach (var t in Config.KnownTypes) { InstanceData.TypeCache.AddKnownType(t); } } if (!Config.PersistObjectCache) { InstanceData.ObjectCache.ClearDeserializationCache(); } } finally { LeaveRecursive(RecursionMode.Deserialization); } }
/// <summary> /// Use this overload whenever you can. The intention is that you reuse the serialization buffer so the serializer only has to resize/reallocate a newer (larger) one if there really is not enough space; instead of allocating an array for every Serialize() call, this lets you avoid GC-pressure. /// You *can* pass in null for 'targetByteArray' and let the serializer allocate one for you. /// </summary> public int Serialize <T>(T obj, ref byte[] buffer, int offset = 0) { EnterRecursive(RecursionMode.Serialization); if (buffer == null) { buffer = new byte[0x4000]; // 16k } try { // // Root object is the IExternalObject we're serializing (if any) // We have to keep track of it so the CacheFormatter knows what NOT to skip // otherwise we'd obviously only write one byte lol (the external ID) and nothing else. InstanceData.CurrentRoot = obj as IExternalRootObject; // // The actual serialization int offsetBeforeWrite = offset; { if (Config.Advanced.EmbedChecksum) { SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, ProtocolChecksum.Checksum); } var formatter = (IFormatter <T>)GetReferenceFormatter(typeof(T)); formatter.Serialize(ref buffer, ref offset, obj); } int offsetAfterWrite = offset; // // After we're done, we have to clear all our caches! // Only very rarely can we avoid that // todo: implement check-pointing inside the TypeDictionary itself if (!Config.Advanced.PersistTypeCache) { InstanceData.TypeCache.ResetSerializationCache(); } InstanceData.ObjectCache.ClearSerializationCache(); int dataSize = offsetAfterWrite - offsetBeforeWrite; return(dataSize); } finally { // // Clear the root object again //InstanceData.WrittenSchemata.Clear(); InstanceData.EncounteredSchemaTypes.Clear(); InstanceData.CurrentRoot = null; LeaveRecursive(RecursionMode.Serialization); } }
/// <summary> /// Use this overload whenever you can. The intention is that you reuse the serialization buffer so the serializer only has to resize/reallocate a newer (larger) one if there really is not enough space; instead of allocating an array for every Serialize() call, this lets you avoid GC-pressure. /// You *can* pass in null for 'targetByteArray' and let the serializer allocate one for you. /// </summary> public int Serialize <T>(T obj, ref byte[] targetByteArray, int offset = 0) { EnterRecursive(RecursionMode.Serialization); if (Config.EmbedChecksum) { SerializerBinary.WriteInt32Fixed(ref targetByteArray, ref offset, ProtocolChecksum.Checksum); } try { // // Root object is the IExternalObject we're serializing (if any) // We have to keep track of it so the CacheFormatter knows what NOT to skip // otherwise we'd obviously only write one byte lol (the external ID) and nothing else. InstanceData.CurrentRoot = obj as IExternalRootObject; var formatter = (IFormatter <T>)GetGenericFormatter(typeof(T)); // // The actual serialization int offsetBeforeWrite = offset; formatter.Serialize(ref targetByteArray, ref offset, obj); int offsetAfterWrite = offset; // // After we're done, we probably have to clear all our caches! // Only very rarely can we avoid that // todo: would it be more efficient to have one static and one dynamic dictionary? if (!Config.PersistTypeCache) { InstanceData.TypeCache.ClearSerializationCache(); foreach (var t in Config.KnownTypes) { InstanceData.TypeCache.RegisterObject(t); } } if (!Config.PersistObjectCache) { InstanceData.ObjectCache.ClearSerializationCache(); } return(offsetAfterWrite - offsetBeforeWrite); } finally { // // Clear the root object again LeaveRecursive(RecursionMode.Serialization); } }
public void Serialize(ref byte[] buffer, ref int offset, AnimationCurve value) { var keys = value.keys; // Length SerializerBinary.WriteInt32(ref buffer, ref offset, keys.Length); // Keyframes for (int i = 0; i < keys.Length; i++) { _keyframeFormatter.Serialize(ref buffer, ref offset, keys[i]); } _wrapModeFormatter.Serialize(ref buffer, ref offset, value.preWrapMode); _wrapModeFormatter.Serialize(ref buffer, ref offset, value.postWrapMode); }
public void Deserialize(byte[] buffer, ref int offset, ref LayerMask value) { value.value = SerializerBinary.ReadInt32Fixed(buffer, ref offset); }
public void Serialize(ref byte[] buffer, ref int offset, LayerMask value) { SerializerBinary.WriteInt32Fixed(ref buffer, ref offset, value.value); }
/// <summary> /// The most advanced deserialize method. /// <para>Again, you can put in an existing object to populate (or a variable that's currently null, in which case Ceras creates an object for you)</para> /// <para>In this version you can put in the offset as well, telling Ceras where to start reading from inside the buffer.</para> /// <para>After the method is done, the offset will be where Ceras has stopped reading.</para> /// <para>If you pass in a value >0 for <paramref name="expectedReadLength"/> then Ceras will check how many bytes it has read (only rarely useful)</para> /// </summary> public void Deserialize <T>(ref T value, byte[] buffer, ref int offset, int expectedReadLength = -1) { if (buffer == null) { throw new ArgumentNullException("Must provide a buffer to deserialize from!"); } EnterRecursive(RecursionMode.Deserialization); try { int offsetBeforeRead = offset; // // Actual deserialization { if (Config.Advanced.EmbedChecksum) { var checksum = SerializerBinary.ReadInt32Fixed(buffer, ref offset); if (checksum != ProtocolChecksum.Checksum) { throw new InvalidOperationException($"Checksum does not match embedded checksum (Serializer={ProtocolChecksum.Checksum}, Data={checksum})"); } } var formatter = (IFormatter <T>)GetReferenceFormatter(typeof(T)); formatter.Deserialize(buffer, ref offset, ref value); } if (expectedReadLength != -1) { int bytesActuallyRead = offset - offsetBeforeRead; if (bytesActuallyRead != expectedReadLength) { throw new UnexpectedBytesConsumedException("The deserialization has completed, but not all of the given bytes were consumed. " + " Maybe you tried to deserialize something directly from a larger byte-array?", expectedReadLength, bytesActuallyRead, offsetBeforeRead, offset); } } // todo: use a custom 'Bag' collection or so for deserialization caches, so we can quickly remove everything above a certain index // Clearing and re-adding the known types is really bad... // But how would we optimize it best? // Maybe having a sort of fallback-cache? I guess it would be faster than what we're doing now, // but then we'd have an additional if() check every time :/ // // The deserialization cache is a list, we'd check for out of range, and then check the secondary cache? // // Or maybe the most straight-forward approach would be to simply remember at what index the KnownTypes end and the dynamic types start, // and then we can just RemoveRange() everything above the known index... if (!Config.Advanced.PersistTypeCache) { InstanceData.TypeCache.ResetDeserializationCache(); } InstanceData.ObjectCache.ClearDeserializationCache(); } finally { LeaveRecursive(RecursionMode.Deserialization); } }