예제 #1
0
 private static void ReadMemberValues(DeserializationState state, ClassRecord record)
 {
     foreach (var member in record.Members)
     {
         var val = ReadMemberValue(state, member);
         member.Value = val;
     }
 }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }