From b3e480751717045f85f041d26c27128f37ced72c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 20 Jun 2020 03:53:07 -0400 Subject: [PATCH] CUnsupportedFormatLoader: Make use of unsigned stream helpers --- .../Factory/CUnsupportedFormatLoader.cpp | 222 +++++++++--------- 1 file changed, 116 insertions(+), 106 deletions(-) diff --git a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp index 844faecf..f0114e5c 100644 --- a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp +++ b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp @@ -9,28 +9,28 @@ void CUnsupportedFormatLoader::PerformCheating(IInputStream& rFile, EGame Game, std::vector Data(rFile.Size() - rFile.Tell()); rFile.ReadBytes(Data.data(), Data.size()); - uint32 MaxIndex = (Game <= EGame::Echoes ? Data.size() - 3 : Data.size() - 7); + const uint32 MaxIndex = (Game <= EGame::Echoes ? Data.size() - 3 : Data.size() - 7); CAssetID ID; for (uint32 iByte = 0; iByte < MaxIndex; iByte++) { if (Game <= EGame::Echoes) { - ID = ( (Data[iByte+0] << 24) | - (Data[iByte+1] << 16) | - (Data[iByte+2] << 8) | - (Data[iByte+3] << 0) ); + ID = (Data[iByte + 0] << 24) | + (Data[iByte + 1] << 16) | + (Data[iByte + 2] << 8) | + (Data[iByte + 3] << 0); } else { - ID = ( ((uint64) Data[iByte+0] << 56) | - ((uint64) Data[iByte+1] << 48) | - ((uint64) Data[iByte+2] << 40) | - ((uint64) Data[iByte+3] << 32) | - ((uint64) Data[iByte+4] << 24) | - ((uint64) Data[iByte+5] << 16) | - ((uint64) Data[iByte+6] << 8) | - ((uint64) Data[iByte+7] << 0) ); + ID = (static_cast(Data[iByte + 0]) << 56) | + (static_cast(Data[iByte + 1]) << 48) | + (static_cast(Data[iByte + 2]) << 40) | + (static_cast(Data[iByte + 3]) << 32) | + (static_cast(Data[iByte + 4]) << 24) | + (static_cast(Data[iByte + 5]) << 16) | + (static_cast(Data[iByte + 6]) << 8) | + (static_cast(Data[iByte + 7]) << 0); } if (gpResourceStore->IsResourceRegistered(ID)) @@ -40,14 +40,14 @@ void CUnsupportedFormatLoader::PerformCheating(IInputStream& rFile, EGame Game, std::unique_ptr CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEntry *pEntry) { - uint32 Magic = rCAUD.ReadLong(); + [[maybe_unused]] const uint32 Magic = rCAUD.ReadULong(); ASSERT(Magic == FOURCC('CAUD')); - uint32 Version = rCAUD.ReadLong(); - EGame Game = (Version == 0x2 ? EGame::CorruptionProto : - Version == 0x9 ? EGame::Corruption : - Version == 0xE ? EGame::DKCReturns : - EGame::Invalid); + const uint32 Version = rCAUD.ReadLong(); + const EGame Game = Version == 0x2 ? EGame::CorruptionProto : + Version == 0x9 ? EGame::Corruption : + Version == 0xE ? EGame::DKCReturns : + EGame::Invalid; ASSERT(Game != EGame::Invalid && Game == pEntry->Game()); auto pMacro = std::make_unique(pEntry); @@ -59,28 +59,28 @@ std::unique_ptr CUnsupportedFormatLoader::LoadCAUD(IInputStream& rC std::list AssetList; PerformCheating(rCAUD, pEntry->Game(), AssetList); - for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++) - pMacro->mSamples.push_back(*Iter); + for (const auto& asset : AssetList) + pMacro->mSamples.push_back(asset); return pMacro; } // Skip past the rest of the header - uint32 NumVolGroups = rCAUD.ReadLong(); + const uint32 NumVolGroups = rCAUD.ReadULong(); for (uint32 iVol = 0; iVol < NumVolGroups; iVol++) rCAUD.ReadString(); - uint32 SkipAmt = (Game == EGame::CorruptionProto ? 0x10 : 0x14); + const uint32 SkipAmt = Game == EGame::CorruptionProto ? 0x10 : 0x14; rCAUD.Seek(SkipAmt, SEEK_CUR); - uint32 NumSamples = rCAUD.ReadLong(); + const uint32 NumSamples = rCAUD.ReadULong(); for (uint32 iSamp = 0; iSamp < NumSamples; iSamp++) { - uint32 SampleDataSize = rCAUD.ReadLong(); - uint32 SampleDataEnd = rCAUD.Tell() + SampleDataSize; + const uint32 SampleDataSize = rCAUD.ReadULong(); + const uint32 SampleDataEnd = rCAUD.Tell() + SampleDataSize; - CAssetID SampleID(rCAUD, Game); + const CAssetID SampleID(rCAUD, Game); ASSERT(gpResourceStore->IsResourceRegistered(SampleID) == true); pMacro->mSamples.push_back(SampleID); @@ -92,12 +92,12 @@ std::unique_ptr CUnsupportedFormatLoader::LoadCAUD(IInputStream& rC std::unique_ptr CUnsupportedFormatLoader::LoadCSNG(IInputStream& rCSNG, CResourceEntry *pEntry) { - uint32 Magic = rCSNG.ReadLong(); + [[maybe_unused]] const uint32 Magic = rCSNG.ReadULong(); ASSERT(Magic == 0x2); rCSNG.Seek(0x8, SEEK_CUR); auto pGroup = std::make_unique(pEntry); - pGroup->AddDependency(rCSNG.ReadLong()); + pGroup->AddDependency(rCSNG.ReadULong()); return pGroup; } @@ -121,65 +121,66 @@ std::unique_ptr CUnsupportedFormatLoader::LoadDUMB(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry) { - uint32 Version = rFRME.ReadLong(); + const uint32 Version = rFRME.ReadULong(); auto pGroup = std::make_unique(pEntry); // Prime 1 if (Version == 0 || Version == 1) { rFRME.Seek(0xC, SEEK_CUR); - uint32 NumWidgets = rFRME.ReadLong(); + const uint32 NumWidgets = rFRME.ReadULong(); for (uint32 iWgt = 0; iWgt < NumWidgets; iWgt++) { // Widget Header - CFourCC WidgetType = rFRME.ReadLong(); + CFourCC WidgetType = rFRME.ReadULong(); rFRME.ReadString(); rFRME.ReadString(); rFRME.Seek(0x18, SEEK_CUR); // Head Widget / Base Widget if (WidgetType == FOURCC('HWIG') || WidgetType == FOURCC('BWIG')) - {} - + { + } // Camera else if (WidgetType == FOURCC('CAMR')) { - uint32 ProjectionType = rFRME.ReadLong(); + const uint32 ProjectionType = rFRME.ReadULong(); if (ProjectionType == 0) rFRME.Seek(0x10, SEEK_CUR); else rFRME.Seek(0x18, SEEK_CUR); } - // Light else if (WidgetType == FOURCC('LITE')) { - uint32 LightType = rFRME.ReadLong(); + const uint32 LightType = rFRME.ReadULong(); rFRME.Seek(0x1C, SEEK_CUR); - if (LightType == 0) rFRME.Seek(0x4, SEEK_CUR); + if (LightType == 0) + rFRME.Seek(0x4, SEEK_CUR); } - // Meter else if (WidgetType == FOURCC('METR')) + { rFRME.Seek(0xA, SEEK_CUR); - + } // Group else if (WidgetType == FOURCC('GRUP')) + { rFRME.Seek(0x3, SEEK_CUR); - + } // Table Group else if (WidgetType == FOURCC('TBGP')) + { rFRME.Seek(0x23, SEEK_CUR); - + } // Model else if (WidgetType == FOURCC('MODL')) { pGroup->AddDependency(CAssetID(rFRME, EIDLength::k32Bit)); // CMDL rFRME.Seek(0x8, SEEK_CUR); } - // Text Pane else if (WidgetType == FOURCC('TXPN')) { @@ -193,32 +194,29 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFRME(IInputStrea rFRME.Seek(0x8, SEEK_CUR); } } - // Image Pane else if (WidgetType == FOURCC('IMGP')) { pGroup->AddDependency(CAssetID(rFRME, EIDLength::k32Bit)); // TXTR - if (rFRME.ReadLong() != 0xFFFFFFFF) DEBUG_BREAK; + if (rFRME.ReadULong() != 0xFFFFFFFF) + DEBUG_BREAK; rFRME.Seek(0x4, SEEK_CUR); - uint32 NumQuadCoords = rFRME.ReadLong(); + const uint32 NumQuadCoords = rFRME.ReadULong(); rFRME.Seek(NumQuadCoords * 0xC, SEEK_CUR); - uint32 NumUVCoords = rFRME.ReadLong(); + const uint32 NumUVCoords = rFRME.ReadULong(); rFRME.Seek(NumUVCoords * 8, SEEK_CUR); } - // Energy Bar else if (WidgetType == FOURCC('ENRG')) { pGroup->AddDependency(CAssetID(rFRME, EIDLength::k32Bit)); // TXTR } - // Slider Group else if (WidgetType == FOURCC('SLGP')) { rFRME.Seek(0x10, SEEK_CUR); } - else { errorf("Unrecognized FRME widget type: %s", *WidgetType.ToString()); @@ -236,16 +234,19 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFRME(IInputStrea else if (Version == 4 || Version == 5 || Version == 0xD || Version == 0xE || Version == 0x10) { EGame Game; - if (Version == 4) Game = EGame::Echoes; - else if (Version == 0x10) Game = EGame::DKCReturns; - else Game = EGame::Corruption; + if (Version == 4) + Game = EGame::Echoes; + else if (Version == 0x10) + Game = EGame::DKCReturns; + else + Game = EGame::Corruption; - uint32 NumDependencies = rFRME.ReadLong(); + const uint32 NumDependencies = rFRME.ReadULong(); for (uint32 iDep = 0; iDep < NumDependencies; iDep++) { rFRME.Seek(0x4, SEEK_CUR); - pGroup->AddDependency( CAssetID(rFRME, Game) ); + pGroup->AddDependency(CAssetID(rFRME, Game)); } } else @@ -259,22 +260,24 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFRME(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry) { - uint32 Magic = rFSM2.ReadLong(); + [[maybe_unused]] const uint32 Magic = rFSM2.ReadULong(); ASSERT(Magic == FOURCC('FSM2')); auto pOut = std::make_unique(pEntry); - uint32 Version = rFSM2.ReadLong(); - uint32 NumStates = rFSM2.ReadLong(); - uint32 NumUnkA = rFSM2.ReadLong(); - uint32 NumUnkB = rFSM2.ReadLong(); - uint32 NumUnkC = rFSM2.ReadLong(); + const uint32 Version = rFSM2.ReadULong(); + const uint32 NumStates = rFSM2.ReadULong(); + const uint32 NumUnkA = rFSM2.ReadULong(); + const uint32 NumUnkB = rFSM2.ReadULong(); + const uint32 NumUnkC = rFSM2.ReadULong(); ASSERT(Version == 1 || Version == 2); for (uint32 iState = 0; iState < NumStates; iState++) { rFSM2.ReadString(); - if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR); - uint32 UnkCount = rFSM2.ReadLong(); + if (Version >= 2) + rFSM2.Seek(0x10, SEEK_CUR); + + const uint32 UnkCount = rFSM2.ReadULong(); for (uint32 iUnk = 0; iUnk < UnkCount; iUnk++) { @@ -286,9 +289,10 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStrea for (uint32 iUnkA = 0; iUnkA < NumUnkA; iUnkA++) { rFSM2.ReadString(); - if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR); + if (Version >= 2) + rFSM2.Seek(0x10, SEEK_CUR); rFSM2.Seek(0x4, SEEK_CUR); - uint32 UnkCount = rFSM2.ReadLong(); + const uint32 UnkCount = rFSM2.ReadULong(); for (uint32 iUnkA2 = 0; iUnkA2 < UnkCount; iUnkA2++) { @@ -302,8 +306,9 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStrea for (uint32 iUnkB = 0; iUnkB < NumUnkB; iUnkB++) { rFSM2.ReadString(); - if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR); - uint32 UnkCount = rFSM2.ReadLong(); + if (Version >= 2) + rFSM2.Seek(0x10, SEEK_CUR); + const uint32 UnkCount = rFSM2.ReadULong(); for (uint32 iUnkB2 = 0; iUnkB2 < UnkCount; iUnkB2++) { @@ -315,8 +320,9 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStrea for (uint32 iUnkC = 0; iUnkC < NumUnkC; iUnkC++) { rFSM2.ReadString(); - if (Version >= 2) rFSM2.Seek(0x10, SEEK_CUR); - uint32 UnkCount = rFSM2.ReadLong(); + if (Version >= 2) + rFSM2.Seek(0x10, SEEK_CUR); + const uint32 UnkCount = rFSM2.ReadLong(); for (uint32 iUnkC2 = 0; iUnkC2 < UnkCount; iUnkC2++) { @@ -324,7 +330,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStrea rFSM2.Seek(0x4, SEEK_CUR); } - pOut->AddDependency( CAssetID(rFSM2, pEntry->Game()) ); + pOut->AddDependency(CAssetID(rFSM2, pEntry->Game())); } return pOut; @@ -332,7 +338,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSM2(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry) { - CFourCC Magic = rFSMC.ReadLong(); + [[maybe_unused]] const CFourCC Magic = rFSMC.ReadULong(); ASSERT(Magic == FOURCC('FSMC')); auto pGroup = std::make_unique(pEntry); @@ -348,10 +354,10 @@ std::unique_ptr CUnsupportedFormatLoader::LoadFSMC(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry) { - CFourCC Magic = rHIER.ReadLong(); + [[maybe_unused]] const CFourCC Magic = rHIER.ReadLong(); ASSERT(Magic == "HIER"); - uint32 NumNodes = rHIER.ReadLong(); + const uint32 NumNodes = rHIER.ReadULong(); auto pOut = std::make_unique(pEntry); // Note: For some reason this file still exists in MP3 and it's identical to MP2, including with 32-bit asset IDs. @@ -362,7 +368,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadHIER(IInputStrea for (uint32 iNode = 0; iNode < NumNodes; iNode++) { // NOTE: The SCAN ID isn't considered a real dependency! - pOut->AddDependency( rHIER.ReadLong() ); + pOut->AddDependency(rHIER.ReadULong()); rHIER.ReadString(); rHIER.Seek(0x8, SEEK_CUR); } @@ -372,16 +378,21 @@ std::unique_ptr CUnsupportedFormatLoader::LoadHIER(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry) { - uint32 Magic = rHINT.ReadLong(); + [[maybe_unused]] const uint32 Magic = rHINT.ReadULong(); ASSERT(Magic == 0x00BADBAD); // Determine version - uint32 Version = rHINT.ReadLong(); + const uint32 Version = rHINT.ReadULong(); EGame Game; - if (Version == 0x1) Game = EGame::Prime; - else if (Version == 0x3) Game = EGame::Corruption; - + if (Version == 0x1) + { + Game = EGame::Prime; + } + else if (Version == 0x3) + { + Game = EGame::Corruption; + } else { errorf("Unrecognized HINT version: %d", Version); @@ -390,32 +401,31 @@ std::unique_ptr CUnsupportedFormatLoader::LoadHINT(IInputStrea // Read main file auto pGroup = std::make_unique(pEntry); - uint32 NumHints = rHINT.ReadLong(); + const uint32 NumHints = rHINT.ReadULong(); for (uint32 iHint = 0; iHint < NumHints; iHint++) { rHINT.ReadString(); // Skip hint name rHINT.Seek(0x8, SEEK_CUR); // Skip unknown + appear time - pGroup->AddDependency( CAssetID(rHINT, Game) ); // Pop-up STRG + pGroup->AddDependency(CAssetID(rHINT, Game)); // Pop-up STRG rHINT.Seek(0x4, SEEK_CUR); // Skip unknowns if (Game <= EGame::Echoes) { rHINT.Seek(0x4, SEEK_CUR); - pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MLVL - pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MREA + pGroup->AddDependency(CAssetID(rHINT, Game)); // Target MLVL + pGroup->AddDependency(CAssetID(rHINT, Game)); // Target MREA rHINT.Seek(0x4, SEEK_CUR); // Skip target room index - pGroup->AddDependency( CAssetID(rHINT, Game) ); // Map STRG + pGroup->AddDependency(CAssetID(rHINT, Game)); // Map STRG } - else { - uint32 NumLocations = rHINT.ReadLong(); + const uint32 NumLocations = rHINT.ReadULong(); for (uint32 iLoc = 0; iLoc < NumLocations; iLoc++) { rHINT.Seek(0x14, SEEK_CUR); // Skip world/area ID, area index - pGroup->AddDependency( CAssetID(rHINT, Game) ); // Objective string + pGroup->AddDependency(CAssetID(rHINT, Game)); // Objective string rHINT.Seek(0xC, SEEK_CUR); // Skip unknown data } } @@ -430,7 +440,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMA TResPtr pMap = ptr.get(); // We don't actually read the file. Just fetch the name string so we can build the dependency tree. - CAssetID MapAreaID = pMap->ID(); + const CAssetID MapAreaID = pMap->ID(); // Find a MapWorld that contains this MapArea CAssetID MapWorldID; @@ -438,7 +448,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMA for (TResourceIterator It; It; ++It) { - CDependencyGroup *pGroup = (CDependencyGroup*) It->Load(); + auto *pGroup = static_cast(It->Load()); for (size_t AreaIdx = 0; AreaIdx < pGroup->NumDependencies(); AreaIdx++) { @@ -459,13 +469,13 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMA { for (TResourceIterator It; It; ++It) { - CWorld *pWorld = (CWorld*) It->Load(); - CDependencyGroup *pMapWorld = (CDependencyGroup*) pWorld->MapWorld(); + auto *pWorld = static_cast(It->Load()); + auto *pMapWorld = static_cast(pWorld->MapWorld()); - if (pMapWorld && pMapWorld->ID() == MapWorldID) + if (pMapWorld != nullptr && pMapWorld->ID() == MapWorldID) { CStringTable *pNameString = pWorld->AreaName(WorldIndex); - pMap->mNameString = (pNameString ? pNameString->ID() : CAssetID::InvalidID(pEntry->Game())); + pMap->mNameString = (pNameString != nullptr ? pNameString->ID() : CAssetID::InvalidID(pEntry->Game())); break; } } @@ -477,18 +487,18 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPA(IInputStream& /*rMA std::unique_ptr CUnsupportedFormatLoader::LoadMAPW(IInputStream& rMAPW, CResourceEntry *pEntry) { - uint32 Magic = rMAPW.ReadLong(); + [[maybe_unused]] const uint32 Magic = rMAPW.ReadULong(); ASSERT(Magic == 0xDEADF00D); - uint32 Version = rMAPW.ReadLong(); + [[maybe_unused]] const uint32 Version = rMAPW.ReadULong(); ASSERT(Version == 1); - uint32 NumAreas = rMAPW.ReadLong(); + const uint32 NumAreas = rMAPW.ReadULong(); // Version check - uint32 AreasStart = rMAPW.Tell(); + const uint32 AreasStart = rMAPW.Tell(); rMAPW.Seek(NumAreas * 4, SEEK_CUR); - const auto IDLength = (rMAPW.EoF() || rMAPW.ReadLong() == 0xFFFFFFFF ? EIDLength::k32Bit : EIDLength::k64Bit); + const auto IDLength = (rMAPW.EoF() || rMAPW.ReadULong() == 0xFFFFFFFF ? EIDLength::k32Bit : EIDLength::k64Bit); rMAPW.Seek(AreasStart, SEEK_SET); // Read MAPA IDs @@ -502,24 +512,24 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPW(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadMAPU(IInputStream& rMAPU, CResourceEntry *pEntry) { - uint32 Magic = rMAPU.ReadLong(); + [[maybe_unused]] const uint32 Magic = rMAPU.ReadULong(); ASSERT(Magic == 0xABCDEF01); - uint32 Version = rMAPU.ReadLong(); + [[maybe_unused]] const uint32 Version = rMAPU.ReadULong(); ASSERT(Version == 0x1); auto pGroup = std::make_unique(pEntry); - pGroup->AddDependency(rMAPU.ReadLong()); + pGroup->AddDependency(rMAPU.ReadULong()); // Read worlds - uint32 NumWorlds = rMAPU.ReadLong(); + const uint32 NumWorlds = rMAPU.ReadULong(); for (uint32 iWorld = 0; iWorld < NumWorlds; iWorld++) { rMAPU.ReadString(); // Skip world name - pGroup->AddDependency(rMAPU.ReadLong()); // World MLVL + pGroup->AddDependency(rMAPU.ReadULong()); // World MLVL rMAPU.Seek(0x30, SEEK_CUR); // Skip world map transform - uint32 NumHexagons = rMAPU.ReadLong(); + const uint32 NumHexagons = rMAPU.ReadULong(); rMAPU.Seek(NumHexagons * 0x30, SEEK_CUR); // Skip hexagon transforms rMAPU.Seek(0x10, SEEK_CUR); // Skip world color } @@ -530,7 +540,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadMAPU(IInputStrea std::unique_ptr CUnsupportedFormatLoader::LoadRULE(IInputStream& rRULE, CResourceEntry *pEntry) { // RULE files can contain a reference to another RULE file, but has no other dependencies. - const uint32 Magic = rRULE.ReadLong(); + [[maybe_unused]] const uint32 Magic = rRULE.ReadULong(); ASSERT(Magic == FOURCC('RULE')); auto pGroup = std::make_unique(pEntry); @@ -539,7 +549,7 @@ std::unique_ptr CUnsupportedFormatLoader::LoadRULE(IInputStrea // Version test const uint32 IDOffset = rRULE.Tell(); rRULE.Seek(0x4, SEEK_CUR); - const uint32 RuleSetCount = rRULE.ReadShort(); + const uint32 RuleSetCount = rRULE.ReadUShort(); const auto IDLength = (RuleSetCount > 0xFF ? EIDLength::k64Bit : EIDLength::k32Bit); rRULE.Seek(IDOffset, SEEK_SET);