49 const char *szCurrAccessedEntry =
nullptr;
50 int iC4GroupRewindFilePtrNoWarn = 0;
76 if (!path || !path[0])
100 || name[strlen(name) - 1] ==
'~'
107 if (group.
Open(filename))
115 bool C4Group_CopyItem(
const char *source,
const char *target,
bool no_sorting,
bool reset_attributes)
118 if (!source || !target || !source[0] || !target[0])
141 return CopyItem(source, target_path, reset_attributes);
162 if ( !source_parent.
Open(source_parent_path)
164 || !source_parent.
Close())
170 if ( !target_parent.
Open(target_parent_path)
173 || !target_parent.
Close())
185 if (!source || !target || !source[0] || !target[0])
209 return MoveItem(source, target_path);
227 if ( !source_parent.
Open(source_parent_path)
229 || !source_parent.
Close())
235 if ( !target_parent.
Open(target_parent_path)
238 || !target_parent.
Close())
245 if ( !source_parent.
Open(source_parent_path)
247 || !source_parent.
Close() )
258 if (!item_name || !item_name[0])
282 if ( !parent.
Open(parent_path)
316 if (!group.
Open(to_filename,
true))
351 else if (!group.
Add(*i,
nullptr))
368 return group.
Close();
420 if (!group.
Open(filename))
442 if (!group.
Extract(
"*",target_directory))
494 if (!filename || !data)
506 if (!parent_group.
Open(parent_path))
512 if (!parent_group.
AccessEntry(entry_name, &filesize))
517 *data =
new char [filesize];
519 if (!parent_group.
Read(*data, filesize))
526 parent_group.
Close();
537 for (
int cnt = 0; cnt < size; cnt++)
542 for (
int cnt = 0; cnt + 2 < size; cnt += 3)
544 BYTE temp = buffer[cnt];
545 buffer[cnt] = buffer[cnt + 2];
546 buffer[cnt + 2] = temp;
629 auto new_p = std::make_unique<P>();
631 new_p->ProcessCallback = p->ProcessCallback;
632 new_p->NoSort = p->NoSort;
633 new_p->LogToStdOutput = p->LogToStdOutput;
636 p = std::move(new_p);
644 bool C4Group::Error(
const char *status_message)
646 p->ErrorString = status_message;
652 return p->ErrorString.c_str();
657 p->LogToStdOutput = log_status;
664 return Error(
"Open: Null filename");
668 return Error(
"Open: Empty filename");
680 return OpenReal(group_name_native);
687 if (temp.
Create(group_name_native,
false))
693 p->FileName = group_name_native;
706 return Error(
FormatString(R
"(Open("%s"): File not found)", group_name_native).getData());
714 if (!mother->
Open(group_name_real))
721 if (!
OpenAsChild(mother, group_name_native+
SLen(group_name_real) + 1,
true))
731 bool C4Group::OpenReal(
const char *filename)
738 p->FileName = filename;
746 return Error(
FormatString(
"OpenReal: filename '%s' ignored", filename).getData());
756 if (OpenRealGrpFile())
767 return Error(
"OpenReal: Not a valid group");
770 bool C4Group::OpenRealGrpFile()
774 if (!p->StdFile.Open(
GetName(),
true))
776 return Error(
"OpenRealGrpFile: Cannot open standard file");
782 return Error(
"OpenRealGrpFile: Error reading header");
792 return Error(
"OpenRealGrpFile: Invalid header");
799 for (
int cnt = 0; cnt<file_entries; cnt++)
803 return Error(
"OpenRealGrpFile: Error reading entries");
807 entryname.EnsureUnicode();
812 !!corebuf.ChildGroup,
819 !!corebuf.Executable))
821 return Error(
"OpenRealGrpFile: Cannot add entry");
830 const char *filename,
832 const char *entry_name,
837 bool buffer_is_stdbuf)
852 SAppend(entry_name, target_folder_name);
863 if (!
CopyItem(filename, target_folder_name))
869 if (delete_on_disk && !
EraseItem(filename))
878 if (file.
Create(target_folder_name, !!add_as_child))
880 okay = !!file.
Write(buffer, size);
888 else delete [] buffer;
897 return Error(
"Add to folder: Invalid request");
919 for (last = p->FirstEntry; last && last->
Next; last = last->
Next) {}
941 next->
Next =
nullptr;
945 if (last) last->
Next = next;
946 else p->FirstEntry = next;
960 for (
C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
973 bool rewrite =
false;
983 CloseExclusiveMother();
989 for (
C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1004 CloseExclusiveMother();
1009 if (p->LogToStdOutput)
1011 printf(
"Writing group file...\n");
1022 bool success =
Save(
false);
1025 CloseExclusiveMother();
1037 int32_t contents_size = 0;
1040 for (
C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1046 save_core[core_index].
Offset = contents_size;
1047 contents_size += entry->Size;
1054 if (!hold_in_memory)
1069 if (
SEqual(temp_filename, group_filename))
1071 SAppend(
".tmp", temp_filename);
1078 if (!temp_file.
Create(temp_filename,
true,
false, hold_in_memory))
1080 delete [] save_core;
1081 return Error(
"Close: ...");
1091 delete [] save_core;
1092 return Error(
"Close: ...");
1094 delete [] save_core;
1098 for (
C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1100 total_size += entry->
Size;
1103 for (
C4GroupEntry *entry = p->FirstEntry; entry; entry = entry->Next)
1105 if (AppendEntry2StdFile(entry, temp_file))
1107 size_done += entry->Size;
1108 if (total_size && p->ProcessCallback)
1110 p->ProcessCallback(entry->FileName, 100 * size_done / total_size);
1122 temp_file.
Close(hold_in_memory ? &buffer :
nullptr);
1132 CloseExclusiveMother();
1134 return Error(
"Close: Cannot move rewritten child data to mother");
1142 CloseExclusiveMother();
1144 return Error(
"Close: Cannot move rewritten child temp file to mother");
1157 return Error(
"Close: Cannot erase temp file");
1159 if (!
RenameFile(temp_filename, group_filename))
1161 return Error(
"Close: Cannot rename group file");
1167 OpenReal(group_filename);
1179 while (p->FirstEntry)
1181 next = p->FirstEntry->Next;
1182 delete p->FirstEntry;
1183 p->FirstEntry = next;
1188 if (p->Mother && p->ExclusiveChild)
1191 p->Mother =
nullptr;
1207 if (!SetFilePtr(entry->
Offset))
1208 return Error(
"AE2S: Cannot set file pointer");
1209 for (
long current_size = entry->
Size; current_size > 0; current_size--)
1211 if (!
Read(&buffer, 1))
1213 return Error(
"AE2S: Cannot read entry from group file");
1215 if (!target.
Write(&buffer, 1))
1217 return Error(
"AE2S: Cannot write to target file");
1230 return Error(
"AE2S: Cannot add directory to group file");
1235 bool has_temp_file =
false;
1244 return Error(
"AE2S: Cannot copy item");
1248 if (!SortGrp.
Open(file_source))
1250 return Error(
"AE2S: Cannot open group");
1254 return Error(
"AE2S: Cannot resort group");
1256 has_temp_file =
true;
1264 return Error(
"AE2S: Cannot open on-disk file");
1266 for (
long current_size = entry->
Size; current_size > 0; current_size--)
1268 if (!source.
Read(&buffer, 1))
1271 return Error(
"AE2S: Cannot read on-disk file");
1273 if (!target.
Write(&buffer, 1))
1276 return Error(
"AE2S: Cannot write to target file");
1298 return Error(
"AE2S: no buffer");
1302 return Error(
"AE2S: writing error");
1310 return Error(
"AE2S: Unknown file status");
1318 switch (p->SourceType)
1321 p->SearchPtr =
nullptr;
1322 p->FolderSearch.Reset(
GetName(), reload_contents);
1323 if (*p->FolderSearch)
1325 p->FolderSearchEntry.Set(p->FolderSearch,
GetName());
1326 p->SearchPtr = &p->FolderSearchEntry;
1330 p->SearchPtr = p->FirstEntry;
1338 if (*++p->FolderSearch)
1340 p->FolderSearchEntry.Set(p->FolderSearch,
GetName());
1341 return &p->FolderSearchEntry;
1349 C4GroupEntry* C4Group::SearchNextEntry(
const char *entry_name)
1352 if (
SEqual(entry_name,
"*.*"))
1358 switch (p->SourceType)
1362 for (pEntry = p->SearchPtr; pEntry; pEntry = pEntry->
Next)
1366 p->SearchPtr = pEntry->
Next;
1372 for (pEntry = p->SearchPtr; pEntry; pEntry = GetNextFolderEntry())
1376 p->LastFolderSearchEntry=(*pEntry);
1377 pEntry=&p->LastFolderSearchEntry;
1378 p->SearchPtr = GetNextFolderEntry();
1386 p->SearchPtr =
nullptr;
1390 bool C4Group::SetFilePtr(
int offset)
1394 return Error(
"SetFilePtr not implemented for Folders");
1397 if (p->Mother) p->Mother->EnsureChildFilePtr(
this);
1400 if (p->FilePtr>offset)
1401 if (!RewindFilePtr())
return false;
1404 if (p->FilePtr<offset)
1405 if (!AdvanceFilePtr(offset- p->FilePtr))
return false;
1412 assert(offset >= 0);
1416 if (p->iInMemEntrySize <
size_t(offset))
return false;
1417 p->iInMemEntrySize -= offset;
1418 p->pInMemEntry += offset;
1422 if (p->SourceType ==
P::ST_Unpacked)
return !!p->StdFile.Advance(offset);
1425 for (; offset>0; offset--)
1426 if (!
Read(&buf, 1))
return false;
1435 if (p->iInMemEntrySize < size)
return Error(
"ReadCached:");
1436 memcpy(buffer, p->pInMemEntry, size);
1437 p->iInMemEntrySize -= size;
1438 p->pInMemEntry += size;
1442 switch (p->SourceType)
1448 if (!p->Mother->Read(buffer, size))
1449 { RewindFilePtr();
return Error(
"Read:"); }
1454 if (!p->StdFile.Read(buffer, size))
1455 { RewindFilePtr();
return Error(
"Read:"); }
1460 if (!p->StdFile.Read(buffer, size))
return Error(
"Read: Error reading from folder contents");
1468 bool C4Group::AdvanceFilePtr(
int offset)
1475 if (!p->Mother->EnsureChildFilePtr(
this))
1478 if (!p->Mother->AdvanceFilePtr(offset))
1485 if (!p->StdFile.Advance(offset))
1491 if (!p->StdFile.Advance(offset))
1501 bool C4Group::RewindFilePtr()
1505 if (szCurrAccessedEntry && !iC4GroupRewindFilePtrNoWarn)
1507 LogF(
"C4Group::RewindFilePtr() for %s (%s) after %s", szCurrAccessedEntry ? szCurrAccessedEntry :
"???",
GetName(), p->sPrevAccessedEntry.getLength() ? p->sPrevAccessedEntry.getData() :
"???");
1508 szCurrAccessedEntry =
nullptr;
1515 if (!p->Mother->SetFilePtr2Entry(
GetName(),
true))
1517 if (!p->Mother->AdvanceFilePtr(p->EntryOffset))
1523 if (!p->StdFile.Rewind())
1525 if (!p->StdFile.Advance(p->EntryOffset))
1538 if (p->LogToStdOutput) printf(
"%s...\n",move ?
"Moving" :
"Adding");
1546 char cSeparator = (
SCharCount(
';', folders) ?
';' :
'|');
1547 for (
int cseg = 0;
SCopySegment(folders, cseg, szFileName, cSeparator); cseg++)
1549 i.
Reset(szFileName);
1555 if (p->LogToStdOutput) printf(
"%s\n",
GetFilename(*i));
1556 if (p->ProcessCallback)
1559 AddEntryOnDisk(*i,
nullptr, move);
1564 if (p->LogToStdOutput) printf(
"%d file(s) %s.\n",iFileCount, move ?
"moved" :
"added");
1569 bool C4Group::AddEntryOnDisk(
const char *filename,
1570 const char *entry_name,
1588 if (move) {
if (!
MoveItem(filename, temp_filename))
return Error(
"AddEntryOnDisk: Move failure"); }
1589 else {
if (!
CopyItem(filename, temp_filename))
return Error(
"AddEntryOnDisk: Copy failure"); }
1593 if (!entry_name) entry_name =
GetFilename(filename);
1594 filename = temp_filename;
1603 bool is_executable =
false;
1605 is_executable = (access(filename, X_OK) == 0);
1625 if (p->LogToStdOutput)
1627 printf(
"%s %s as %s...\n", move ?
"Moving" :
"Adding",
GetFilename(filename), entry_name);
1630 return AddEntryOnDisk(filename, entry_name, move);
1637 if (p->LogToStdOutput)
1639 printf(
"%s %s as %s...\n", move ?
"Moving" :
"Adding",
GetFilename(filename), entry_name);
1642 return AddEntryOnDisk(filename, entry_name, move);
1653 char cSeparator = (
SCharCount(
';', files) ?
';' :
'|');
1654 bool success =
true;
1657 if (!
Delete(filespec, recursive))
1664 while ((tentry = SearchNextEntry(files)))
1667 if (p->LogToStdOutput) printf(
"%s\n",tentry->
FileName);
1669 return Error(
"Delete: Could not delete entry");
1678 while ((tentry = SearchNextEntry(
"*")))
1683 hChild.
Delete(files, recursive);
1689 if (p->LogToStdOutput)
1690 printf(
"%d file(s) deleted.\n",fcount);
1697 switch (p->SourceType)
1702 if (!(pEntry =
GetEntry(filename)))
return false;
1738 if (p->LogToStdOutput)
1740 printf(
"Renaming %s to %s...\n",filename, new_name);
1743 switch (p->SourceType)
1748 if (!(pEntry =
GetEntry(filename)))
1750 return Error(
"Rename: File not found");
1755 return Error(
"Rename: File exists already");
1776 return Error(
"Rename: Failure");
1790 if (!filename || !filename[0] || !exclude_list || !exclude_list[0])
1795 char separator = (
SCharCount(
';', exclude_list) ?
';' :
'|');
1797 for (
int i = 0;
SCopySegment(exclude_list, i, segment, separator); i++)
1811 if (p->LogToStdOutput)
1813 printf(
"Extracting");
1816 printf(
" to %s",destination);
1822 int current_bytes = 0;
1828 char separator = (
SCharCount(
';', files) ?
';' :
'|');
1830 for (
int segment_index = 0;
SCopySegment(files, segment_index, filename, separator); segment_index++)
1834 while ((entry = SearchNextEntry(filename)))
1842 if (p->LogToStdOutput)
1846 current_bytes += entry->
Size;
1847 if (p->ProcessCallback)
1849 p->ProcessCallback(entry->
FileName, 100 * current_bytes / std::max(total_bytes, 1));
1855 return Error(
"Extract: Could not extract entry");
1862 if (p->LogToStdOutput)
1864 printf(
"%d file(s) extracted.\n", filecount);
1893 switch (p->SourceType)
1900 return Error(
"Extract: Entry not found");
1904 dummy.
Create(target_file_name,
false);
1905 dummy.
Write(
"Dummy",5);
1914 return Error(
"Extract: Cannot create target file");
1917 if (!AppendEntry2StdFile(entry, temp_file))
1932 return Error(
"Extract: Cannot erase temporary file");
1934 if (!
RenameItem(temp_file_name, target_file_name))
1936 return Error(
"Extract: Cannot rename temporary file");
1942 if (!
CopyItem(path, target_file_name))
1944 return Error(
"ExtractEntry: Cannot copy item");
1955 if (!mother)
return Error(
"OpenAsChild: No mother specified");
1959 return Error(
"OpenAsChild: No wildcards allowed");
1974 if (!mother2->
OpenAsChild(mother, mothername, is_exclusive))
1977 return Error(
"OpenAsChild: Cannot open mother");
1984 p->FileName = entry_name;
1986 p->ExclusiveChild = is_exclusive;
2001 if ((centry = p->Mother->GetEntry(
GetName())))
2008 if ((!p->Mother->AccessEntry(
GetName(), &size,
nullptr,
true)))
2012 CloseExclusiveMother();
2014 return Error(
"OpenAsChild: Entry not in mother group");
2028 CloseExclusiveMother();
2030 return Error(
"OpenAsChild: Is not a child group");
2038 CloseExclusiveMother();
2040 return Error(
"OpenAsChild: Entry too small");
2044 CloseExclusiveMother();
2046 return Error(
"OpenAsChild: Entry reading error");
2056 CloseExclusiveMother();
2058 return Error(
"OpenAsChild: Invalid Header");
2065 for (
int cnt = 0; cnt < file_entries; cnt++)
2069 CloseExclusiveMother();
2071 return Error(
"OpenAsChild: Entry reading error");
2084 CloseExclusiveMother();
2086 return Error(
"OpenAsChild: Insufficient memory");
2098 p->MotherOffset = centry->
Offset;
2107 bool needs_to_be_a_group)
2109 #ifdef C4GROUP_DUMP_ACCESS
2113 if (!
FindEntry(wildcard,&fname,&p->iCurrFileSize))
2118 szCurrAccessedEntry = fname.
getMData();
2120 bool okay = SetFilePtr2Entry(fname.
getData(), needs_to_be_a_group);
2122 p->sPrevAccessedEntry.Copy(szCurrAccessedEntry);
2123 szCurrAccessedEntry =
nullptr;
2135 *size = p->iCurrFileSize;
2143 bool start_at_filename)
2146 if (!
FindNextEntry(wildcard, entry_name, &p->iCurrFileSize, start_at_filename))
2151 szCurrAccessedEntry = filename;
2153 bool okay = SetFilePtr2Entry(entry_name);
2155 szCurrAccessedEntry =
nullptr;
2163 SCopy(entry_name, filename);
2167 *size = p->iCurrFileSize;
2172 bool C4Group::SetFilePtr2Entry(
const char *entry_name,
bool needs_to_be_a_group)
2176 if (entry && entry->
MemoryBuffer && !needs_to_be_a_group)
2179 p->iInMemEntrySize = entry->
Size;
2184 p->pInMemEntry =
nullptr;
2188 switch (p->SourceType)
2196 return SetFilePtr(entry->
Offset);
2204 return p->StdFile.Open(path, needs_to_be_a_group);
2220 bool start_at_filename)
2228 if (start_at_filename)
2234 if (!(entry = SearchNextEntry(wildcard)))
2244 *size = entry->
Size;
2249 bool C4Group::Add(
const char *entry_name,
void *buffer,
int size,
bool add_as_child,
bool hold_buffer,
bool is_executable)
2262 bool C4Group::Add(
const char *entry_name,
StdBuf &buffer,
bool add_as_child,
bool hold_buffer,
bool is_executable)
2311 return p->FileName.c_str();
2326 while ((entry = SearchNextEntry(wildcard)))
2345 while ((entry = SearchNextEntry(wildcard)))
2347 filesize += entry->
Size;
2363 unsigned int CRC = 0;
2365 while ((entry = SearchNextEntry(wildcard)))
2367 CRC ^= CalcCRC32(entry);
2380 (*buffer) =
nullptr;
2387 return Error(
"LoadEntry: Not found");
2389 *buffer =
new char[size + zeros_to_append];
2390 if (!
Read(*buffer, size))
2392 delete [] (*buffer);
2394 return Error(
"LoadEntry: Reading error");
2402 if (zeros_to_append)
2404 ZeroMem( (*buffer)+size, zeros_to_append );
2416 return Error(
"LoadEntry: Not found");
2424 return Error(
"LoadEntry: Reading error");
2436 return Error(
"LoadEntry: Not found");
2449 return Error(
"LoadEntry: Reading error");
2455 int SortRank(
const char *element,
const char *sort_list)
2463 return (
SCharCount(
'|',sort_list) + 1) - cnt;
2478 if (!list || !list[0])
2483 if (p->LogToStdOutput)
2485 printf(
"Sorting...\n");
2492 for (prev =
nullptr, current = p->FirstEntry; current; prev = current, current = next)
2494 if ((next = current->
Next))
2499 if (rank_a > rank_b)
2504 if (rank_a == rank_b)
2512 nextnext = next->
Next;
2519 p->FirstEntry = next;
2521 next->
Next = current;
2522 current->
Next = nextnext;
2549 return p->Mother->IsPacked();
2554 bool C4Group::CloseExclusiveMother()
2556 if (p->Mother && p->ExclusiveChild)
2560 p->Mother =
nullptr;
2580 const char **list_entry;
2581 for (list_entry = list; *list_entry; list_entry += 2)
2589 if (*list_entry && *(list_entry + 1))
2591 Sort(*(list_entry + 1));
2597 bool C4Group::EnsureChildFilePtr(
C4Group *child)
2604 if (p->FilePtr != child->p->MotherOffset + child->p->EntryOffset + child->p->FilePtr)
2607 if (!SetFilePtr(child->p->MotherOffset + child->p->EntryOffset + child->p->FilePtr))
2627 if (!AdvanceFilePtr( child->p->EntryOffset + child->p->FilePtr))
2644 for (
const C4Group *pGroup =
this; pGroup; pGroup = pGroup->p->Mother)
2651 if (pGroup ==
this || pGroup->p->FileName.length() > 1 || pGroup->p->FileName[0] !=
'/')
2693 else if (!entry->
Size)
2699 BYTE *data =
nullptr;
2710 if (!SetFilePtr2Entry(entry->
FileName))
2752 CRC = crc32(0, data, entry->
Size);
2768 p->FolderSearch.Reset();
2775 if (!child.
OpenAsChild(ourselves, entry_name,
false))
2778 ourselves->p.reset();
2784 p->FolderSearch.Reset();
2785 child.p->FolderSearch.Reset();
2791 for (
C4Group *group =
this; group != ourselves; group = group->p->Mother)
2793 group->p->ExclusiveChild =
true;
2806 if (!p->Mother || !p->ExclusiveChild)
2815 p->ExclusiveChild =
false;
2819 mother->p->FolderSearch.Reset();
2820 p->FolderSearch.Reset();
2822 *
this = std::move(*mother);
2833 assert(search_pattern);
2847 for (
C4GroupEntry * e_pre = p->FirstEntry; e_pre != entry; e_pre = e_pre->
Next)
2849 if (e_pre->Offset >= p->FilePtr)
2851 PreCacheEntry(e_pre);
2856 PreCacheEntry(entry);
#define C4CFN_PlayerFiles
#define C4CFN_ScenarioSections
#define C4CFN_ScenarioFiles
#define C4CFN_ObjectInfoFiles
#define C4CFN_FolderFiles
void MemScramble(BYTE *buffer, int size)
void C4Group_SetTempPath(const char *path)
bool C4Group_ExplodeDirectory(const char *filename)
bool C4Group_PackDirectoryTo(const char *filename, const char *to_filename)
bool C4Group_PackDirectory(const char *filename)
bool C4Group_CopyItem(const char *source, const char *target, bool no_sorting, bool reset_attributes)
void C4Group_SetSortList(const char **sort_list)
bool C4Group_MoveItem(const char *source, const char *target, bool no_sorting)
int SortRank(const char *element, const char *sort_list)
bool C4Group_DeleteItem(const char *item_name, bool do_recycle)
void C4Group_SetProcessCallback(bool(*callback)(const char *, int))
bool C4Group_TestIgnore(const char *filename)
bool C4Group_UnpackDirectory(const char *filename)
bool C4Group_IsExcluded(const char *filename, const char *exclude_list)
const char ** C4Group_SortList
bool C4Group_IsGroup(const char *filename)
char C4Group_Ignore[_MAX_PATH_LEN]
const char * C4Group_GetTempPath()
bool C4Group_ReadFile(const char *filename, char **data, size_t *size)
bool(* C4Group_ProcessCallback)(const char *, int)
char C4Group_TempPath[_MAX_PATH_LEN]
const int32_t C4GroupSwapThreshold
const int C4GroupFileVer2
const int C4GroupFileVer1
bool EraseItemSafe(const char *szFilename)
bool LogF(const char *strMessage,...)
int UncompressedFileSize(const char *szFilename)
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil)
void SReplaceChar(char *str, char fc, char tc)
bool SIsModule(const char *szList, const char *szString, int *ipIndex, bool fCaseSensitive)
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
void SInsert(char *szString, const char *szInsert, int iPosition, int iMaxLen)
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL, int iIndex)
void SAppend(const char *szSource, char *szTarget, int iMaxL)
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
std::enable_if< std::is_nothrow_default_constructible< T >::value >::type InplaceReconstruct(T *obj)
bool SEqual(const char *szStr1, const char *szStr2)
size_t SLen(const char *sptr)
StdStrBuf FormatString(const char *szFmt,...)
bool EraseItem(const char *szItemName)
bool CreateItem(const char *szItemname)
bool TruncatePath(char *szPath)
bool DirectoryExists(const char *szFilename)
bool GetParentPath(const char *szFilename, char *szBuffer)
bool WildcardMatch(const char *szWildcard, const char *szString)
void MakeTempFilename(char *szFilename)
bool EraseDirectory(const char *szDirName)
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
char * GetFilename(char *szPath)
void AppendBackslash(char *szFilename)
bool WildcardListMatch(const char *szWildcardList, const char *szString)
bool RenameItem(const char *szItemName, const char *szNewItemName)
bool CreatePath(const std::string &path)
bool CopyItem(const char *szSource, const char *szTarget, bool fResetAttributes)
bool MoveItem(const char *szSource, const char *szTarget)
int ForEachFile(const char *szDirName, bool(*fnCallback)(const char *))
bool FileExists(const char *szFileName)
bool ItemExists(const char *szItemName)
bool EraseFile(const char *szFileName)
size_t FileSize(const char *fname)
bool RenameFile(const char *szFileName, const char *szNewFileName)
void Set(const DirectoryIterator &directories, const char *path)
char DiskPath[_MAX_PATH_LEN]
bool Rename(const char *filename, const char *new_name)
bool Read(void *buffer, size_t size) override
bool FindNextEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
const C4GroupEntry * GetFirstEntry() const
bool DeleteEntry(const char *filename, bool do_recycle=false)
bool HasPackedMother() const
bool Merge(const char *folders)
size_t EntrySize(const char *wildcard=nullptr)
const C4GroupHeader & GetHeader() const
bool Extract(const char *files, const char *destination=nullptr, const char *exclude=nullptr)
const char * GetName() const
size_t AccessedEntrySize() const override
bool AccessNextEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool start_at_filename=false)
bool AccessEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool needs_to_be_a_group=false)
int EntryCount(const char *wildcard=nullptr)
StdStrBuf GetFullName() const
int PreCacheEntries(const char *search_pattern, bool cache_previous=false)
bool ExtractEntry(const char *filename, const char *destination=nullptr)
bool Add(const char *filename, const char *entry_name)
unsigned int EntryCRC32(const char *wildcard=nullptr)
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
bool OpenAsChild(C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
bool SetNoSort(bool no_sorting)
C4GroupEntry * GetEntry(const char *entry_name)
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
bool OpenChild(const char *entry_name)
bool Sort(const char *list)
void SetStdOutput(bool log_status)
void ResetSearch(bool reload_contents=false)
bool Move(const char *filename, const char *entry_name)
bool Delete(const char *files, bool recursive=false)
bool SortByList(const char **list, const char *filename=nullptr)
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
bool Open(const char *group_name, bool do_create=false)
bool Advance(int offset) override
bool Close(StdBuf **ppMemory=nullptr)
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
bool Write(const void *pBuffer, int iSize)
bool Read(void *pBuffer, size_t iSize) override
bool Open(const char *szFileName, bool fCompressed=false)
size_t GetFileSize() const
void Reset(const char *dirname, bool force_reread=false)
static void DeletePointer(void *data)
void SetLength(size_t iLength)
const char * getData() const
bool ValidateFilename(char *szFilename, size_t iMaxSize=_MAX_PATH)
bool(* ProcessCallback)(const char *, int)
C4GroupEntry * FirstEntry
DirectoryIterator FolderSearch
C4GroupEntry LastFolderSearchEntry
C4GroupEntry FolderSearchEntry