internal STFSDescriptor(byte[] xDescriptor, uint xTotalBlocks, uint xOldBlocks, byte xType) { xStruct = xDescriptor; XSetStructure((STFSType)(xType & 1)); TopRecord = new BlockRecord(((uint)(xType >> 1) << 30 | xOldBlocks << 15)); if (xTotalBlocks > SpaceBetween[2]) { xStruct = null; return; } xBlockCount = xTotalBlocks; xBaseByte = (byte)((ThisType == STFSType.Type0) ? 0xB : 0xA); }
internal STFSDescriptor(STFSPackage xPackage) { xPackage.xIO.Position = 0x340; xPackage.xIO.IsBigEndian = true; var xBlockInfo = xPackage.xIO.ReadInt32(); xBaseByte = (byte)(((xBlockInfo + 0xFFF) & 0xF000) >> 0xC); xPackage.xIO.Position = 0x379; if (xPackage.xIO.ReadByte() != 0x24) // Struct Size { throw STFSExcepts.Type; } if (xPackage.xIO.ReadByte() != 0) // Reversed { throw STFSExcepts.Type; } /* STRUCT OF THE NEXT 6 BYTES: * byte for block separation * Little Endian File Table block count short (2 bytes) * 3 bytes in Little Endian for the starting block of the File Table */ var idx = (byte)(xPackage.xIO.ReadByte() & 3); xStruct = xPackage.xIO.ReadBytes(5); xPackage.xIO.Position = 0x395; xBlockCount = xPackage.xIO.ReadUInt32(); var xOldBlocks = xPackage.xIO.ReadUInt32(); // Checks the type of Structure switch (xBaseByte) { case 0xB: if (idx == 1) { XSetStructure(STFSType.Type0); } else { throw STFSExcepts.Type; } break; case 0xA: if (idx == 0 || idx == 2) { XSetStructure(STFSType.Type1); } else { throw STFSExcepts.Type; } break; default: throw STFSExcepts.Type; } if (xBlockCount > SpaceBetween[2]) { throw STFSExcepts.MaxOver; } TopRecord = new BlockRecord(((uint)((idx >> 1) & 1) << 30 | xOldBlocks << 15)); // Grab Real Block Count for (var i = (xBlockCount - 1); ; i--) { xBlockCount = (i + 1); if (GenerateDataOffset(i) < xPackage.xIO.Length) { break; } } }