示例#1
0
        public void Serialize(object obj, ExtendedBinaryWriter writer, Type objType = null)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("valueObj cannot be null");
            }

            if (objType == null)
            {
                objType = obj.GetType();
            }

            if (objType.IsArray)
            {
                Type elemType = objType.GetElementType();

                var arrayObj = obj as Array;
                int length   = arrayObj.Length;

                writer.AlignStream();
                writer.Write(length);

                if (elemType == typeof(Byte))
                {
                    writer.Write(obj as byte[]);
                    writer.AlignStream();
                }
                else if (elemType.IsValueType)
                {
                    foreach (object element in arrayObj)
                    {
                        WriteValueType(element, writer, objType, noAlign: true);
                    }

                    writer.AlignStream();
                }
                else
                {
                    foreach (object element in arrayObj)
                    {
                        Serialize(element, writer);
                    }
                }
            }
            else if (objType.IsEnum)
            {
                var enumType = Enum.GetUnderlyingType(objType);
                WriteValueType(obj, writer, enumType);
            }
            else if (objType.IsValueType)
            {
                WriteValueType(obj, writer, objType);
            }
            else if (objType == typeof(string))
            {
                writer.AlignStream();
                writer.WriteAlignedString(obj as string);
            }
            else if (objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(List <>))
            {
                Type elemType = objType.GetGenericArguments()[0];

                var listObj = obj as IList;
                int length  = listObj.Count;

                writer.AlignStream();
                writer.Write(length);

                if (elemType.IsValueType)
                {
                    foreach (object element in listObj)
                    {
                        WriteValueType(element, writer, elemType, noAlign: true);
                    }
                }
                else
                {
                    foreach (object element in listObj)
                    {
                        Serialize(element, writer);
                    }
                }
            }
            else if (objType.IsClass)
            {
                if (!Attribute.IsDefined(objType, typeof(UnitySerializableAttribute)))
                {
                    throw new Exception("not serializable type : " + objType.ToString());
                }

                if (Attribute.IsDefined(objType.BaseType, typeof(UnitySerializableAttribute)))
                {
                    Serialize(obj, writer, objType.BaseType);
                }

                foreach (var field in objType.GetFields())
                {
                    if (!field.DeclaringType.Equals(objType))
                    {
                        continue;
                    }
                    var fieldValue = field.GetValue(obj);
                    var fieldType  = field.FieldType;

                    if (fieldType.IsEnum)
                    {
                        var enumType = Enum.GetUnderlyingType(fieldType);
                        WriteValueType(fieldValue, writer, enumType);
                    }
                    else if (fieldType.IsValueType)
                    {
                        WriteValueType(fieldValue, writer, fieldType, Attribute.IsDefined(field, typeof(UnityDoNotAlignAttribute)));
                    }
                    else
                    {
                        Serialize(fieldValue, writer);
                    }
                }
            }

            writer.AlignStream();
        }
示例#2
0
        private static void WriteValueType(object valueObj, ExtendedBinaryWriter writer, Type valueType, bool noAlign = false)
        {
            if (valueObj == null)
            {
                throw new ArgumentNullException("valueObj cannot be null");
            }

            if (valueType == null)
            {
                valueType = valueObj.GetType();
            }

            if (!noAlign)
            {
                writer.AlignStream();
            }

            if (valueType == typeof(Int32))
            {
                writer.Write((int)valueObj);
            }
            else if (valueType == typeof(UInt32))
            {
                writer.Write((uint)valueObj);
            }
            else if (valueType == typeof(Int64))
            {
                writer.Write((long)valueObj);
            }
            else if (valueType == typeof(UInt64))
            {
                writer.Write((ulong)valueObj);
            }
            else if (valueType == typeof(Int16))
            {
                writer.Write((short)valueObj);
            }
            else if (valueType == typeof(UInt16))
            {
                writer.Write((ushort)valueObj);
            }
            else if (valueType == typeof(Byte))
            {
                writer.Write((byte)valueObj);
            }
            else if (valueType == typeof(SByte))
            {
                writer.Write((sbyte)valueObj);
            }
            else if (valueType == typeof(Boolean))
            {
                writer.Write((bool)valueObj);
            }
            else if (valueType == typeof(Double))
            {
                writer.Write((double)valueObj);
            }
            else if (valueType == typeof(Single))
            {
                writer.Write((float)valueObj);
            }
        }
示例#3
0
        public void Save(string path)
        {
            var fourByteArray = new byte[4];

            byte[] buffer = new byte[0x8000];
            int    size;
            int    read = 0;

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            using (var w = new ExtendedBinaryWriter(File.OpenWrite(path)))
            {
                buf.Position = 0;
                w.Write(buf.ReadBytes((int)data_offset));

                int objCount = assets.Count;

                long[] offsetArray = new long[objCount];
                uint[] sizeArray   = new uint[objCount];

                for (int i = 0; i < objCount; i++)
                {
                    var objInfo = assets.ElementAt(i).Value;

                    offsetArray[i] = w.BaseStream.Position - data_offset;

                    if (replaceDict.ContainsKey(objInfo.pathID))
                    {
                        w.Write(replaceDict[objInfo.pathID]);
                        sizeArray[i] = (uint)replaceDict[objInfo.pathID].Length;
                    }
                    else
                    {
                        buf.Position = objInfo.RealOffset;
                        size         = (int)objInfo.size;
                        while (size > 0 && (read = buf.Read(buffer, 0, Math.Min(buffer.Length, size))) > 0)
                        {
                            w.Write(buffer, 0, read);
                            size -= read;
                        }
                        sizeArray[i] = objInfo.size;
                    }

                    var pos = w.BaseStream.Position;
                    var mod = pos % 4;
                    if (mod != 0)
                    {
                        w.Write(new byte[4 - mod]);
                    }
                    else
                    {
                        w.Write(fourByteArray);
                    }
                }

                long totalSize = w.BaseStream.Position;

                w.BaseStream.Position = objectsIndexOffset;

                for (int i = 0; i < objCount; i++)
                {
                    if (format >= 14)
                    {
                        w.AlignStream();
                        w.Seek(8, SeekOrigin.Current);
                    }
                    else if (longObjectIDs)
                    {
                        w.Seek(8, SeekOrigin.Current);
                    }
                    else
                    {
                        w.Seek(4, SeekOrigin.Current);
                    }

                    if (format >= 22)
                    {
                        w.Write(offsetArray[i]);
                    }
                    else
                    {
                        w.Write((uint)offsetArray[i]);
                    }
                    w.Write(sizeArray[i]);

                    w.Seek(4, SeekOrigin.Current);

                    if (format < 16)
                    {
                        w.Seek(4, SeekOrigin.Current);
                    }

                    if (format == 15 || format == 16)
                    {
                        w.Seek(1, SeekOrigin.Current);
                    }
                }

                if (format >= 22)
                {
                    w.Seek(0x18, SeekOrigin.Begin);
                    var sizeBytes = BitConverter.GetBytes(totalSize);
                    Array.Reverse(sizeBytes);
                    w.Write(sizeBytes);
                }
                else
                {
                    w.Seek(4, SeekOrigin.Begin);
                    var sizeBytes = BitConverter.GetBytes((uint)totalSize);
                    Array.Reverse(sizeBytes);
                    w.Write(sizeBytes);
                }
            }
        }