| 1018 | } |
| 1019 | |
| 1020 | void PakWriter::Finalize() |
| 1021 | { |
| 1022 | if (_finalized) { |
| 1023 | return; |
| 1024 | } |
| 1025 | |
| 1026 | _finalized = true; |
| 1027 | |
| 1028 | Array<PakFile::Item*> queuedDirectories; |
| 1029 | bool hasFiles = false; |
| 1030 | |
| 1031 | for (PakFile::Item& item : _rootItems) { |
| 1032 | if ((item.Flags & PakFile::ItemFlags::Directory) == PakFile::ItemFlags::Directory) { |
| 1033 | arrayAppend(queuedDirectories, &item); |
| 1034 | } else { |
| 1035 | hasFiles = true; |
| 1036 | } |
| 1037 | } |
| 1038 | |
| 1039 | for (std::int32_t i = 0; i < queuedDirectories.size(); i++) { |
| 1040 | PakFile::Item& item = *queuedDirectories[i]; |
| 1041 | for (PakFile::Item& child : item.ChildItems) { |
| 1042 | if ((child.Flags & PakFile::ItemFlags::Directory) == PakFile::ItemFlags::Directory) { |
| 1043 | arrayAppend(queuedDirectories, &child); |
| 1044 | } else { |
| 1045 | hasFiles = true; |
| 1046 | } |
| 1047 | } |
| 1048 | } |
| 1049 | |
| 1050 | if DEATH_UNLIKELY(!hasFiles) { |
| 1051 | // No files added - close the stream and try to delete the file |
| 1052 | String path = _outputStream->GetPath(); |
| 1053 | _outputStream = nullptr; |
| 1054 | if (!_alreadyExisted) { |
| 1055 | FileSystem::RemoveFile(path); |
| 1056 | } |
| 1057 | return; |
| 1058 | } |
| 1059 | |
| 1060 | if (!queuedDirectories.empty()) { |
| 1061 | std::size_t i = queuedDirectories.size() - 1; |
| 1062 | while (true) { |
| 1063 | PakFile::Item& item = *queuedDirectories[i]; |
| 1064 | item.Offset = _outputStream->GetPosition(); |
| 1065 | |
| 1066 | // Names need to be sorted, because binary search is used to find files |
| 1067 | std::sort(item.ChildItems.begin(), item.ChildItems.end(), [](const PakFile::Item& a, const PakFile::Item& b) { |
| 1068 | return a.Name < b.Name; |
| 1069 | }); |
| 1070 | |
| 1071 | #if defined(WITH_ZLIB) || defined(WITH_MINIZ) |
| 1072 | if (_useCompressedIndex) { |
| 1073 | DeflateWriter dw(*_outputStream); |
| 1074 | dw.WriteVariableUint32(std::uint32_t(item.ChildItems.size())); |
| 1075 | for (PakFile::Item& childItem : item.ChildItems) { |
| 1076 | WriteItemDescription(dw, childItem, item.Offset); |
| 1077 | } |
nothing calls this directly
no test coverage detected