OpenClonk
C4GroupEx Class Reference
Inheritance diagram for C4GroupEx:
[legend]
Collaboration diagram for C4GroupEx:
[legend]

Public Member Functions

void SetHead (C4Group &rByGrp)
 
bool HeadIdentical (C4Group &rByGrp, bool fLax)
 
void SaveEntryCore (C4Group &rByGrp, const char *szEntry)
 
void SetSavedEntryCore (const char *szEntry)
 
void SetNoSort (const char *szEntry)
 
bool Close (bool fHeaderUpdate)
 
bool Open (const char *group_name, bool do_create=false)
 
bool Close ()
 
bool Save (bool reopen)
 
bool OpenAsChild (C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
 
bool OpenChild (const char *entry_name)
 
bool OpenMother ()
 
bool Add (const char *filename, const char *entry_name)
 
bool Add (const char *entry_name, void *buffer, int size, bool add_as_child=false, bool hold_buffer=false, bool is_executable=false)
 
bool Add (const char *entry_name, StdBuf &buffer, bool add_as_child=false, bool hold_buffer=false, bool is_executable=false)
 
bool Add (const char *entry_name, StdStrBuf &buffer, bool add_as_child=false, bool hold_buffer=false, bool is_executable=false)
 
bool Merge (const char *folders)
 
bool Move (const char *filename, const char *entry_name)
 
bool Extract (const char *files, const char *destination=nullptr, const char *exclude=nullptr)
 
bool ExtractEntry (const char *filename, const char *destination=nullptr)
 
bool Delete (const char *files, bool recursive=false)
 
bool DeleteEntry (const char *filename, bool do_recycle=false)
 
bool Rename (const char *filename, const char *new_name)
 
bool Sort (const char *list)
 
bool SortByList (const char **list, const char *filename=nullptr)
 
bool AccessEntry (const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool needs_to_be_a_group=false)
 
bool AccessNextEntry (const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool start_at_filename=false)
 
bool LoadEntry (const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
 
bool LoadEntry (const char *entry_name, StdBuf *buffer)
 
bool LoadEntry (const StdStrBuf &name, StdBuf *buffer)
 
bool LoadEntryString (const char *entry_name, StdStrBuf *buffer)
 
bool LoadEntryString (const StdStrBuf &name, StdStrBuf *buffer)
 
bool FindEntry (const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
 
bool FindEntry (const char *wildcard, char *filename)
 
bool FindNextEntry (const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
 
bool FindNextEntry (const char *wildcard, char *filename, size_t *size=nullptr, bool start_at_filename=false)
 
bool Read (void *buffer, size_t size) override
 
bool Advance (int offset) override
 
void SetStdOutput (bool log_status)
 
void ResetSearch (bool reload_contents=false)
 
const char * GetError ()
 
const char * GetName () const
 
StdStrBuf GetFullName () const
 
int EntryCount (const char *wildcard=nullptr)
 
size_t EntrySize (const char *wildcard=nullptr)
 
size_t AccessedEntrySize () const override
 
unsigned int EntryCRC32 (const char *wildcard=nullptr)
 
bool IsOpen () const
 
C4GroupGetMother ()
 
bool IsPacked () const
 
bool HasPackedMother () const
 
bool SetNoSort (bool no_sorting)
 
int PreCacheEntries (const char *search_pattern, bool cache_previous=false)
 
const C4GroupHeaderGetHeader () const
 
const C4GroupEntryGetFirstEntry () const
 

Public Attributes

C4GroupEntryCore SavedCore
 

Protected Member Functions

C4GroupEntryGetEntry (const char *entry_name)
 
void Clear ()
 

Protected Attributes

C4GroupHeader Head
 

Detailed Description

Definition at line 165 of file C4Update.cpp.

Member Function Documentation

◆ AccessedEntrySize()

size_t C4Group::AccessedEntrySize ( ) const
overridevirtualinherited

Implements CStdStream.

Definition at line 2352 of file C4Group.cpp.

2352 { return p->iCurrFileSize; }

◆ AccessEntry()

bool C4Group::AccessEntry ( const char *  wildcard,
size_t *  size = nullptr,
char *  filename = nullptr,
bool  needs_to_be_a_group = false 
)
inherited

Definition at line 2104 of file C4Group.cpp.

2108 {
2109 #ifdef C4GROUP_DUMP_ACCESS
2110  LogF("Group access in %s: %s", GetFullName().getData(), wildcard);
2111 #endif
2112  StdStrBuf fname;
2113  if (!FindEntry(wildcard,&fname,&p->iCurrFileSize))
2114  {
2115  return false;
2116  }
2117 #ifdef _DEBUG
2118  szCurrAccessedEntry = fname.getMData();
2119 #endif
2120  bool okay = SetFilePtr2Entry(fname.getData(), needs_to_be_a_group);
2121 #ifdef _DEBUG
2122  p->sPrevAccessedEntry.Copy(szCurrAccessedEntry);
2123  szCurrAccessedEntry = nullptr;
2124 #endif
2125  if (!okay)
2126  {
2127  return false;
2128  }
2129  if (filename)
2130  {
2131  SCopy(fname.getData(),filename);
2132  }
2133  if (size)
2134  {
2135  *size = p->iCurrFileSize;
2136  }
2137  return true;
2138 }
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
Definition: C4Group.cpp:2211
const char * getData() const
Definition: StdBuf.h:442
char * getMData()
Definition: StdBuf.h:443

References C4Group::FindEntry(), StdStrBuf::getData(), C4Group::GetFullName(), StdStrBuf::getMData(), LogF(), and SCopy().

Referenced by C4Group_ReadFile(), C4Landscape::P::CreateMapS2(), C4MassMoverSet::Load(), C4PXSSystem::Load(), C4Surface::Load(), C4PlayerInfo::LoadBigIcon(), C4Group::LoadEntry(), C4Group::LoadEntryString(), C4DefAdditionalResourcesLoader::LoadTexture(), and C4MCParser::ParseFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AccessNextEntry()

bool C4Group::AccessNextEntry ( const char *  wildcard,
size_t *  size = nullptr,
char *  filename = nullptr,
bool  start_at_filename = false 
)
inherited

Definition at line 2140 of file C4Group.cpp.

2144 {
2145  char entry_name[_MAX_FNAME_LEN];
2146  if (!FindNextEntry(wildcard, entry_name, &p->iCurrFileSize, start_at_filename))
2147  {
2148  return false;
2149  }
2150 #ifdef _DEBUG
2151  szCurrAccessedEntry = filename;
2152 #endif
2153  bool okay = SetFilePtr2Entry(entry_name);
2154 #ifdef _DEBUG
2155  szCurrAccessedEntry = nullptr;
2156 #endif
2157  if (!okay)
2158  {
2159  return false;
2160  }
2161  if (filename)
2162  {
2163  SCopy(entry_name, filename);
2164  }
2165  if (size)
2166  {
2167  *size = p->iCurrFileSize;
2168  }
2169  return true;
2170 }
#define _MAX_FNAME_LEN
bool FindNextEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
Definition: C4Group.cpp:2217

References _MAX_FNAME_LEN, C4Group::FindNextEntry(), and SCopy().

Referenced by C4TextureMap::LoadTextures().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Add() [1/4]

bool C4Group::Add ( const char *  entry_name,
StdBuf buffer,
bool  add_as_child = false,
bool  hold_buffer = false,
bool  is_executable = false 
)
inherited

Definition at line 2262 of file C4Group.cpp.

2263 {
2264  if (!AddEntry(C4GroupEntry::C4GRES_InMemory,
2265  add_as_child,
2266  entry_name,
2267  buffer.getSize(),
2268  entry_name,
2269  (BYTE*) buffer.getMData(),
2270  false,
2271  hold_buffer,
2272  is_executable,
2273  true))
2274  {
2275  return false;
2276  }
2277  // Pointer is now owned and released by C4Group!
2278  if (hold_buffer)
2279  {
2280  buffer.GrabPointer();
2281  }
2282  return true;
2283 }
uint8_t BYTE
@ C4GRES_InMemory
Definition: C4Group.h:118
size_t getSize() const
Definition: StdBuf.h:101
void * GrabPointer()
Definition: StdBuf.h:133
void * getMData()
Definition: StdBuf.h:100

References C4GroupEntry::C4GRES_InMemory, StdBuf::getMData(), StdBuf::getSize(), and StdBuf::GrabPointer().

Here is the call graph for this function:

◆ Add() [2/4]

bool C4Group::Add ( const char *  entry_name,
StdStrBuf buffer,
bool  add_as_child = false,
bool  hold_buffer = false,
bool  is_executable = false 
)
inherited

Definition at line 2285 of file C4Group.cpp.

2286 {
2287  if (!AddEntry(C4GroupEntry::C4GRES_InMemory,
2288  add_as_child,
2289  entry_name,
2290  buffer.getLength(),
2291  entry_name,
2292  (BYTE*) buffer.getMData(),
2293  false,
2294  hold_buffer,
2295  is_executable,
2296  true))
2297  {
2298  return false;
2299  }
2300  // Pointer is now owned and released by C4Group!
2301  if (hold_buffer)
2302  {
2303  buffer.GrabPointer();
2304  }
2305  return true;
2306 }
size_t getLength() const
Definition: StdBuf.h:445
char * GrabPointer()
Definition: StdBuf.h:459

References C4GroupEntry::C4GRES_InMemory, StdStrBuf::getLength(), StdStrBuf::getMData(), and StdStrBuf::GrabPointer().

Here is the call graph for this function:

◆ Add() [3/4]

bool C4Group::Add ( const char *  entry_name,
void *  buffer,
int  size,
bool  add_as_child = false,
bool  hold_buffer = false,
bool  is_executable = false 
)
inherited

Definition at line 2249 of file C4Group.cpp.

2250 {
2251  return AddEntry(C4GroupEntry::C4GRES_InMemory,
2252  add_as_child,
2253  entry_name,
2254  size,
2255  entry_name,
2256  (BYTE*) buffer,
2257  false,
2258  hold_buffer,
2259  is_executable);
2260 }

References C4GroupEntry::C4GRES_InMemory.

◆ Add() [4/4]

bool C4Group::Add ( const char *  filename,
const char *  entry_name 
)
inherited

Definition at line 1621 of file C4Group.cpp.

1622 {
1623  bool move = false;
1624 
1625  if (p->LogToStdOutput)
1626  {
1627  printf("%s %s as %s...\n", move ? "Moving" : "Adding", GetFilename(filename), entry_name);
1628  }
1629 
1630  return AddEntryOnDisk(filename, entry_name, move);
1631 }
char * GetFilename(char *szPath)
Definition: StdFile.cpp:42

References GetFilename().

Referenced by C4Record::AddFile(), C4ControlReInitScenario::C4ControlReInitScenario(), C4Group_CopyEntry(), C4Group_PackDirectoryTo(), C4UpdatePackage::MkUp(), C4UpdatePackageCore::Save(), C4TeamList::Save(), C4MassMoverSet::Save(), C4Def::Save(), C4PlayerInfoCore::Save(), C4Scenario::Save(), C4GameParameters::Save(), C4ObjectInfoCore::Save(), C4PlayerControlFile::Save(), C4RoundResults::Save(), C4PlayerInfoList::Save(), C4Game::SaveData(), C4GameSave::SaveDesc(), C4MaterialMap::SaveEnumeration(), C4Game::SaveGameTitle(), C4TextureMap::SaveMap(), C4ScenarioListLoader::Entry::SetTitleInGroup(), and C4Playback::StreamToRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Advance()

bool C4Group::Advance ( int  offset)
overridevirtualinherited

Implements CStdStream.

Definition at line 1410 of file C4Group.cpp.

1411 {
1412  assert(offset >= 0);
1413  // cached advance
1414  if (p->pInMemEntry)
1415  {
1416  if (p->iInMemEntrySize < size_t(offset)) return false;
1417  p->iInMemEntrySize -= offset;
1418  p->pInMemEntry += offset;
1419  return true;
1420  }
1421  // uncached advance
1422  if (p->SourceType == P::ST_Unpacked) return !!p->StdFile.Advance(offset);
1423  // FIXME: reading the file one byte at a time sounds just slow.
1424  BYTE buf;
1425  for (; offset>0; offset--)
1426  if (!Read(&buf, 1)) return false;
1427  return true;
1428 }
bool Read(void *buffer, size_t size) override
Definition: C4Group.cpp:1430

References C4Group::Read(), and C4Group::P::ST_Unpacked.

Here is the call graph for this function:

◆ Clear()

void C4Group::Clear ( )
protectedinherited

Definition at line 1173 of file C4Group.cpp.

1174 {
1175  if (p)
1176  {
1177  // Delete entries
1178  C4GroupEntry *next;
1179  while (p->FirstEntry)
1180  {
1181  next = p->FirstEntry->Next;
1182  delete p->FirstEntry;
1183  p->FirstEntry = next;
1184  }
1185  // Close std file
1186  p->StdFile.Close();
1187  // Delete mother
1188  if (p->Mother && p->ExclusiveChild)
1189  {
1190  delete p->Mother;
1191  p->Mother = nullptr;
1192  }
1193  }
1194  // Reset
1195  Init();
1196 }
Definition: C4Group.h:110

Referenced by C4Group::Close(), Close(), C4Group::Open(), C4Group::OpenAsChild(), C4Group::OpenMother(), C4Group::Save(), and C4Group::~C4Group().

Here is the caller graph for this function:

◆ Close() [1/2]

bool C4Group::Close ( )
inherited

Definition at line 971 of file C4Group.cpp.

972 {
973  bool rewrite = false;
974 
975  if (p->SourceType == P::ST_None)
976  {
977  return false;
978  }
979 
980  // Folder: just close
981  if (p->SourceType == P::ST_Unpacked)
982  {
983  CloseExclusiveMother();
984  Clear();
985  return true;
986  }
987 
988  // Rewrite check
989  for (C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
990  {
991  if (entry->Status != C4GroupEntry::C4GRES_InGroup)
992  {
993  rewrite = true;
994  }
995  }
996  if (p->Modified)
997  {
998  rewrite = true;
999  }
1000 
1001  // No rewrite: just close
1002  if (!rewrite)
1003  {
1004  CloseExclusiveMother();
1005  Clear();
1006  return true;
1007  }
1008 
1009  if (p->LogToStdOutput)
1010  {
1011  printf("Writing group file...\n");
1012  }
1013 
1014  // Set new version
1017 
1018  // Automatic sort
1020 
1021  // Save group contents to disk
1022  bool success = Save(false);
1023 
1024  // Close files
1025  CloseExclusiveMother();
1026  Clear();
1027 
1028  return !!success;
1029 }
const char ** C4Group_SortList
Definition: C4Group.cpp:61
const int C4GroupFileVer2
Definition: C4Group.h:56
const int C4GroupFileVer1
Definition: C4Group.h:55
@ C4GRES_InGroup
Definition: C4Group.h:116
void Clear()
Definition: C4Group.cpp:1173
bool Save(bool reopen)
Definition: C4Group.cpp:1031
C4GroupHeader Head
Definition: C4Group.h:147
bool SortByList(const char **list, const char *filename=nullptr)
Definition: C4Group.cpp:2566

References C4GroupEntry::C4GRES_InGroup, C4Group_SortList, C4GroupFileVer1, C4GroupFileVer2, C4Group::Clear(), C4Group::Head, C4Group::Save(), C4Group::SortByList(), C4Group::P::ST_None, C4Group::P::ST_Unpacked, C4GroupHeader::Ver1, and C4GroupHeader::Ver2.

Referenced by C4MainMenu::ActivateNewPlayer(), C4Group_ApplyUpdate(), C4Group_CopyItem(), C4Group_DeleteItem(), C4Group_IsGroup(), C4Group_MoveItem(), C4Group_PackDirectoryTo(), C4Group_ReadFile(), C4Group_UnpackDirectory(), C4UpdatePackage::Check(), C4Language::Clear(), C4SoundSystem::Clear(), C4Application::Clear(), C4GameSave::Close(), Close(), C4Game::CloseScenario(), C4Application::CloseSystemGroup(), DefFileGetID(), C4Group::Delete(), C4ScenarioSection::EnsureTempStore(), C4LoaderScreen::Init(), C4DefList::Load(), C4ObjectInfo::Load(), C4Player::Load(), C4StartupPlrSelDlg::PlayerListItem::Load(), C4Game::LoadAdditionalSystemGroup(), C4GameResList::LoadFoldersWithLocalDefs(), C4Game::LoadScenarioSection(), C4StartupPlrPropertiesDlg::OnClosed(), C4Network2Res::OptimizeStandalone(), ProcessGroup(), C4Shader::Refresh(), C4DefList::Reload(), C4ScenarioListLoader::Entry::RenameTo(), C4Network2::RetrieveScenario(), C4Player::Save(), C4ObjectInfo::Save(), C4PlayerList::Save(), C4Console::SaveScenario(), C4Landscape::SaveTextures(), C4Record::Stop(), C4Playback::StreamToRecord(), C4ControlJoinPlayer::Strip(), C4Player::Strip(), and C4StartupPlrSelDlg::PlayerListItem::UpdateCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Close() [2/2]

bool C4GroupEx::Close ( bool  fHeaderUpdate)
inline

Definition at line 222 of file C4Update.cpp.

223  {
224  if (fHeaderUpdate) return C4Group::Close(); else { bool fSuccess = Save(false); Clear(); return fSuccess; }
225  }
bool Close()
Definition: C4Group.cpp:971

References C4Group::Clear(), C4Group::Close(), and C4Group::Save().

Referenced by C4UpdatePackage::DoUpdate(), C4UpdatePackage::Execute(), C4UpdatePackage::MakeUpdate(), C4UpdatePackage::MkUp(), and C4UpdatePackage::Optimize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Delete()

bool C4Group::Delete ( const char *  files,
bool  recursive = false 
)
inherited

Definition at line 1645 of file C4Group.cpp.

1646 {
1647  int fcount = 0;
1648  C4GroupEntry *tentry;
1649 
1650  // Segmented file specs
1651  if (SCharCount(';', files) || SCharCount('|', files))
1652  {
1653  char cSeparator = (SCharCount(';', files) ? ';' : '|');
1654  bool success = true;
1655  char filespec[_MAX_FNAME_LEN];
1656  for (int cseg = 0; SCopySegment(files, cseg, filespec, cSeparator, _MAX_FNAME); cseg++)
1657  if (!Delete(filespec, recursive))
1658  success = false;
1659  return success; // Would be nicer to return the file count and add up all counts from recursive actions...
1660  }
1661 
1662  // Delete all matching Entries
1663  ResetSearch();
1664  while ((tentry = SearchNextEntry(files)))
1665  {
1666  // StdOutput
1667  if (p->LogToStdOutput) printf("%s\n",tentry->FileName);
1668  if (!DeleteEntry(tentry->FileName))
1669  return Error("Delete: Could not delete entry");
1670  fcount++;
1671  }
1672 
1673  // Recursive: process sub groups
1674  if (recursive)
1675  {
1676  C4Group hChild;
1677  ResetSearch();
1678  while ((tentry = SearchNextEntry("*")))
1679  if (tentry->ChildGroup)
1680  if (hChild.OpenAsChild(this, tentry->FileName))
1681  {
1682  hChild.SetStdOutput(p->LogToStdOutput);
1683  hChild.Delete(files, recursive);
1684  hChild.Close();
1685  }
1686  }
1687 
1688  // StdOutput
1689  if (p->LogToStdOutput)
1690  printf("%d file(s) deleted.\n",fcount);
1691 
1692  return true; // Would be nicer to return the file count and add up all counts from recursive actions...
1693 }
#define _MAX_FNAME
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil)
Definition: Standard.cpp:326
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:279
bool DeleteEntry(const char *filename, bool do_recycle=false)
Definition: C4Group.cpp:1695
bool OpenAsChild(C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
Definition: C4Group.cpp:1952
void SetStdOutput(bool log_status)
Definition: C4Group.cpp:655
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1316
bool Delete(const char *files, bool recursive=false)
Definition: C4Group.cpp:1645
char FileName[260]
Definition: C4Group.h:94
int32_t ChildGroup
Definition: C4Group.h:96

References _MAX_FNAME, _MAX_FNAME_LEN, C4GroupEntryCore::ChildGroup, C4Group::Close(), C4Group::Delete(), C4Group::DeleteEntry(), C4GroupEntryCore::FileName, C4Group::OpenAsChild(), C4Group::ResetSearch(), SCharCount(), SCopySegment(), and C4Group::SetStdOutput().

Referenced by C4Group::Delete(), C4ScenarioSection::EnsureTempStore(), C4StartupPlrPropertiesDlg::OnClosed(), C4Network2Res::OptimizeStandalone(), C4ScenarioListLoader::Entry::RenameTo(), C4MassMoverSet::Save(), C4PXSSystem::Save(), C4PlayerInfoCore::Save(), C4ObjectInfo::Save(), C4GameSave::Save(), C4Game::SaveData(), C4ControlJoinPlayer::Strip(), and C4Player::Strip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteEntry()

bool C4Group::DeleteEntry ( const char *  filename,
bool  do_recycle = false 
)
inherited

Definition at line 1695 of file C4Group.cpp.

1696 {
1697  switch (p->SourceType)
1698  {
1699  case P::ST_Packed:
1700  // Get entry
1701  C4GroupEntry *pEntry;
1702  if (!(pEntry = GetEntry(filename))) return false;
1703  // Delete moved source files
1704  if (pEntry->Status == C4GroupEntry::C4GRES_OnDisk)
1705  if (pEntry->DeleteOnDisk)
1706  {
1707  EraseItem(pEntry->DiskPath);
1708  }
1709  // (moved buffers are deleted by ~C4GroupEntry)
1710  // Delete status and update virtual file count
1712  Head.Entries--;
1713  break;
1714  case P::ST_Unpacked:
1715  p->StdFile.Close();
1716  char path[_MAX_FNAME_LEN];
1717  sprintf(path,"%s%c%s", GetName(),DirectorySeparator, filename);
1718 
1719  if (do_recycle)
1720  {
1721  if (!EraseItemSafe(path)) return false;
1722  }
1723  else
1724  {
1725  if (!EraseItem(path)) return false;
1726  }
1727  // refresh file list
1728  ResetSearch(true);
1729  break;
1730  default: break; // InGrp & Deleted ignored
1731  }
1732  return true;
1733 }
int Entries
Definition: C4Group.h:88
bool EraseItemSafe(const char *szFilename)
Definition: C4GroupMain.cpp:42
#define DirectorySeparator
#define sprintf
Definition: Standard.h:162
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:833
bool DeleteOnDisk
Definition: C4Group.h:125
char DiskPath[_MAX_PATH_LEN]
Definition: C4Group.h:123
@ C4GRES_OnDisk
Definition: C4Group.h:117
@ C4GRES_Deleted
Definition: C4Group.h:119
EntryStatus Status
Definition: C4Group.h:124
const char * GetName() const
Definition: C4Group.cpp:2309
C4GroupEntry * GetEntry(const char *entry_name)
Definition: C4Group.cpp:954

References _MAX_FNAME_LEN, C4GroupEntry::C4GRES_Deleted, C4GroupEntry::C4GRES_OnDisk, C4GroupEntry::DeleteOnDisk, DirectorySeparator, C4GroupEntry::DiskPath, C4GroupHeader::Entries, EraseItem(), EraseItemSafe(), C4Group::GetEntry(), C4Group::GetName(), C4Group::Head, C4Group::ResetSearch(), sprintf, C4Group::P::ST_Packed, C4Group::P::ST_Unpacked, and C4GroupEntry::Status.

Referenced by C4Group_DeleteItem(), C4Group_MoveItem(), C4Group::Delete(), C4UpdatePackage::DoGrpUpdate(), C4TeamList::Save(), C4RoundResults::Save(), and C4PlayerInfoList::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EntryCount()

int C4Group::EntryCount ( const char *  wildcard = nullptr)
inherited

Definition at line 2314 of file C4Group.cpp.

2315 {
2316  // All files if no wildcard
2317  if (!wildcard)
2318  {
2319  wildcard = "*";
2320  }
2321  // Match wildcard
2322  ResetSearch();
2323 
2324  int filecount = 0;
2325  C4GroupEntry *entry;
2326  while ((entry = SearchNextEntry(wildcard)))
2327  {
2328  filecount++;
2329  }
2330  return filecount;
2331 }

References C4Group::ResetSearch().

Referenced by C4Group_ApplyUpdate(), C4MaterialMap::HasMaterials(), C4TextureMap::HasTextures(), C4MaterialMap::Load(), C4Game::LoadScenarioComponents(), and C4UpdatePackage::MkUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EntryCRC32()

unsigned int C4Group::EntryCRC32 ( const char *  wildcard = nullptr)
inherited

Definition at line 2354 of file C4Group.cpp.

2355 {
2356  if (!wildcard)
2357  {
2358  wildcard = "*";
2359  }
2360  ResetSearch();
2361 
2362  // iterate thorugh child
2363  unsigned int CRC = 0;
2364  C4GroupEntry *entry;
2365  while ((entry = SearchNextEntry(wildcard)))
2366  {
2367  CRC ^= CalcCRC32(entry);
2368  }
2369  // return
2370  return CRC;
2371 }

References C4Group::ResetSearch().

Referenced by DisplayGroup(), C4UpdatePackage::MkUp(), and C4Network2Res::SetByGroup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EntrySize()

size_t C4Group::EntrySize ( const char *  wildcard = nullptr)
inherited

Definition at line 2333 of file C4Group.cpp.

2334 {
2335  // All files if no wildcard
2336  if (!wildcard)
2337  {
2338  wildcard = "*";
2339  }
2340  // Match wildcard
2341  ResetSearch();
2342 
2343  int filesize = 0;
2344  C4GroupEntry *entry;
2345  while ((entry = SearchNextEntry(wildcard)))
2346  {
2347  filesize += entry->Size;
2348  }
2349  return filesize;
2350 }
int32_t Size
Definition: C4Group.h:97

References C4Group::ResetSearch(), and C4GroupEntryCore::Size.

Referenced by C4Group::Extract(), and C4UpdatePackage::MkUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extract()

bool C4Group::Extract ( const char *  files,
const char *  destination = nullptr,
const char *  exclude = nullptr 
)
inherited

Definition at line 1808 of file C4Group.cpp.

1809 {
1810  // StdOutput
1811  if (p->LogToStdOutput)
1812  {
1813  printf("Extracting");
1814  if (destination)
1815  {
1816  printf(" to %s",destination);
1817  }
1818  printf("...\n");
1819  }
1820 
1821  int filecount = 0;
1822  int current_bytes = 0;
1823  int total_bytes = EntrySize();
1824  C4GroupEntry *entry;
1825 
1826 
1827  // Process segmented list
1828  char separator = (SCharCount(';', files) ? ';' : '|');
1829  char filename[_MAX_PATH_LEN];
1830  for (int segment_index = 0; SCopySegment(files, segment_index, filename, separator); segment_index++)
1831  {
1832  // Search all entries
1833  ResetSearch();
1834  while ((entry = SearchNextEntry(filename)))
1835  {
1836  // skip?
1837  if (C4Group_IsExcluded(entry->FileName, exclude))
1838  {
1839  continue;
1840  }
1841  // Process data & output
1842  if (p->LogToStdOutput)
1843  {
1844  printf("%s\n", entry->FileName);
1845  }
1846  current_bytes += entry->Size;
1847  if (p->ProcessCallback)
1848  {
1849  p->ProcessCallback(entry->FileName, 100 * current_bytes / std::max(total_bytes, 1));
1850  }
1851 
1852  // Extract
1853  if (!ExtractEntry(entry->FileName, destination))
1854  {
1855  return Error("Extract: Could not extract entry");
1856  }
1857 
1858  filecount++;
1859  }
1860  }
1861 
1862  if (p->LogToStdOutput)
1863  {
1864  printf("%d file(s) extracted.\n", filecount);
1865  }
1866 
1867  return true;
1868 }
bool C4Group_IsExcluded(const char *filename, const char *exclude_list)
Definition: C4Group.cpp:1787
#define _MAX_PATH_LEN
size_t EntrySize(const char *wildcard=nullptr)
Definition: C4Group.cpp:2333
bool ExtractEntry(const char *filename, const char *destination=nullptr)
Definition: C4Group.cpp:1870

References _MAX_PATH_LEN, C4Group_IsExcluded(), C4Group::EntrySize(), C4Group::ExtractEntry(), C4GroupEntryCore::FileName, C4Group::ResetSearch(), SCharCount(), SCopySegment(), and C4GroupEntryCore::Size.

Referenced by C4Group_ApplyUpdate(), C4Group_CopyItem(), C4Group_MoveItem(), C4Group_UnpackDirectory(), and C4PlayerInfoList::RecreatePlayerFiles().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ExtractEntry()

bool C4Group::ExtractEntry ( const char *  filename,
const char *  destination = nullptr 
)
inherited

Definition at line 1870 of file C4Group.cpp.

1871 {
1872  CStdFile temp_file;
1873  CStdFile dummy;
1874  char temp_file_name[_MAX_FNAME_LEN];
1875  char target_file_name[_MAX_FNAME_LEN];
1876 
1877  // Target file name
1878  if (destination)
1879  {
1880  SCopy(destination, target_file_name, _MAX_FNAME-1);
1881  if (DirectoryExists(target_file_name))
1882  {
1883  AppendBackslash(target_file_name);
1884  SAppend(filename, target_file_name, _MAX_FNAME);
1885  }
1886  }
1887  else
1888  {
1889  SCopy(filename, target_file_name, _MAX_FNAME);
1890  }
1891 
1892  // Extract
1893  switch (p->SourceType)
1894  {
1895  case P::ST_Packed: // Copy entry to target
1896  // Get entry
1897  C4GroupEntry *entry;
1898  if (!(entry = GetEntry(filename)))
1899  {
1900  return Error("Extract: Entry not found");
1901  }
1902 
1903  // Create dummy file to reserve target file name
1904  dummy.Create(target_file_name, false);
1905  dummy.Write("Dummy",5);
1906  dummy.Close();
1907 
1908  // Make temp target file name
1909  SCopy(target_file_name, temp_file_name, _MAX_FNAME);
1910  MakeTempFilename(temp_file_name);
1911  // Create temp target file
1912  if (!temp_file.Create(temp_file_name, !!entry->ChildGroup, !!entry->Executable))
1913  {
1914  return Error("Extract: Cannot create target file");
1915  }
1916  // Write entry file to temp target file
1917  if (!AppendEntry2StdFile(entry, temp_file))
1918  {
1919  // Failure: close and erase temp target file
1920  temp_file.Close();
1921  EraseItem(temp_file_name);
1922  // Also erase reservation target file
1923  EraseItem(target_file_name);
1924  // Failure
1925  return false;
1926  }
1927  // Close target file
1928  temp_file.Close();
1929  // Make temp file to original file
1930  if (!EraseItem(target_file_name))
1931  {
1932  return Error("Extract: Cannot erase temporary file");
1933  }
1934  if (!RenameItem(temp_file_name, target_file_name))
1935  {
1936  return Error("Extract: Cannot rename temporary file");
1937  }
1938  break;
1939  case P::ST_Unpacked: // Copy item from folder to target
1940  char path[_MAX_FNAME_LEN];
1941  sprintf(path,"%s%c%s", GetName(),DirectorySeparator, filename);
1942  if (!CopyItem(path, target_file_name))
1943  {
1944  return Error("ExtractEntry: Cannot copy item");
1945  }
1946  break;
1947  }
1948  return true;
1949 }
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:263
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:708
void MakeTempFilename(char *szFilename)
Definition: StdFile.cpp:320
void AppendBackslash(char *szFilename)
Definition: StdFile.cpp:254
bool RenameItem(const char *szItemName, const char *szNewItemName)
Definition: StdFile.cpp:827
bool CopyItem(const char *szSource, const char *szTarget, bool fResetAttributes)
Definition: StdFile.cpp:855
bool Close(StdBuf **ppMemory=nullptr)
Definition: CStdFile.cpp:151
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
Definition: CStdFile.cpp:49
bool Write(const void *pBuffer, int iSize)
Definition: CStdFile.cpp:240
char Executable
Definition: C4Group.h:103

References _MAX_FNAME, _MAX_FNAME_LEN, AppendBackslash(), C4GroupEntryCore::ChildGroup, CStdFile::Close(), CopyItem(), CStdFile::Create(), DirectoryExists(), DirectorySeparator, EraseItem(), C4GroupEntryCore::Executable, C4Group::GetEntry(), C4Group::GetName(), MakeTempFilename(), RenameItem(), SAppend(), SCopy(), sprintf, C4Group::P::ST_Packed, C4Group::P::ST_Unpacked, and CStdFile::Write().

Referenced by C4ScenarioSection::EnsureTempStore(), and C4Group::Extract().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindEntry() [1/2]

bool C4Group::FindEntry ( const char *  wildcard,
char *  filename 
)
inlineinherited

Definition at line 190 of file C4Group.h.

191  {
192  StdStrBuf name;
193  bool found_entry = FindEntry(wildcard, &name);
194  if (filename)
195  {
196  SCopy(name.getData(), filename);
197  }
198  return found_entry;
199  }

References C4Group::FindEntry(), StdStrBuf::getData(), and SCopy().

Here is the call graph for this function:

◆ FindEntry() [2/2]

bool C4Group::FindEntry ( const char *  wildcard,
StdStrBuf filename = nullptr,
size_t *  size = nullptr 
)
inherited

◆ FindNextEntry() [1/2]

bool C4Group::FindNextEntry ( const char *  wildcard,
char *  filename,
size_t *  size = nullptr,
bool  start_at_filename = false 
)
inlineinherited

Definition at line 204 of file C4Group.h.

208  {
209  StdStrBuf name(start_at_filename ? filename : "");
210  bool found_entry = FindNextEntry(wildcard, &name, size, start_at_filename);
211  if (found_entry && filename)
212  {
213  SCopy(name.getData(),filename);
214  }
215  return found_entry;
216  }

References C4Group::FindNextEntry(), StdStrBuf::getData(), and SCopy().

Here is the call graph for this function:

◆ FindNextEntry() [2/2]

bool C4Group::FindNextEntry ( const char *  wildcard,
StdStrBuf filename = nullptr,
size_t *  size = nullptr,
bool  start_at_filename = false 
)
inherited

Definition at line 2217 of file C4Group.cpp.

2221 {
2222  if (!wildcard)
2223  {
2224  return false;
2225  }
2226 
2227  // Reset search to specified position
2228  if (start_at_filename)
2229  {
2230  FindEntry(filename->getData());
2231  }
2232 
2233  C4GroupEntry *entry;
2234  if (!(entry = SearchNextEntry(wildcard)))
2235  {
2236  return false;
2237  }
2238  if (filename)
2239  {
2240  filename->Copy(entry->FileName);
2241  }
2242  if (size)
2243  {
2244  *size = entry->Size;
2245  }
2246  return true;
2247 }
void Copy()
Definition: StdBuf.h:467

References StdStrBuf::Copy(), C4GroupEntryCore::FileName, C4Group::FindEntry(), StdStrBuf::getData(), and C4GroupEntryCore::Size.

Referenced by C4Group::AccessNextEntry(), c4_mapgen_handle_new(), C4Group_ApplyUpdate(), C4UpdatePackage::DoGrpUpdate(), C4ScenarioListLoader::SubFolder::DoLoadContents(), C4UpdatePackage::DoUpdate(), C4ScenarioSection::EnsureTempStore(), C4UpdatePackage::Execute(), C4Group::FindEntry(), C4Group::FindNextEntry(), C4Language::Init(), C4AchievementGraphics::Init(), C4Game::InitScriptEngine(), C4MaterialMap::Load(), C4ObjectInfoList::Load(), C4Surface::Load(), C4DefList::Load(), C4DefGraphics::Load(), C4Game::LoadAdditionalSystemGroup(), C4MusicSystem::LoadDir(), C4SoundSystem::LoadEffects(), C4Game::LoadScenarioComponents(), C4UpdatePackage::MkUp(), C4UpdatePackage::Optimize(), and C4LoaderScreen::SeekLoaderScreens().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetEntry()

C4GroupEntry * C4Group::GetEntry ( const char *  entry_name)
protectedinherited

Definition at line 954 of file C4Group.cpp.

955 {
956  if (p->SourceType == P::ST_Unpacked)
957  {
958  return nullptr;
959  }
960  for (C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
961  {
962  if (entry->Status != C4GroupEntry::C4GRES_Deleted
963  && WildcardMatch(entry_name, entry->FileName))
964  {
965  return entry;
966  }
967  }
968  return nullptr;
969 }
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396

References C4GroupEntry::C4GRES_Deleted, C4Group::P::ST_Unpacked, and WildcardMatch().

Referenced by C4Group::DeleteEntry(), C4Group::ExtractEntry(), C4Group::Rename(), SetNoSort(), and SetSavedEntryCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetError()

const char * C4Group::GetError ( )
inherited

Definition at line 650 of file C4Group.cpp.

651 {
652  return p->ErrorString.c_str();
653 }

Referenced by c4_mapgen_handle_new(), C4LoaderScreen::Init(), C4StartupPlrSelDlg::PlayerListItem::Load(), C4StartupPlrPropertiesDlg::OnClosed(), C4Group::Open(), ProcessGroup(), C4ScenarioListLoader::Entry::RenameTo(), and C4ScenarioListLoader::Entry::SetTitleInGroup().

Here is the caller graph for this function:

◆ GetFirstEntry()

const C4GroupEntry * C4Group::GetFirstEntry ( ) const
inherited

Definition at line 2863 of file C4Group.cpp.

2863 { return p->FirstEntry; }

Referenced by DisplayGroup(), and PrintGroupInternals().

Here is the caller graph for this function:

◆ GetFullName()

StdStrBuf C4Group::GetFullName ( ) const
inherited

Definition at line 2638 of file C4Group.cpp.

2639 {
2640  char name[_MAX_PATH_LEN];
2641  *name='\0';
2642  char sep[] = "/";
2643  sep[0] = DirectorySeparator;
2644  for (const C4Group *pGroup = this; pGroup; pGroup = pGroup->p->Mother)
2645  {
2646  if (*name)
2647  {
2648  SInsert(name, sep, 0, _MAX_PATH);
2649  }
2650  // Avoid double slash
2651  if (pGroup == this || pGroup->p->FileName.length() > 1 || pGroup->p->FileName[0] != '/')
2652  {
2653  SInsert(name, pGroup->GetName(), 0, _MAX_PATH);
2654  }
2655  if (pGroup->p->SourceType == P::ST_Unpacked)
2656  {
2657  break; // Folder is assumed to have full path
2658  }
2659  }
2660  StdStrBuf result;
2661  result.Copy(name);
2662  return result;
2663 }
#define _MAX_PATH
void SInsert(char *szString, const char *szInsert, int iPosition, int iMaxLen)
Definition: Standard.cpp:509

References _MAX_PATH, _MAX_PATH_LEN, StdStrBuf::Copy(), DirectorySeparator, SInsert(), and C4Group::P::ST_Unpacked.

Referenced by C4Group::AccessEntry(), C4GameSaveSavegame::AdjustCore(), C4Language::CloseGroup(), C4ComponentHost::CopyFilePathFromGroup(), DisplayGroup(), C4ScenarioListLoader::SubFolder::DoLoadContents(), C4UpdatePackage::DoUpdate(), C4UpdatePackage::Execute(), C4Language::GetPackGroups(), C4MusicSystem::InitForScenario(), C4Game::InitScriptEngine(), C4ParticleDef::Load(), C4PlayerInfoCore::Load(), C4GameParameters::Load(), C4GameResList::Load(), C4MaterialCore::Load(), C4Surface::Load(), C4DefList::Load(), C4ScenarioListLoader::Entry::Load(), C4UpdatePackage::Load(), C4Player::Load(), C4Game::LoadAdditionalSystemGroup(), C4DefGraphics::LoadBitmap(), C4ScenarioListLoader::Scenario::LoadCustomPre(), C4ScenarioListLoader::Folder::LoadCustomPre(), C4Def::LoadDefCore(), C4TextureMap::LoadTextures(), C4UpdatePackage::MkUp(), C4Playback::Open(), C4Group::OpenAsChild(), C4Game::OpenScenario(), C4MessageInput::ProcessCommand(), C4PlayerInfoCore::Save(), C4ObjectInfo::Save(), and C4Network2Res::SetByGroup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetHeader()

const C4GroupHeader & C4Group::GetHeader ( ) const
inherited

Definition at line 2861 of file C4Group.cpp.

2861 { return Head; }

References C4Group::Head.

Referenced by DisplayGroup(), and PrintGroupInternals().

Here is the caller graph for this function:

◆ GetMother()

C4Group * C4Group::GetMother ( )
inherited

Definition at line 2536 of file C4Group.cpp.

2537 {
2538  return p->Mother;
2539 }

Referenced by C4Console::SaveScenario().

Here is the caller graph for this function:

◆ GetName()

const char * C4Group::GetName ( ) const
inherited

◆ HasPackedMother()

bool C4Group::HasPackedMother ( ) const
inherited

Definition at line 2543 of file C4Group.cpp.

2544 {
2545  if (!p->Mother)
2546  {
2547  return false;
2548  }
2549  return p->Mother->IsPacked();
2550 }

Referenced by C4UpdatePackage::MakeUpdate().

Here is the caller graph for this function:

◆ HeadIdentical()

bool C4GroupEx::HeadIdentical ( C4Group rByGrp,
bool  fLax 
)
inline

Definition at line 184 of file C4Update.cpp.

185  {
186  // Cheat away the protection while avoiding
187  // gcc strict aliasing violation warnings.
188  intptr_t iGroup = (intptr_t) &rByGrp;
189  C4GroupHeader *pHdr = &((C4GroupEx*) iGroup)->Head;
190  // overwrite entries field
191  int Entries = Head.Entries;
192  Head.Entries = pHdr->Entries;
193  // compare
194  bool fIdentical = !memcmp(&Head, pHdr, sizeof(C4GroupHeader));
195  // restore field values
196  Head.Entries = Entries;
197  // okay
198  return fIdentical;
199  }

References C4GroupHeader::Entries, and C4Group::Head.

Referenced by C4UpdatePackage::Optimize().

Here is the caller graph for this function:

◆ IsOpen()

bool C4Group::IsOpen ( ) const
inherited

Definition at line 2373 of file C4Group.cpp.

2373 { return p->SourceType != P::ST_None; }

References C4Group::P::ST_None.

Referenced by c4_group_handle_is_folder(), C4SoundSystem::Init(), C4Game::LoadScenarioSection(), C4Application::OpenSystemGroup(), C4MessageInput::ProcessCommand(), and C4Landscape::SaveTextures().

Here is the caller graph for this function:

◆ IsPacked()

bool C4Group::IsPacked ( ) const
inherited

Definition at line 2541 of file C4Group.cpp.

2541 { return p->SourceType == P::ST_Packed; }

References C4Group::P::ST_Packed.

Referenced by c4_group_handle_is_folder(), C4UpdatePackage::Check(), C4UpdatePackage::Execute(), C4Game::InitScriptEngine(), C4Game::LoadAdditionalSystemGroup(), C4UpdatePackage::MakeUpdate(), C4Playback::Open(), C4Game::OpenScenario(), C4UpdatePackage::Optimize(), C4MessageInput::ProcessCommand(), C4Console::SaveScenario(), and C4ScenarioSection::ScenarioLoad().

Here is the caller graph for this function:

◆ LoadEntry() [1/3]

bool C4Group::LoadEntry ( const char *  entry_name,
char **  buffer,
size_t *  size_info = nullptr,
int  zeros_to_append = 0 
)
inherited

Definition at line 2375 of file C4Group.cpp.

2376 {
2377  size_t size;
2378 
2379  // Access entry, allocate buffer, read data
2380  (*buffer) = nullptr;
2381  if (size_info)
2382  {
2383  *size_info = 0;
2384  }
2385  if (!AccessEntry(entry_name, &size))
2386  {
2387  return Error("LoadEntry: Not found");
2388  }
2389  *buffer = new char[size + zeros_to_append];
2390  if (!Read(*buffer, size))
2391  {
2392  delete [] (*buffer);
2393  *buffer = nullptr;
2394  return Error("LoadEntry: Reading error");
2395  }
2396 
2397  if (size_info)
2398  {
2399  *size_info = size;
2400  }
2401 
2402  if (zeros_to_append)
2403  {
2404  ZeroMem( (*buffer)+size, zeros_to_append );
2405  }
2406 
2407  return true;
2408 }
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
Definition: Standard.h:60
bool AccessEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool needs_to_be_a_group=false)
Definition: C4Group.cpp:2104

References C4Group::AccessEntry(), C4Group::Read(), and ZeroMem().

Referenced by C4ControlReInitScenario::C4ControlReInitScenario(), C4Group_CopyEntry(), C4UpdatePackage::DoGrpUpdate(), C4FontLoader::InitFont(), C4ParticleDef::Load(), C4TextureShape::Load(), C4Folder::Load(), C4SoundEffect::Load(), C4KeyboardInput::LoadCustomConfig(), C4GroupSet::LoadEntry(), C4TextureMap::LoadMap(), C4SolidMask::LoadMaskFromFile(), C4DefGraphics::LoadMesh(), C4DefGraphics::LoadSkeleton(), C4Playback::Open(), and C4Game::SaveGameTitle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadEntry() [2/3]

bool C4Group::LoadEntry ( const char *  entry_name,
StdBuf buffer 
)
inherited

Definition at line 2410 of file C4Group.cpp.

2411 {
2412  size_t size;
2413  // Access entry, allocate buffer, read data
2414  if (!AccessEntry(entry_name, &size))
2415  {
2416  return Error("LoadEntry: Not found");
2417  }
2418  // Allocate memory
2419  buffer->New(size);
2420  // Load data
2421  if (!Read(buffer->getMData(), size))
2422  {
2423  buffer->Clear();
2424  return Error("LoadEntry: Reading error");
2425  }
2426  // ok
2427  return true;
2428 }
void New(size_t inSize)
Definition: StdBuf.h:146
void Clear()
Definition: StdBuf.h:190

References C4Group::AccessEntry(), StdBuf::Clear(), StdBuf::getMData(), StdBuf::New(), and C4Group::Read().

Here is the call graph for this function:

◆ LoadEntry() [3/3]

bool C4Group::LoadEntry ( const StdStrBuf name,
StdBuf buffer 
)
inlineinherited

Definition at line 184 of file C4Group.h.

184 { return LoadEntry(name.getData(), buffer); }
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375

References StdStrBuf::getData(), and C4Group::LoadEntry().

Referenced by C4Group::LoadEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadEntryString() [1/2]

bool C4Group::LoadEntryString ( const char *  entry_name,
StdStrBuf buffer 
)
inherited

Definition at line 2430 of file C4Group.cpp.

2431 {
2432  size_t size;
2433  // Access entry, allocate buffer, read data
2434  if (!AccessEntry(entry_name, &size))
2435  {
2436  return Error("LoadEntry: Not found");
2437  }
2438  // Allocate memory
2439  buffer->SetLength(size);
2440  // other parts crash when they get a zero length buffer, so fail here
2441  if (!size)
2442  {
2443  return false;
2444  }
2445  // Load data
2446  if (!Read(buffer->getMData(), size))
2447  {
2448  buffer->Clear();
2449  return Error("LoadEntry: Reading error");
2450  }
2451  // ok
2452  return true;
2453 }
void SetLength(size_t iLength)
Definition: StdBuf.h:509
void Clear()
Definition: StdBuf.h:466

References C4Group::AccessEntry(), StdStrBuf::Clear(), StdStrBuf::getMData(), C4Group::Read(), and StdStrBuf::SetLength().

Referenced by C4UpdatePackageCore::Load(), C4ObjectInfoCore::Load(), C4PlayerInfoCore::Load(), C4Scenario::Load(), C4GameParameters::Load(), C4MapFolderData::Load(), C4ScenarioParameterDefs::Load(), C4TeamList::Load(), C4MaterialCore::Load(), C4PlayerControlFile::Load(), C4ComponentHost::Load(), C4RoundResults::Load(), C4PlayerInfoList::Load(), C4ScenarioListLoader::Entry::Load(), C4UpdatePackage::Load(), C4ScenarioListLoader::Scenario::LoadCustomPre(), C4ScenarioListLoader::Folder::LoadCustomPre(), C4Def::LoadDefCore(), C4GroupSet::LoadEntryString(), C4MaterialMap::LoadEnumeration(), C4TextureMap::LoadFlags(), C4DefAdditionalResourcesLoader::LoadShaderCode(), C4Playback::Open(), and C4Shader::Refresh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadEntryString() [2/2]

bool C4Group::LoadEntryString ( const StdStrBuf name,
StdStrBuf buffer 
)
inlineinherited

Definition at line 186 of file C4Group.h.

186 { return LoadEntryString(name.getData(), buffer); }
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430

References StdStrBuf::getData(), and C4Group::LoadEntryString().

Referenced by C4Group::LoadEntryString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Merge()

bool C4Group::Merge ( const char *  folders)
inherited

Definition at line 1534 of file C4Group.cpp.

1535 {
1536  bool move = true;
1537 
1538  if (p->LogToStdOutput) printf("%s...\n",move ? "Moving" : "Adding");
1539 
1540  // Add files & directories
1541  char szFileName[_MAX_FNAME_LEN];
1542  int iFileCount = 0;
1544 
1545  // Process segmented path & search wildcards
1546  char cSeparator = (SCharCount(';', folders) ? ';' : '|');
1547  for (int cseg = 0; SCopySegment(folders, cseg, szFileName, cSeparator); cseg++)
1548  {
1549  i.Reset(szFileName);
1550  while (*i)
1551  {
1552  // File count
1553  iFileCount++;
1554  // Process output & callback
1555  if (p->LogToStdOutput) printf("%s\n",GetFilename(*i));
1556  if (p->ProcessCallback)
1557  p->ProcessCallback(GetFilename(*i),0); // cbytes/tbytes
1558  // AddEntryOnDisk
1559  AddEntryOnDisk(*i, nullptr, move);
1560  ++i;
1561  }
1562  }
1563 
1564  if (p->LogToStdOutput) printf("%d file(s) %s.\n",iFileCount, move ? "moved" : "added");
1565 
1566  return true;
1567 }
void Reset(const char *dirname, bool force_reread=false)
Definition: StdFile.cpp:942

References _MAX_FNAME_LEN, GetFilename(), DirectoryIterator::Reset(), SCharCount(), and SCopySegment().

Referenced by C4Network2::RetrieveScenario(), and C4Playback::StreamToRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Move()

bool C4Group::Move ( const char *  filename,
const char *  entry_name 
)
inherited

Definition at line 1633 of file C4Group.cpp.

1634 {
1635  bool move = true;
1636 
1637  if (p->LogToStdOutput)
1638  {
1639  printf("%s %s as %s...\n", move ? "Moving" : "Adding", GetFilename(filename), entry_name);
1640  }
1641 
1642  return AddEntryOnDisk(filename, entry_name, move);
1643 }

References GetFilename().

Referenced by C4Record::AddFile(), C4Group_CopyItem(), C4Group_MoveItem(), C4Group_PackDirectoryTo(), C4UpdatePackage::DoUpdate(), C4UpdatePackage::MkUp(), C4PXSSystem::Save(), C4PlayerList::Save(), C4Landscape::P::SaveDiffInternal(), C4Game::SaveGameTitle(), C4Landscape::P::SaveInternal(), C4Landscape::SaveMap(), C4Surface::SavePNG(), C4Landscape::SaveTextures(), and C4Playback::StreamToRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Open()

bool C4Group::Open ( const char *  group_name,
bool  do_create = false 
)
inherited

Definition at line 660 of file C4Group.cpp.

661 {
662  if (!group_name)
663  {
664  return Error("Open: Null filename");
665  }
666  if (!group_name[0])
667  {
668  return Error("Open: Empty filename");
669  }
670 
671  char group_name_native[_MAX_FNAME];
672  SCopy(group_name, group_name_native, _MAX_FNAME);
673  // Convert to native path
675 
676  // Real reference
677  if (FileExists(group_name_native))
678  {
679  Init();
680  return OpenReal(group_name_native);
681  }
682 
683  // If requested, try creating a new group file
684  if (do_create)
685  {
686  CStdFile temp;
687  if (temp.Create(group_name_native, false))
688  {
689  // Temporary file has been created
690  temp.Close();
691  Init();
692  p->SourceType = P::ST_Packed; p->Modified = true;
693  p->FileName = group_name_native;
694  return true;
695  }
696  }
697 
698  // While not a real reference (child group), trace back to mother group or folder.
699  // Open mother and child in exclusive mode.
700  char group_name_real[_MAX_FNAME];
701  SCopy(group_name_native, group_name_real, _MAX_FNAME);
702  do
703  {
704  if (!TruncatePath(group_name_real))
705  {
706  return Error(FormatString(R"(Open("%s"): File not found)", group_name_native).getData());
707  }
708  }
709  while (!FileExists(group_name_real));
710 
711  // Open mother and child in exclusive mode
712  C4Group *mother = new C4Group;
713  mother->SetStdOutput(p->LogToStdOutput);
714  if (!mother->Open(group_name_real))
715  {
716  Clear();
717  Error(mother->GetError());
718  delete mother;
719  return false;
720  }
721  if (!OpenAsChild(mother, group_name_native+SLen(group_name_real) + 1, true))
722  {
723  Clear();
724  return false;
725  }
726 
727  // Success
728  return true;
729 }
#define AltDirectorySeparator
void SReplaceChar(char *str, char fc, char tc)
Definition: Standard.cpp:354
size_t SLen(const char *sptr)
Definition: Standard.h:74
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
bool TruncatePath(char *szPath)
Definition: StdFile.cpp:237
bool FileExists(const char *szFileName)
C4Group()
Definition: C4Group.cpp:623
const char * GetError()
Definition: C4Group.cpp:650
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660

References _MAX_FNAME, AltDirectorySeparator, C4Group::C4Group(), C4Group::Clear(), CStdFile::Close(), CStdFile::Create(), DirectorySeparator, FileExists(), FormatString(), C4Group::GetError(), C4Group::Open(), C4Group::OpenAsChild(), SCopy(), C4Group::SetStdOutput(), SLen(), SReplaceChar(), C4Group::P::ST_Packed, and TruncatePath().

Referenced by C4MainMenu::ActivateNewPlayer(), c4_mapgen_handle_new(), C4ControlReInitScenario::C4ControlReInitScenario(), C4Group_CopyItem(), C4Group_DeleteItem(), C4Group_IsGroup(), C4Group_MoveItem(), C4Group_PackDirectoryTo(), C4Group_ReadFile(), C4Group_UnpackDirectory(), C4UpdatePackage::Check(), DefFileGetID(), C4ScenarioListLoader::SubFolder::DoLoadContents(), C4ScenarioSection::EnsureTempStore(), C4UpdatePackage::Execute(), C4ScenarioSection::GetGroupfile(), C4Language::Init(), C4ScenarioListLoader::Entry::Load(), C4StartupPlrSelDlg::PlayerListItem::Load(), C4PlayerInfo::LoadBigIcon(), C4KeyboardInput::LoadCustomConfig(), C4MusicSystem::LoadDir(), C4UpdatePackage::MakeUpdate(), C4UpdatePackage::MkUp(), C4StartupPlrPropertiesDlg::OnClosed(), C4Reloc::Open(), C4Group::Open(), C4Network2Res::OpenAsGrp(), C4Application::OpenSystemGroup(), C4UpdatePackage::Optimize(), C4Network2Res::OptimizeStandalone(), ProcessGroup(), C4Shader::Refresh(), C4ParticleDef::Reload(), C4DefList::Reload(), C4ScriptHost::ReloadScript(), C4ScenarioListLoader::Entry::RenameTo(), C4Network2::RetrieveScenario(), C4Player::Save(), C4PlayerList::Save(), C4Console::SaveScenario(), C4Landscape::SaveTextures(), C4Record::Start(), C4Playback::StreamToRecord(), C4ControlJoinPlayer::Strip(), C4Player::Strip(), and C4StartupPlrSelDlg::PlayerListItem::UpdateCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenAsChild()

bool C4Group::OpenAsChild ( C4Group mother,
const char *  entry_name,
bool  is_exclusive = false,
bool  do_create = false 
)
inherited

Definition at line 1952 of file C4Group.cpp.

1953 {
1954 
1955  if (!mother) return Error("OpenAsChild: No mother specified");
1956 
1957  if (SCharCount('*',entry_name))
1958  {
1959  return Error("OpenAsChild: No wildcards allowed");
1960  }
1961 
1962  // Open nested child group check: If entry_name is a reference to
1963  // a nested group, open the first mother (in specified mode), then open the child
1964  // in exclusive mode
1965 
1966  if (SCharCount(DirectorySeparator, entry_name))
1967  {
1968  char mothername[_MAX_FNAME_LEN];
1969  SCopyUntil(entry_name, mothername, DirectorySeparator, _MAX_FNAME);
1970 
1971  C4Group *mother2;
1972  mother2 = new C4Group;
1973  mother2->SetStdOutput(p->LogToStdOutput);
1974  if (!mother2->OpenAsChild(mother, mothername, is_exclusive))
1975  {
1976  delete mother2;
1977  return Error("OpenAsChild: Cannot open mother");
1978  }
1979  return OpenAsChild(mother2, entry_name + SLen(mothername) + 1, true);
1980  }
1981 
1982  // Init
1983  Init();
1984  p->FileName = entry_name;
1985  p->Mother = mother;
1986  p->ExclusiveChild = is_exclusive;
1987 
1988  // Folder: Simply set status and return
1989  char path[_MAX_FNAME_LEN];
1990  SCopy( GetFullName().getData(), path, _MAX_FNAME);
1991  if (DirectoryExists(path))
1992  {
1993  p->FileName = path;
1994  p->SourceType = P::ST_Unpacked;
1995  ResetSearch();
1996  return true;
1997  }
1998 
1999  // Get original entry name
2000  C4GroupEntry *centry;
2001  if ((centry = p->Mother->GetEntry(GetName())))
2002  {
2003  p->FileName = centry->FileName;
2004  }
2005 
2006  // Access entry in mother group
2007  size_t size;
2008  if ((!p->Mother->AccessEntry(GetName(), &size, nullptr, true)))
2009  {
2010  if (!do_create)
2011  {
2012  CloseExclusiveMother();
2013  Clear();
2014  return Error("OpenAsChild: Entry not in mother group");
2015  }
2016  else
2017  {
2018  // Create - will be added to mother in Close()
2019  p->SourceType = P::ST_Packed;
2020  p->Modified = true;
2021  return true;
2022  }
2023  }
2024 
2025  // Child Group?
2026  if (centry && !centry->ChildGroup)
2027  {
2028  CloseExclusiveMother();
2029  Clear();
2030  return Error("OpenAsChild: Is not a child group");
2031  }
2032 
2033  // Read header
2034  // Do not do size checks for packed subgroups of unpacked groups (there will be no entry),
2035  // because that would be the PACKED size which can actually be smaller than sizeof(C4GroupHeader)!
2036  if (size < sizeof(C4GroupHeader) && centry)
2037  {
2038  CloseExclusiveMother();
2039  Clear();
2040  return Error("OpenAsChild: Entry too small");
2041  }
2042  if (!p->Mother->Read(&Head, sizeof(C4GroupHeader)))
2043  {
2044  CloseExclusiveMother();
2045  Clear();
2046  return Error("OpenAsChild: Entry reading error");
2047  }
2048  MemScramble((BYTE*)&Head, sizeof(C4GroupHeader));
2049  p->EntryOffset += sizeof(C4GroupHeader);
2050 
2051  // Check Header
2052  if (!SEqual(Head.Id, C4GroupFileID)
2053  || (Head.Ver1 != C4GroupFileVer1)
2054  || (Head.Ver2 > C4GroupFileVer2))
2055  {
2056  CloseExclusiveMother();
2057  Clear();
2058  return Error("OpenAsChild: Invalid Header");
2059  }
2060 
2061  // Read Entries
2062  C4GroupEntryCore buffer;
2063  int file_entries = Head.Entries;
2064  Head.Entries = 0; // Reset, will be recounted by AddEntry
2065  for (int cnt = 0; cnt < file_entries; cnt++)
2066  {
2067  if (!p->Mother->Read(&buffer, sizeof(C4GroupEntryCore)))
2068  {
2069  CloseExclusiveMother();
2070  Clear();
2071  return Error("OpenAsChild: Entry reading error");
2072  }
2073  p->EntryOffset += sizeof(C4GroupEntryCore);
2074  if (!AddEntry(C4GroupEntry::C4GRES_InGroup,
2075  !!buffer.ChildGroup,
2076  buffer.FileName,
2077  buffer.Size,
2078  nullptr,
2079  nullptr,
2080  false,
2081  false,
2082  !!buffer.Executable))
2083  {
2084  CloseExclusiveMother();
2085  Clear();
2086  return Error("OpenAsChild: Insufficient memory");
2087  }
2088  }
2089 
2090  ResetSearch();
2091 
2092  // File
2093  p->SourceType = P::ST_Packed;
2094 
2095  // save position in mother group
2096  if (centry)
2097  {
2098  p->MotherOffset = centry->Offset;
2099  }
2100 
2101  return true;
2102 }
void MemScramble(BYTE *buffer, int size)
Definition: C4Group.cpp:534
char Id[24+4]
Definition: C4Group.h:85
#define C4GroupFileID
Definition: C4Group.h:62
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL, int iIndex)
Definition: Standard.cpp:172
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
Definition: C4Group.h:93
int32_t Offset
Definition: C4Group.h:98

References _MAX_FNAME, _MAX_FNAME_LEN, C4GroupEntry::C4GRES_InGroup, C4Group::C4Group(), C4GroupFileID, C4GroupFileVer1, C4GroupFileVer2, C4GroupEntryCore::ChildGroup, C4Group::Clear(), DirectoryExists(), DirectorySeparator, C4GroupHeader::Entries, C4GroupEntryCore::Executable, C4GroupEntryCore::FileName, C4Group::GetFullName(), C4Group::GetName(), C4Group::Head, C4GroupHeader::Id, MemScramble(), C4GroupEntryCore::Offset, C4Group::OpenAsChild(), C4Group::ResetSearch(), SCharCount(), SCopy(), SCopyUntil(), SEqual(), C4Group::SetStdOutput(), C4GroupEntryCore::Size, SLen(), C4Group::P::ST_Packed, C4Group::P::ST_Unpacked, C4GroupHeader::Ver1, and C4GroupHeader::Ver2.

Referenced by C4Group_ApplyUpdate(), C4Group::Delete(), C4ScenarioListLoader::SubFolder::DoLoadContents(), C4UpdatePackage::DoUpdate(), C4ScenarioSection::GetGroupfile(), C4Game::InitMaterialTexture(), C4ObjectInfoList::Load(), C4DefList::Load(), C4ObjectInfo::Load(), C4ScenarioListLoader::Entry::Load(), C4Game::LoadAdditionalSystemGroup(), C4Extra::LoadDef(), C4SoundSystem::LoadEffects(), C4UpdatePackage::MkUp(), C4Group::Open(), C4Group::OpenAsChild(), C4Group::OpenChild(), C4Game::OpenScenario(), C4UpdatePackage::Optimize(), PrintGroupInternals(), C4GroupSet::RegisterGroups(), C4GroupSet::RegisterParentFolders(), C4ObjectInfo::Save(), and C4Landscape::SaveTextures().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenChild()

bool C4Group::OpenChild ( const char *  entry_name)
inherited

Definition at line 2765 of file C4Group.cpp.

2766 {
2767  // hack: The seach-handle would be closed twice otherwise
2768  p->FolderSearch.Reset();
2769  // Create a memory copy of ourselves
2770  C4Group *ourselves = new C4Group;
2771  *ourselves->p = *p;
2772 
2773  // Open a child from the memory copy
2774  C4Group child;
2775  if (!child.OpenAsChild(ourselves, entry_name, false))
2776  {
2777  // Silently delete our memory copy
2778  ourselves->p.reset();
2779  delete ourselves;
2780  return false;
2781  }
2782 
2783  // hack: The seach-handle would be closed twice otherwise
2784  p->FolderSearch.Reset();
2785  child.p->FolderSearch.Reset();
2786 
2787  // We now become our own child
2788  *p = *child.p;
2789 
2790  // Make ourselves exclusive (until we hit our memory copy mother)
2791  for (C4Group *group = this; group != ourselves; group = group->p->Mother)
2792  {
2793  group->p->ExclusiveChild = true;
2794  }
2795 
2796  // Reset the temporary child variable so it doesn't delete anything
2797  child.p.reset();
2798 
2799  // Yeehaw
2800  return true;
2801 }

References C4Group::C4Group(), and C4Group::OpenAsChild().

Here is the call graph for this function:

◆ OpenMother()

bool C4Group::OpenMother ( )
inherited

Definition at line 2803 of file C4Group.cpp.

2804 {
2805  // This only works if we are an exclusive child
2806  if (!p->Mother || !p->ExclusiveChild)
2807  {
2808  return false;
2809  }
2810 
2811  // Store a pointer to our mother
2812  C4Group *mother = p->Mother;
2813 
2814  // Clear ourselves without deleting our mother
2815  p->ExclusiveChild = false;
2816  Clear();
2817 
2818  // hack: The seach-handle would be closed twice otherwise
2819  mother->p->FolderSearch.Reset();
2820  p->FolderSearch.Reset();
2821  // We now become our own mother (whoa!)
2822  *this = std::move(*mother);
2823 
2824  // Now silently delete our former mother
2825  delete mother;
2826 
2827  // Yeehaw
2828  return true;
2829 }

References C4Group::Clear().

Here is the call graph for this function:

◆ PreCacheEntries()

int C4Group::PreCacheEntries ( const char *  search_pattern,
bool  cache_previous = false 
)
inherited

Definition at line 2831 of file C4Group.cpp.

2832 {
2833  assert(search_pattern);
2834  int result = 0;
2835  // pre-load entries to memory. return number of loaded entries.
2836  for (C4GroupEntry * entry = p->FirstEntry; entry; entry = entry->Next)
2837  {
2838  // is this to be cached?
2839  if (!WildcardListMatch(search_pattern, entry->FileName))
2840  {
2841  continue;
2842  }
2843  // if desired, cache all entries up to that one to allow rewind in unpacked memory
2844  // (only makes sense for groups)
2845  if (cache_previous && p->SourceType == P::ST_Packed)
2846  {
2847  for (C4GroupEntry * e_pre = p->FirstEntry; e_pre != entry; e_pre = e_pre->Next)
2848  {
2849  if (e_pre->Offset >= p->FilePtr)
2850  {
2851  PreCacheEntry(e_pre);
2852  }
2853  }
2854  }
2855  // cache the given entry
2856  PreCacheEntry(entry);
2857  }
2858  return result;
2859 }
bool WildcardListMatch(const char *szWildcardList, const char *szString)
Definition: StdFile.cpp:348

References C4GroupEntryCore::FileName, C4GroupEntry::Next, C4Group::P::ST_Packed, and WildcardListMatch().

Referenced by C4Game::InitMaterialTexture(), and C4ScenarioListLoader::Scenario::LoadCustomPre().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Read()

bool C4Group::Read ( void *  buffer,
size_t  size 
)
overridevirtualinherited

Implements CStdStream.

Definition at line 1430 of file C4Group.cpp.

1431 {
1432  // Access cached entry from memory?
1433  if (p->pInMemEntry)
1434  {
1435  if (p->iInMemEntrySize < size) return Error("ReadCached:");
1436  memcpy(buffer, p->pInMemEntry, size);
1437  p->iInMemEntrySize -= size;
1438  p->pInMemEntry += size;
1439  return true;
1440  }
1441  // Not cached. Read from file.
1442  switch (p->SourceType)
1443  {
1444  case P::ST_Packed:
1445  // Child group: read from mother group
1446  if (p->Mother)
1447  {
1448  if (!p->Mother->Read(buffer, size))
1449  { RewindFilePtr(); return Error("Read:"); }
1450  }
1451  // Regular group: read from standard file
1452  else
1453  {
1454  if (!p->StdFile.Read(buffer, size))
1455  { RewindFilePtr(); return Error("Read:"); }
1456  }
1457  p->FilePtr+=size;
1458  break;
1459  case P::ST_Unpacked:
1460  if (!p->StdFile.Read(buffer, size)) return Error("Read: Error reading from folder contents");
1461  break;
1462  default: break; // InGrp & Deleted ignored
1463  }
1464 
1465  return true;
1466 }

References C4Group::P::ST_Packed, and C4Group::P::ST_Unpacked.

Referenced by C4Group::Advance(), C4Group_ReadFile(), C4MassMoverSet::Load(), C4PXSSystem::Load(), C4Group::LoadEntry(), C4Group::LoadEntryString(), and C4MCParser::ParseFile().

Here is the caller graph for this function:

◆ Rename()

bool C4Group::Rename ( const char *  filename,
const char *  new_name 
)
inherited

Definition at line 1735 of file C4Group.cpp.

1736 {
1737 
1738  if (p->LogToStdOutput)
1739  {
1740  printf("Renaming %s to %s...\n",filename, new_name);
1741  }
1742 
1743  switch (p->SourceType)
1744  {
1745  case P::ST_Packed:
1746  // Get entry
1747  C4GroupEntry *pEntry;
1748  if (!(pEntry = GetEntry(filename)))
1749  {
1750  return Error("Rename: File not found");
1751  }
1752  // Check double name
1753  if (GetEntry(new_name) && !SEqualNoCase(new_name, filename))
1754  {
1755  return Error("Rename: File exists already");
1756  }
1757  // Rename
1758  SCopy(new_name, pEntry->FileName, _MAX_FNAME);
1759  p->Modified = true;
1760  break;
1761  case P::ST_Unpacked:
1762  p->StdFile.Close();
1763 
1764  char path[_MAX_FNAME_LEN];
1765  SCopy(GetName(),path, _MAX_PATH-1);
1766  AppendBackslash(path);
1767  SAppend(filename, path, _MAX_PATH);
1768 
1769  char path2[_MAX_FNAME_LEN];
1770  SCopy(GetName(),path2, _MAX_PATH-1);
1771  AppendBackslash(path2);
1772  SAppend(new_name, path2, _MAX_PATH);
1773 
1774  if (!RenameFile(path, path2))
1775  {
1776  return Error("Rename: Failure");
1777  }
1778  // refresh file list
1779  ResetSearch(true);
1780  break;
1781  default: break; // InGrp & Deleted ignored
1782  }
1783 
1784  return true;
1785 }
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213
bool RenameFile(const char *szFileName, const char *szNewFileName)

References _MAX_FNAME, _MAX_FNAME_LEN, _MAX_PATH, AppendBackslash(), C4GroupEntryCore::FileName, C4Group::GetEntry(), C4Group::GetName(), RenameFile(), C4Group::ResetSearch(), SAppend(), SCopy(), SEqualNoCase(), C4Group::P::ST_Packed, and C4Group::P::ST_Unpacked.

Referenced by C4ObjectInfo::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ResetSearch()

void C4Group::ResetSearch ( bool  reload_contents = false)
inherited

Definition at line 1316 of file C4Group.cpp.

1317 {
1318  switch (p->SourceType)
1319  {
1320  case P::ST_Unpacked:
1321  p->SearchPtr = nullptr;
1322  p->FolderSearch.Reset(GetName(), reload_contents);
1323  if (*p->FolderSearch)
1324  {
1325  p->FolderSearchEntry.Set(p->FolderSearch, GetName());
1326  p->SearchPtr = &p->FolderSearchEntry;
1327  }
1328  break;
1329  case P::ST_Packed:
1330  p->SearchPtr = p->FirstEntry;
1331  break;
1332  default: break; // InGrp & Deleted ignored
1333  }
1334 }

References C4Group::GetName(), C4Group::P::ST_Packed, and C4Group::P::ST_Unpacked.

Referenced by c4_mapgen_handle_new(), C4Group_ApplyUpdate(), C4Group::Delete(), C4Group::DeleteEntry(), C4UpdatePackage::DoGrpUpdate(), C4ScenarioListLoader::SubFolder::DoLoadContents(), C4UpdatePackage::DoUpdate(), C4ScenarioSection::EnsureTempStore(), C4Group::EntryCount(), C4Group::EntryCRC32(), C4Group::EntrySize(), C4UpdatePackage::Execute(), C4Group::Extract(), C4Group::FindEntry(), C4AchievementGraphics::Init(), C4Game::InitScriptEngine(), C4MaterialMap::Load(), C4ObjectInfoList::Load(), C4DefList::Load(), C4DefGraphics::Load(), C4Game::LoadAdditionalSystemGroup(), C4MusicSystem::LoadDir(), C4SoundSystem::LoadEffects(), C4Game::LoadScenarioComponents(), C4TextureMap::LoadTextures(), C4UpdatePackage::MkUp(), C4Group::OpenAsChild(), C4UpdatePackage::Optimize(), and C4Group::Rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Save()

bool C4Group::Save ( bool  reopen)
inherited

Definition at line 1031 of file C4Group.cpp.

1032 {
1033  char temp_filename[_MAX_FNAME+1];
1034  char group_filename[_MAX_FNAME+1];
1035 
1036  // Create temporary core list with new actual offsets to be saved
1037  int32_t contents_size = 0;
1038  C4GroupEntryCore *save_core = new C4GroupEntryCore[Head.Entries];
1039  int core_index = 0;
1040  for (C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1041  {
1042  if (entry->Status != C4GroupEntry::C4GRES_Deleted)
1043  {
1044  save_core[core_index]=(C4GroupEntryCore)*entry;
1045  // Make actual offset
1046  save_core[core_index].Offset = contents_size;
1047  contents_size += entry->Size;
1048  core_index++;
1049  }
1050  }
1051 
1052  // Hold contents in memory?
1053  bool hold_in_memory = !reopen && p->Mother && contents_size < C4GroupSwapThreshold;
1054  if (!hold_in_memory)
1055  {
1056  // Create target temp file (in temp directory!)
1057  SCopy(GetName(), group_filename, _MAX_FNAME);
1058  if (C4Group_TempPath[0])
1059  {
1060  SCopy(C4Group_TempPath, temp_filename, _MAX_FNAME);
1061  SAppend(GetFilename(GetName()),temp_filename, _MAX_FNAME);
1062  }
1063  else
1064  {
1065  SCopy(GetName(), temp_filename, _MAX_FNAME);
1066  }
1067  MakeTempFilename(temp_filename);
1068  // (Temp file must not have the same name as the group.)
1069  if (SEqual(temp_filename, group_filename))
1070  {
1071  SAppend(".tmp", temp_filename); // Add a second temp extension
1072  MakeTempFilename(temp_filename);
1073  }
1074  }
1075 
1076  // Create the new (temp) group file
1077  CStdFile temp_file;
1078  if (!temp_file.Create(temp_filename, true, false, hold_in_memory))
1079  {
1080  delete [] save_core;
1081  return Error("Close: ...");
1082  }
1083 
1084  // Save header and core list
1085  C4GroupHeader header_buffer = Head;
1086  MemScramble((BYTE*)&header_buffer, sizeof(C4GroupHeader));
1087  if (!temp_file.Write((BYTE*)&header_buffer, sizeof(C4GroupHeader))
1088  || !temp_file.Write((BYTE*)save_core, Head.Entries*sizeof(C4GroupEntryCore)))
1089  {
1090  temp_file.Close();
1091  delete [] save_core;
1092  return Error("Close: ...");
1093  }
1094  delete [] save_core;
1095 
1096  // Save Entries to temp file
1097  int total_size = 0;
1098  for (C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1099  {
1100  total_size += entry->Size;
1101  }
1102  int size_done = 0;
1103  for (C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1104  {
1105  if (AppendEntry2StdFile(entry, temp_file))
1106  {
1107  size_done += entry->Size;
1108  if (total_size && p->ProcessCallback)
1109  {
1110  p->ProcessCallback(entry->FileName, 100 * size_done / total_size);
1111  }
1112  }
1113  else
1114  {
1115  temp_file.Close();
1116  return false;
1117  }
1118  }
1119 
1120  // Write
1121  StdBuf *buffer;
1122  temp_file.Close(hold_in_memory ? &buffer : nullptr);
1123 
1124  // Child: move temp file to mother
1125  if (p->Mother)
1126  {
1127  if (hold_in_memory)
1128  {
1129  if (!p->Mother->Add(GetFilename(GetName()), *buffer, true, true))
1130  {
1131  delete buffer;
1132  CloseExclusiveMother();
1133  Clear();
1134  return Error("Close: Cannot move rewritten child data to mother");
1135  }
1136  delete buffer;
1137  }
1138  else
1139  {
1140  if (!p->Mother->Move(temp_filename, GetFilename(GetName())))
1141  {
1142  CloseExclusiveMother();
1143  Clear();
1144  return Error("Close: Cannot move rewritten child temp file to mother");
1145  }
1146  }
1147  Clear();
1148  return true;
1149  }
1150 
1151  // Clear (close file)
1152  Clear();
1153 
1154  // Delete old group file, rename new file
1155  if (!EraseFile(group_filename))
1156  {
1157  return Error("Close: Cannot erase temp file");
1158  }
1159  if (!RenameFile(temp_filename, group_filename))
1160  {
1161  return Error("Close: Cannot rename group file");
1162  }
1163 
1164  // Should reopen the file?
1165  if (reopen)
1166  {
1167  OpenReal(group_filename);
1168  }
1169 
1170  return true;
1171 }
char C4Group_TempPath[_MAX_PATH_LEN]
Definition: C4Group.cpp:59
const int32_t C4GroupSwapThreshold
Definition: C4Group.h:60
bool EraseFile(const char *szFileName)
Definition: StdBuf.h:30

References _MAX_FNAME, C4GroupEntry::C4GRES_Deleted, C4Group_TempPath, C4GroupSwapThreshold, C4Group::Clear(), CStdFile::Close(), CStdFile::Create(), C4GroupHeader::Entries, EraseFile(), GetFilename(), C4Group::GetName(), C4Group::Head, MakeTempFilename(), MemScramble(), C4GroupEntryCore::Offset, RenameFile(), SAppend(), SCopy(), SEqual(), C4GroupEntryCore::Size, and CStdFile::Write().

Referenced by C4ControlReInitScenario::C4ControlReInitScenario(), C4Group::Close(), and Close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveEntryCore()

void C4GroupEx::SaveEntryCore ( C4Group rByGrp,
const char *  szEntry 
)
inline

Definition at line 202 of file C4Update.cpp.

203  {
204  C4GroupEntryCore *pCore = ((C4GroupEx &)rByGrp).GetEntry(szEntry);
205  // copy core
207  }
C4GroupEntryCore SavedCore
Definition: C4Update.cpp:201

References C4GroupEntryCore::Executable, and SavedCore.

Referenced by C4UpdatePackage::DoUpdate(), C4UpdatePackage::MkUp(), and C4UpdatePackage::Optimize().

Here is the caller graph for this function:

◆ SetHead()

void C4GroupEx::SetHead ( C4Group rByGrp)
inline

Definition at line 172 of file C4Update.cpp.

173  {
174  // Cheat away the protection
175  C4GroupHeader *pHdr = &static_cast<C4GroupEx&>(rByGrp).Head;
176  // save Entries
177  int Entries = Head.Entries;
178  // copy
179  memcpy(&Head, pHdr, sizeof(Head));
180  // restore
181  Head.Entries = Entries;
182  }

References C4GroupHeader::Entries, and C4Group::Head.

Referenced by C4UpdatePackage::DoGrpUpdate(), C4UpdatePackage::MkUp(), and C4UpdatePackage::Optimize().

Here is the caller graph for this function:

◆ SetNoSort() [1/2]

bool C4Group::SetNoSort ( bool  no_sorting)
inherited

Definition at line 2552 of file C4Group.cpp.

2552 { p->NoSort = no_sorting; return true; }

Referenced by C4Group_CopyItem(), and C4Group_MoveItem().

Here is the caller graph for this function:

◆ SetNoSort() [2/2]

void C4GroupEx::SetNoSort ( const char *  szEntry)
inline

Definition at line 215 of file C4Update.cpp.

216  {
217  C4GroupEntry *pEntry = GetEntry(szEntry);
218  if (pEntry) pEntry->NoSort = true;
219  }
bool NoSort
Definition: C4Group.h:128

References C4Group::GetEntry(), and C4GroupEntry::NoSort.

Referenced by C4UpdatePackage::DoUpdate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetSavedEntryCore()

void C4GroupEx::SetSavedEntryCore ( const char *  szEntry)
inline

Definition at line 208 of file C4Update.cpp.

209  {
210  C4GroupEntryCore *pCore = GetEntry(szEntry);
211  // copy core
213  }

References C4GroupEntryCore::Executable, C4Group::GetEntry(), and SavedCore.

Referenced by C4UpdatePackage::DoUpdate(), C4UpdatePackage::MkUp(), and C4UpdatePackage::Optimize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetStdOutput()

void C4Group::SetStdOutput ( bool  log_status)
inherited

Definition at line 655 of file C4Group.cpp.

656 {
657  p->LogToStdOutput = log_status;
658 }

Referenced by C4Group::Delete(), C4Group::Open(), C4Group::OpenAsChild(), and ProcessGroup().

Here is the caller graph for this function:

◆ Sort()

bool C4Group::Sort ( const char *  list)
inherited

Definition at line 2470 of file C4Group.cpp.

2471 {
2472  bool bubble;
2473  C4GroupEntry *current;
2474  C4GroupEntry *prev;
2475  C4GroupEntry *next;
2476  C4GroupEntry *nextnext;
2477 
2478  if (!list || !list[0])
2479  {
2480  return false;
2481  }
2482 
2483  if (p->LogToStdOutput)
2484  {
2485  printf("Sorting...\n");
2486  }
2487 
2488  do
2489  {
2490  bubble = false;
2491 
2492  for (prev = nullptr, current = p->FirstEntry; current; prev = current, current = next)
2493  {
2494  if ((next = current->Next))
2495  {
2496  // primary sort by file list
2497  int rank_a = SortRank(current->FileName, list);
2498  int rank_b = SortRank(next->FileName, list);
2499  if (rank_a > rank_b)
2500  {
2501  continue;
2502  }
2503  // secondary sort by filename
2504  if (rank_a == rank_b)
2505  {
2506  if (stricmp(current->FileName, next->FileName) <= 0)
2507  {
2508  continue;
2509  }
2510  }
2511  // wrong order: Swap!
2512  nextnext = next->Next;
2513  if (prev)
2514  {
2515  prev->Next = next;
2516  }
2517  else
2518  {
2519  p->FirstEntry = next;
2520  }
2521  next->Next = current;
2522  current->Next = nextnext;
2523  next = nextnext;
2524 
2525  bubble = true;
2526  p->Modified = true;
2527  }
2528  }
2529 
2530  }
2531  while (bubble);
2532 
2533  return true;
2534 }
int SortRank(const char *element, const char *sort_list)
Definition: C4Group.cpp:2455
int stricmp(const char *s1, const char *s2)
C4GroupEntry * Next
Definition: C4Group.h:130

References C4GroupEntryCore::FileName, C4GroupEntry::Next, SortRank(), and stricmp().

Referenced by C4GameSave::Close(), C4UpdatePackage::DoGrpUpdate(), ProcessGroup(), C4Player::Save(), and C4Group::SortByList().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SortByList()

bool C4Group::SortByList ( const char **  list,
const char *  filename = nullptr 
)
inherited

Definition at line 2566 of file C4Group.cpp.

2567 {
2568  // No sort list specified
2569  if (!list)
2570  {
2571  return false;
2572  }
2573  // No group name specified, use own
2574  if (!filename)
2575  {
2576  filename = GetName();
2577  }
2578  filename = GetFilename(filename);
2579  // Find matching filename entry in sort list
2580  const char **list_entry;
2581  for (list_entry = list; *list_entry; list_entry += 2)
2582  {
2583  if (WildcardMatch( *list_entry, filename ))
2584  {
2585  break;
2586  }
2587  }
2588  // Sort by sort list entry
2589  if (*list_entry && *(list_entry + 1))
2590  {
2591  Sort(*(list_entry + 1));
2592  }
2593  // Success
2594  return true;
2595 }
bool Sort(const char *list)
Definition: C4Group.cpp:2470

References GetFilename(), C4Group::GetName(), C4Group::Sort(), and WildcardMatch().

Referenced by C4Group_PackDirectoryTo(), C4Group::Close(), and C4UpdatePackage::MkUp().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ Head

C4GroupHeader C4Group::Head
protectedinherited

◆ SavedCore

C4GroupEntryCore C4GroupEx::SavedCore

Definition at line 201 of file C4Update.cpp.

Referenced by SaveEntryCore(), and SetSavedEntryCore().


The documentation for this class was generated from the following file: