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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
writer.WriteStringZeroTerm(UnityVersion.ToString());
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using AssetRipper.IO.Endian;
|
||||
using AssetRipper.IO.Files.Converters;
|
||||
using AssetRipper.IO.Files.SerializedFiles.IO;
|
||||
using AssetRipper.IO.Files.SerializedFiles.Parser;
|
||||
using AssetRipper.IO.Files.Streams.Smart;
|
||||
using AssetRipper.IO.Files.Utils;
|
||||
@ -118,7 +119,111 @@ namespace AssetRipper.IO.Files.SerializedFiles
|
||||
|
||||
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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user