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(); }
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); } }
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); } } }