public static void WriteProperty(this Stream stream, string fieldName, Type fieldType, 
            object fieldValue, List<string> nameTable, int? arrayIndex = null)
        {
            if (fieldType.IsArray)
            {
                var array = (Array)fieldValue;
                for (var i = 0; i < array.Length; i++)
                {
                    var value = array.GetValue(i);
                    if (value != null)
                        stream.WriteProperty(fieldName, fieldType.GetElementType(), array.GetValue(i), nameTable, i);
                }
                return;
            }

            var fieldBodyStream = new MemoryStream();

            var baseProperty = new BaseProperty
            {
                NameIdx = AddToNameTable(nameTable, fieldName),
                ArrayIdx = arrayIndex ?? 0
            };

            if (fieldType == typeof (int))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "IntProperty");
                var value = (int) fieldValue;
                fieldBodyStream.WriteInt32(value);
            }
            else if (fieldType == typeof (bool))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "BoolProperty");
                var value = (bool) fieldValue;
                fieldBodyStream.WriteBool(value);
            }
            else if (fieldType.IsEnum)
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "ByteProperty");
                var value1 = AddToNameTable(nameTable, fieldType.Name); // Enum type name
                var value2 = AddToNameTable(nameTable, fieldValue.ToString()); // Enum value
                fieldBodyStream.WriteInt32(value1);
                fieldBodyStream.WriteInt32(value2);
            }
            else if (fieldType == typeof (float))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "FloatProperty");
                var value = (float) fieldValue;
                fieldBodyStream.WriteFloat(value);
            }
            else if (fieldType == typeof (NameProperty))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "NameProperty");
                var nameProp = (NameProperty) fieldValue;
                var value = AddToNameTable(nameTable, nameProp.Name);
                fieldBodyStream.WriteInt32(value);
            }
            else if (fieldType == typeof (string))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "StrProperty");
                var value = (string) fieldValue;
                switch (fieldName)
                {
                    case "SaveDetails":
                    case "FriendlyName":
                        fieldBodyStream.WriteUnicodeString(value);
                        break;
                    default:
                        fieldBodyStream.WriteString(value);
                        break;
                }
                //fieldBodyStream.WriteUnicodeString(value); // Save every string as unicode
            }
            else if (fieldType.IsGenericType && (fieldType.GetGenericTypeDefinition() == typeof(List<>)))
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "ArrayProperty");
                var list = fieldValue as IList;
                var elementType = fieldType.GetGenericArguments()[0];
                fieldBodyStream.WriteInt32(list.Count); // numElements
                for (var i = 0; i < list.Count; i++)
                {
                    if (elementType == typeof (int))
                    {
                        fieldBodyStream.WriteInt32((int) list[i]);
                    }
                    else if (elementType == typeof (string))
                    {
                        fieldBodyStream.WriteString((string) list[i]);
                    }
                    else if (elementType == typeof (NameProperty))
                    {
                        var value = AddToNameTable(nameTable, ((NameProperty) list[i]).Name);
                        fieldBodyStream.WriteInt32(value);
                    }
                    else
                    {
                        fieldBodyStream.SerializeObject(list[i], nameTable);
                    }
                }
            }
            else if (!fieldType.IsGenericType && !fieldType.IsValueType && !fieldType.IsPrimitive && fieldType.IsClass)
            {
                baseProperty.TypeIdx = AddToNameTable(nameTable, "StructProperty");

                fieldBodyStream.WriteInt32(AddToNameTable(nameTable, fieldType.Name)); // StructNameIdx

                if (fieldType == typeof (Vector))
                {
                    var value = (Vector) fieldValue;
                    fieldBodyStream.WriteFloat(value.X);
                    fieldBodyStream.WriteFloat(value.Y);
                    fieldBodyStream.WriteFloat(value.Z);
                }
                else if (fieldType == typeof (Rotator))
                {
                    var value = (Rotator) fieldValue;
                    fieldBodyStream.WriteInt32(value.Pitch);
                    fieldBodyStream.WriteInt32(value.Yaw);
                    fieldBodyStream.WriteInt32(value.Roll);
                }
                else
                {
                    fieldBodyStream.SerializeObject(fieldValue, nameTable);
                }
            }

            baseProperty.PropertySize = (int) fieldBodyStream.Length;
            stream.WriteBaseProperty(baseProperty);
            fieldBodyStream.WriteTo(stream);
        }
Example #2
0
        public static Stream Serialize(this Bin bin)
        {
            Stream serialized = new MemoryStream();

            serialized.WriteUint((uint)bin.Count);

            var alias = TypeIdentity.Instance.FindAlias(bin.GetInnerType());
            serialized.WriteUint(alias.UnicodeLength());
            serialized.WriteUnicode(alias);

            for (int i = 0; i < bin.Count; i++)
            {
                if (bin.GetInnerType() == typeof(bool))
                {
                    serialized.WriteBool((bool)bin[i]);
                }
                if (bin.GetInnerType() == typeof(int))
                {
                    serialized.WriteInt((int)bin[i]);
                }
                if (bin.GetInnerType() == typeof(float))
                {
                    serialized.WriteFloat((float)bin[i]);
                }
                if (bin.GetInnerType() == typeof(double))
                {
                    serialized.WriteDouble((double)bin[i]);
                }
                if (bin.GetInnerType() == typeof(string))
                {
                    var l = ((string)bin[i]).UnicodeLength();
                    serialized.WriteUint(l);
                    if (l>0) serialized.WriteUnicode((string)bin[i]);
                }

                if (bin.GetInnerType() == typeof(RGBAColor))
                {
                    serialized.WriteDouble(((RGBAColor)bin[i]).R);
                    serialized.WriteDouble(((RGBAColor)bin[i]).G);
                    serialized.WriteDouble(((RGBAColor)bin[i]).B);
                    serialized.WriteDouble(((RGBAColor)bin[i]).A);
                }
                if (bin.GetInnerType() == typeof(Vector2D))
                {
                    serialized.WriteDouble(((Vector2D)bin[i]).x);
                    serialized.WriteDouble(((Vector2D)bin[i]).y);
                }
                if (bin.GetInnerType() == typeof(Vector3D))
                {
                    serialized.WriteDouble(((Vector3D)bin[i]).x);
                    serialized.WriteDouble(((Vector3D)bin[i]).y);
                    serialized.WriteDouble(((Vector3D)bin[i]).z);
                }
                if (bin.GetInnerType() == typeof(Vector4D))
                {
                    serialized.WriteDouble(((Vector4D)bin[i]).x);
                    serialized.WriteDouble(((Vector4D)bin[i]).y);
                    serialized.WriteDouble(((Vector4D)bin[i]).z);
                    serialized.WriteDouble(((Vector4D)bin[i]).w);
                }
                if (bin.GetInnerType() == typeof(Matrix4x4))
                {
                    for (int j = 0; j < 16; j++)
                    {
                        serialized.WriteDouble(((Matrix4x4)bin[i]).Values[j]);
                    }
                }
                if (bin.GetInnerType() == typeof(Stream))
                {
                    var l = ((Stream)bin[i]).Length;
                    serialized.WriteUint((uint)l);
                    if (l > 0)
                    {
                        ((Stream) bin[i]).Position = 0;
                        ((Stream) bin[i]).CopyTo(serialized, (int) l);
                    }
                }
                if (bin.GetInnerType() == typeof(Time.Time))
                {
                    var t = (Time.Time) bin[i];
                    var time = t.UniversalTime.ToString("yyyy-MM-dd HH:mm:ss.ffff");
                    var zone = t.TimeZone.Id;

                    serialized.WriteUint(time.UnicodeLength());
                    serialized.WriteUnicode(time);

                    serialized.WriteUint(zone.UnicodeLength());
                    serialized.WriteUnicode(zone);
                }

            }
            serialized.Position = 0;
            return serialized;
        }