mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
Starting code for writing SerializedFiles
This commit is contained in:
parent
896131f828
commit
6ddb8cc2dd
@ -69,27 +69,6 @@ namespace AssetRipper.IO.Files.SerializedFiles.Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(Stream stream, SerializedFileHeader header)
|
|
||||||
{
|
|
||||||
bool swapEndianess = WriteSwapEndianess(stream, header);
|
|
||||||
EndianType endianess = swapEndianess ? EndianType.BigEndian : EndianType.LittleEndian;
|
|
||||||
using SerializedWriter writer = new SerializedWriter(stream, endianess, header.Version, UnityVersion);
|
|
||||||
Write(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool WriteSwapEndianess(Stream stream, SerializedFileHeader header)
|
|
||||||
{
|
|
||||||
if (HasEndian(header.Version))
|
|
||||||
{
|
|
||||||
stream.WriteByte(SwapEndianess ? (byte)1 : (byte)0);
|
|
||||||
return SwapEndianess;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return header.Endianess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Read(SerializedReader reader)
|
private void Read(SerializedReader reader)
|
||||||
{
|
{
|
||||||
if (HasSignature(reader.Generation))
|
if (HasSignature(reader.Generation))
|
||||||
@ -144,8 +123,12 @@ namespace AssetRipper.IO.Files.SerializedFiles.Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Write(SerializedWriter writer)
|
public void Write(SerializedWriter writer)
|
||||||
{
|
{
|
||||||
|
if (HasEndian(writer.Generation))
|
||||||
|
{
|
||||||
|
writer.Write(writer.EndianType == EndianType.BigEndian ? (byte)1 : (byte)0);
|
||||||
|
}
|
||||||
if (HasSignature(writer.Generation))
|
if (HasSignature(writer.Generation))
|
||||||
{
|
{
|
||||||
writer.WriteStringZeroTerm(UnityVersion.ToString());
|
writer.WriteStringZeroTerm(UnityVersion.ToString());
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using AssetRipper.IO.Endian;
|
using AssetRipper.IO.Endian;
|
||||||
using AssetRipper.IO.Files.Converters;
|
using AssetRipper.IO.Files.Converters;
|
||||||
|
using AssetRipper.IO.Files.SerializedFiles.IO;
|
||||||
using AssetRipper.IO.Files.SerializedFiles.Parser;
|
using AssetRipper.IO.Files.SerializedFiles.Parser;
|
||||||
using AssetRipper.IO.Files.Streams.Smart;
|
using AssetRipper.IO.Files.Streams.Smart;
|
||||||
using AssetRipper.IO.Files.Utils;
|
using AssetRipper.IO.Files.Utils;
|
||||||
@ -118,7 +119,111 @@ namespace AssetRipper.IO.Files.SerializedFiles
|
|||||||
|
|
||||||
public override void Write(Stream stream)
|
public override void Write(Stream stream)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long initialPosition = stream.Position;
|
||||||
|
using SerializedWriter writer = new(stream, EndianType, Generation, Version);
|
||||||
|
SerializedFileHeader header = new()
|
||||||
|
{
|
||||||
|
Version = Generation,
|
||||||
|
Endianess = EndianType == EndianType.BigEndian,
|
||||||
|
};
|
||||||
|
header.Write(writer);
|
||||||
|
|
||||||
|
SerializedFileMetadata metadata = new()
|
||||||
|
{
|
||||||
|
UnityVersion = Version,
|
||||||
|
TargetPlatform = Platform,
|
||||||
|
Externals = m_dependencies ?? Array.Empty<FileIdentifier>(),
|
||||||
|
Object = GetNewObjectInfoArray(m_objects),
|
||||||
|
Types = m_types ?? Array.Empty<SerializedType>(),
|
||||||
|
RefTypes = m_refTypes ?? Array.Empty<SerializedTypeReference>(),
|
||||||
|
EnableTypeTree = HasTypeTree,
|
||||||
|
};
|
||||||
|
long metadataPosition;
|
||||||
|
long metadataSize;
|
||||||
|
long objectDataPosition;
|
||||||
|
if (SerializedFileMetadata.IsMetadataAtTheEnd(Generation))
|
||||||
|
{
|
||||||
|
metadataPosition = stream.Position;
|
||||||
|
metadata.Write(writer);
|
||||||
|
metadataSize = stream.Position - metadataPosition;
|
||||||
|
AlignStream(writer);//Object data must always be aligned.
|
||||||
|
objectDataPosition = stream.Position;
|
||||||
|
WriteObjectData(writer, metadata.Object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AlignStream(writer);//Object data must always be aligned.
|
||||||
|
objectDataPosition = stream.Position;
|
||||||
|
WriteObjectData(writer, metadata.Object);
|
||||||
|
metadataPosition = stream.Position;
|
||||||
|
metadata.Write(writer);
|
||||||
|
metadataSize = stream.Position - metadataPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
long finalPosition = stream.Position;
|
||||||
|
|
||||||
|
stream.Position = initialPosition;
|
||||||
|
header.FileSize = finalPosition - initialPosition;
|
||||||
|
header.MetadataSize = metadataSize;
|
||||||
|
header.DataOffset = objectDataPosition - initialPosition;
|
||||||
|
header.Write(writer);
|
||||||
|
|
||||||
|
stream.Position = finalPosition;
|
||||||
|
|
||||||
|
static void WriteObjectData(SerializedWriter writer, ObjectInfo[] objects)
|
||||||
|
{
|
||||||
|
foreach (ObjectInfo objectInfo in objects)
|
||||||
|
{
|
||||||
|
writer.Write(objectInfo.ObjectData);
|
||||||
|
AlignStream(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ObjectInfo[] GetNewObjectInfoArray(ObjectInfo[]? objects)
|
||||||
|
{
|
||||||
|
if (objects is null)
|
||||||
|
{
|
||||||
|
return Array.Empty<ObjectInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectInfo[] newObjects = new ObjectInfo[objects.Length];
|
||||||
|
|
||||||
|
//This doesn't work correctly because ObjectInfo is not a struct, but that can be fixed later.
|
||||||
|
Array.Copy(objects, newObjects, objects.Length);
|
||||||
|
|
||||||
|
long byteStart = 0;
|
||||||
|
for (int i = 0; i < newObjects.Length; i++)
|
||||||
|
{
|
||||||
|
ObjectInfo objectInfo = newObjects[i];
|
||||||
|
objectInfo.ByteStart = byteStart;
|
||||||
|
objectInfo.ByteSize = objectInfo.ObjectData.Length;
|
||||||
|
newObjects[i] = objectInfo;
|
||||||
|
|
||||||
|
byteStart += objectInfo.ByteSize;
|
||||||
|
byteStart += 3 - (byteStart % 4);//Object data must always be aligned.
|
||||||
|
}
|
||||||
|
|
||||||
|
return newObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AlignStream(SerializedWriter writer)
|
||||||
|
{
|
||||||
|
switch (writer.BaseStream.Position % 4)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
writer.Write((byte)0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SerializedFile FromFile(string filePath)
|
public static SerializedFile FromFile(string filePath)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user