private static string?ReadString(DuplicatableStream s, uint maxBytes, EndianUtils.Endianness e) { if (maxBytes < 8) { // can't be a valid string s.DiscardBytes(maxBytes); return(null); } ulong rawlength = s.ReadUInt64(e); ulong length = (rawlength & 0x7ffffffffffffffful); bool hasOffset = (rawlength & 0x8000000000000000ul) > 0; if (hasOffset) { // format is 8 bytes length, then 8 bytes position of string in data if (maxBytes < 16) { // can't be valid s.DiscardBytes(maxBytes - 8); return(null); } ulong offset = s.ReadUInt64(e); long p = s.Position + (maxBytes - 16); s.Position = (long)offset; string str = s.ReadSizedString((long)length, TextUtils.GameTextEncoding.UTF8); s.Position = p; return(str); } else { // format is 8 bytes length, then [number read] bytes string uint restBytes = maxBytes - 8; if (length > restBytes) { // can't be a valid string s.DiscardBytes(restBytes); return(null); } string str = s.ReadSizedString((long)length, TextUtils.GameTextEncoding.UTF8); s.DiscardBytes(restBytes - length); return(str); } }
private bool LoadFile(DuplicatableStream inputStream, EndianUtils.Endianness?endianParam, TextUtils.GameTextEncoding encoding) { DuplicatableStream stream = inputStream.Duplicate(); stream.Position = 0; EndianUtils.Endianness endian; if (endianParam == null) { uint magic = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian); if (magic == 0x53453320) { endian = EndianUtils.Endianness.BigEndian; } else if (magic == 0x20334553) { endian = EndianUtils.Endianness.LittleEndian; } else { Console.WriteLine("Invalid magic: " + magic); return(false); } } else { endian = endianParam.Value; uint magic = stream.ReadUInt32(endian); if (magic != 0x53453320) { Console.WriteLine("Invalid magic: " + magic); return(false); } } this.Endian = endian; uint lengthOfFilenameSection = stream.ReadUInt32(endian); // probably? uint startOfFilenameSection = stream.ReadUInt32(endian); // probably? DataBegin = stream.ReadUInt32(endian); stream.Position = startOfFilenameSection; uint magicOfFilenameSection = stream.ReadUInt32(endian); FileCount = stream.ReadUInt32(endian); Filenames = new List <string>((int)FileCount); for (uint i = 0; i < FileCount; ++i) { Filenames.Add(stream.ReadSizedString(48, encoding).TrimNull()); } Data = stream; return(true); }