private static void ReadMemberValues(DeserializationState state, ClassRecord record) { foreach (var member in record.Members) { var val = ReadMemberValue(state, member); member.Value = val; } }
private static void ReadMembers(DeserializationState state, ClassRecord record) { record.TypeName = state.array.Read7BitLengthPrefixedString(ref state.idx); var cap = state.array.ReadInt32LEFromBytes(ref state.idx); record.Members.Capacity = cap; for (var i = 0; i < cap; ++i) { var member = new ClassRecordMember(); member.Name = state.array.Read7BitLengthPrefixedString(ref state.idx); record.Members.Add(member); } }
private static void ReadMemberTypes(DeserializationState state, ClassRecord record) { // First normal info foreach (var member in record.Members) { ReadBasicTypeInfo(state, member); } // Then additional info, if any foreach (var member in record.Members) { ReadAdditionalTypeInfo(state, member); } }
private static void WriteClassRecord(SerializationState state, ClassRecord claas, Int32 id) { var metaDataKey = Tuple.Create(claas.AssemblyName, claas.TypeName); Int32 otherID; if (state.serializedObjects.TryGetValue(metaDataKey, out otherID)) { // Another record of the same type was serialized earlier, can use previous info state.EnsureCapacity(9); state.array .WriteByteToBytes(ref state.idx, (Byte)RecordTypeEnumeration.ClassWithID) .WriteInt32LEToBytes(ref state.idx, id) .WriteInt32LEToBytes(ref state.idx, otherID); state.WriteArrayToStream(); } else { var isSystem = claas.AssemblyName == null; var nameByteCount = SafeByteCount(claas.TypeName); state.EnsureCapacity(14 + nameByteCount); // class type (1), id (4), space for class name length (max 5), member count (4) state.array .WriteByteToBytes(ref state.idx, (Byte)(isSystem ? RecordTypeEnumeration.SystemClassWithMembersAndTypes : RecordTypeEnumeration.ClassWithMembersAndTypes)) .WriteInt32LEToBytes(ref state.idx, id) .WriteInt32Encoded7Bit(ref state.idx, nameByteCount) .WriteStringToBytes(ref state.idx, UTF8, claas.TypeName) .WriteInt32LEToBytes(ref state.idx, claas.Members.Count); state.WriteArrayToStream(); // Write member names foreach (var member in claas.Members) { nameByteCount = SafeByteCount(member.Name); state.EnsureCapacity(5 + nameByteCount); state.array .WriteInt32Encoded7Bit(ref state.idx, nameByteCount) .WriteStringToBytes(ref state.idx, UTF8, member.Name); state.WriteArrayToStream(); } // Write member type infos state.EnsureCapacity(claas.Members.Count); var mTypeCodes = new List <Tuple <BinaryTypeEnumeration, PrimitiveTypeEnumeration> >(claas.Members.Count); foreach (var member in claas.Members) { PrimitiveTypeEnumeration pType; var bt = GetTypeInfo(member.Value, out pType); mTypeCodes.Add(Tuple.Create(bt, pType)); state.array.WriteByteToBytes(ref state.idx, (Byte)bt); } state.WriteArrayToStream(); // Write additional type info where applicable for (var i = 0; i < mTypeCodes.Count; ++i) { var member = claas.Members[i]; var tuple = mTypeCodes[i]; switch (tuple.Item1) { case BinaryTypeEnumeration.Primitive: state.EnsureCapacity(1); state.array.WriteByteToBytes(ref state.idx, (Byte)tuple.Item2); break; case BinaryTypeEnumeration.SystemClass: nameByteCount = SafeByteCount(member.TypeName); state.EnsureCapacity(5 + nameByteCount); state.array .WriteInt32Encoded7Bit(ref state.idx, nameByteCount) .WriteStringToBytes(ref state.idx, UTF8, member.TypeName); break; case BinaryTypeEnumeration.Class: nameByteCount = SafeByteCount(member.TypeName); state.EnsureCapacity(9 + nameByteCount); state.array .WriteInt32Encoded7Bit(ref state.idx, nameByteCount) .WriteStringToBytes(ref state.idx, UTF8, member.TypeName) .WriteInt32LEToBytes(ref state.idx, state.assemblies[member.AssemblyName]); break; case BinaryTypeEnumeration.PrimitiveArray: state.EnsureCapacity(1); state.array .WriteByteToBytes(ref state.idx, (Byte)tuple.Item2); break; } state.WriteArrayToStream(); } // Write this class assembly name if needed if (!isSystem) { state.EnsureCapacity(4); state.array.WriteInt32LEToBytes(ref state.idx, state.assemblies[claas.AssemblyName]); state.WriteArrayToStream(); } // Write member values for (var i = 0; i < mTypeCodes.Count; ++i) { var member = claas.Members[i]; var val = member.Value; // Change raw string values to StringRecords to enable caching strings by id if (val is String) { var sRec = new StringRecord(); sRec.StringValue = (String)val; val = sRec; } var rec = val as AbstractRecord; if (rec != null) { // All arrays and non-structs are serialized afterwards. if (rec is ArrayRecord || (rec is ClassRecord && !((ClassRecord)rec).IsSerializedInPlace)) { // Add to mapping before calling recursively in order to create MemberReference if (state.TryAddRecord(rec, out id)) { // The record hasn't been serialized, add to queue state.recordQueue.Enqueue(rec); } } // Write the record WriteSingleRecord(state, rec, false); } else { // Write value as primitive WritePrimitive(state, val, mTypeCodes[i].Item2); } } } if (!state.serializedObjects.ContainsKey(metaDataKey)) { state.serializedObjects.Add(metaDataKey, id); } }