mirror of
https://github.com/StarBeat/UnityDependencyAnalyzer.git
synced 2026-03-08 05:35:27 +08:00
139 lines
4.2 KiB
C#
139 lines
4.2 KiB
C#
|
|
using System;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Text;
|
|||
|
|
using Force.Crc32;
|
|||
|
|
namespace UnityFileApi
|
|||
|
|
{
|
|||
|
|
// This class can be used to read typed data from a UnityFile. Is uses a buffer for better performance.
|
|||
|
|
public class UnityFileReader : IDisposable
|
|||
|
|
{
|
|||
|
|
UnityFile m_File;
|
|||
|
|
byte[] m_Buffer;
|
|||
|
|
long m_BufferStartInFile;
|
|||
|
|
long m_BufferEndInFile;
|
|||
|
|
|
|||
|
|
public long Length { get; }
|
|||
|
|
|
|||
|
|
public UnityFileReader(string path, int bufferSize)
|
|||
|
|
{
|
|||
|
|
m_Buffer = new byte[bufferSize];
|
|||
|
|
m_BufferStartInFile = 0;
|
|||
|
|
m_BufferEndInFile = 0;
|
|||
|
|
|
|||
|
|
m_File = UnityFileSystem.OpenFile(path);
|
|||
|
|
Length = m_File.GetSize();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int GetBufferOffset(long fileOffset, int count)
|
|||
|
|
{
|
|||
|
|
// Should we update the buffer?
|
|||
|
|
if (fileOffset < m_BufferStartInFile || fileOffset + count > m_BufferEndInFile)
|
|||
|
|
{
|
|||
|
|
if (count > m_Buffer.Length)
|
|||
|
|
throw new IOException("Requested size is larger than cache size");
|
|||
|
|
|
|||
|
|
m_BufferStartInFile = m_File.Seek(fileOffset);
|
|||
|
|
|
|||
|
|
if (m_BufferStartInFile != fileOffset)
|
|||
|
|
throw new IOException("Invalid file offset");
|
|||
|
|
|
|||
|
|
m_BufferEndInFile = m_File.Read(m_Buffer.Length, m_Buffer);
|
|||
|
|
m_BufferEndInFile += m_BufferStartInFile;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (int)(fileOffset - m_BufferStartInFile);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ReadArray(long fileOffset, int size, Array dest)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, size);
|
|||
|
|
Buffer.BlockCopy(m_Buffer, offset, dest, 0, size);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public string ReadString(long fileOffset, int size)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, size);
|
|||
|
|
return Encoding.Default.GetString(m_Buffer, offset, size);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public float ReadFloat(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 4);
|
|||
|
|
return BitConverter.ToSingle(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public double ReadDouble(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 8);
|
|||
|
|
return BitConverter.ToDouble(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public long ReadInt64(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 8);
|
|||
|
|
return BitConverter.ToInt64(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public ulong ReadUInt64(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 8);
|
|||
|
|
return BitConverter.ToUInt64(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public int ReadInt32(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 4);
|
|||
|
|
return BitConverter.ToInt32(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public uint ReadUInt32(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 4);
|
|||
|
|
return BitConverter.ToUInt32(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public short ReadInt16(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 2);
|
|||
|
|
return BitConverter.ToInt16(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public ushort ReadUInt16(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 2);
|
|||
|
|
return BitConverter.ToUInt16(m_Buffer, offset);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public sbyte ReadInt8(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 1);
|
|||
|
|
return (sbyte)m_Buffer[offset];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public byte ReadUInt8(long fileOffset)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, 1);
|
|||
|
|
return m_Buffer[offset];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public uint ComputeCRC(long fileOffset, int size, uint crc32 = 0)
|
|||
|
|
{
|
|||
|
|
var readSize = size > m_Buffer.Length ? m_Buffer.Length : size;
|
|||
|
|
var readBytes = 0;
|
|||
|
|
|
|||
|
|
while (readBytes < size)
|
|||
|
|
{
|
|||
|
|
var offset = GetBufferOffset(fileOffset, readSize);
|
|||
|
|
crc32 = Crc32Algorithm.Append(crc32, m_Buffer, offset, readSize);
|
|||
|
|
readBytes += readSize;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return crc32;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Dispose()
|
|||
|
|
{
|
|||
|
|
m_File.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|