UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PakFile.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
10template <typename ShouldVisitFunc, class ContainerType>
11void FPakFile::FindFilesAtPathInIndex(const FDirectoryIndex& TargetIndex, const FDirectoryTreeIndex& TargetTreeIndex, ContainerType& OutFiles,
12 const FString& FullSearchPath, const FVisitFilter<ShouldVisitFunc>& VisitFilter) const
13{
14 TRACE_CPUPROFILER_EVENT_SCOPE(FindFilesAtPathInIndex);
15
17 if (FullSearchPath.StartsWith(MountPoint))
18 {
20 }
21 else
22 {
23 // Directory is unnormalized and might not end with /; MountPoint is guaranteed to end with /.
24 // Act as if we were called with a normalized directory if adding slash makes it match MountPoint.
25 if (FStringView(FullSearchPath).StartsWith(FStringView(MountPoint).LeftChop(1)))
26 {
28 }
29 else
30 {
31 // Early out; directory does not start with MountPoint and so will not match any of files in this pakfile.
32 return;
33 }
34 }
35
36 TArray<FString> DirectoriesInPak; // List of all unique directories at path
37
38#if ENABLE_PAKFILE_USE_DIRECTORY_TREE
39 if (ShouldUseDirectoryTree())
40 {
42
43#if !UE_BUILD_SHIPPING
45 {
46 ContainerType OutFilesIndexed;
48 FindFilesAtPathInIndexInternal(RelSearchPath, TargetIndex, OutFilesIndexed, OutDirectoriesInPakIndexed, FullSearchPath, VisitFilter);
49 if (!ValidateDirectoryTreeSearchConsistency(OutFiles, DirectoriesInPak, OutFilesIndexed, OutDirectoriesInPakIndexed))
50 {
52 TEXT("Mismatch between directoryindex and directorytreeindex search when searching for [%s] in pak [%s]"),
53 *FString(RelSearchPath), *GetFilename());
54 }
55 }
56#endif // !UE_BUILD_SHIPPING
57 }
58 else
59#endif // ENABLE_PAKFILE_USE_DIRECTORY_TREE
60 {
61 FindFilesAtPathInIndexInternal(RelSearchPath, TargetIndex, OutFiles, DirectoriesInPak, FullSearchPath, VisitFilter);
62 }
64}
65
66#if ENABLE_PAKFILE_USE_DIRECTORY_TREE
67template <typename ShouldVisitFunc, class ContainerType>
68void FPakFile::FindFilesAtPathInTreeIndexInternal(FStringView RelSearchPath, const FDirectoryTreeIndex& TargetTreeIndex,
69 ContainerType& OutFiles, TArray<FString>& OutDirectories, const FString& FullSearchPath,
71{
72 if (RelSearchPath.IsEmpty())
73 {
75 {
76 FindFilesAtPathInPakDirectoryInternal(MountPoint, Pair.Key, Pair.Value, OutFiles, OutDirectories,
78 }
79 }
80 else
81 {
83 if (PakDirectory)
84 {
85 FindFilesAtPathInPakDirectoryInternal(MountPoint, RelSearchPath, *PakDirectory, OutFiles, OutDirectories,
87
88 if (VisitFilter.bRecursive || VisitFilter.bIncludeDirectories)
89 {
90 // TODO: Add TDirectoryTree::CreatePathIterator so we can avoid the copy of children and the redundant
91 // lookups of the children in the tree.
95 for (const FString& ChildDirectoryPath : OutChildDirectories)
96 {
100 {
101 FindFilesAtPathInPakDirectoryInternal(MountPoint, RelChildPath,
103 }
104 }
105 }
106 }
107 }
108}
109
110#if !UE_BUILD_SHIPPING
111template <class ContainerType>
112bool FPakFile::ValidateDirectoryTreeSearchConsistency(const ContainerType& FilesTree, const TArray<FString>& DirectoriesInPakTree, const ContainerType& FilesIndexed, const TArray<FString>& DirectoriesInPakIndexed) const
113{
114 if (FilesTree.Num() == FilesIndexed.Num())
115 {
116 for (const FString& File : FilesTree)
117 {
118 if (!FilesIndexed.Contains(File))
119 {
120 return false;
121 }
122 }
123 }
124 else
125 {
126 return false;
127 }
128
130 {
131 for (const FString& Dir : DirectoriesInPakTree)
132 {
133 if (!DirectoriesInPakIndexed.Contains(Dir))
134 {
135 return false;
136 }
137 }
138 }
139 else
140 {
141 return false;
142 }
143
144 return true;
145}
146#endif // UE_BUILD_SHIPPING
147
148#endif // ENABLE_PAKFILE_USE_DIRECTORY_TREE
149
150template <typename ShouldVisitFunc, class ContainerType>
151void FPakFile::FindFilesAtPathInIndexInternal(const FStringView& RelSearchPath, const FDirectoryIndex& TargetIndex,
152 ContainerType& OutFiles, TArray<FString>& OutDirectories,
153 const FString& FullSearchPath, const FVisitFilter<ShouldVisitFunc>& VisitFilter) const
154{
155 for (TMap<FString, FPakDirectory>::TConstIterator It(TargetIndex); It; ++It)
156 {
157 // Check if the file is under the specified path.
158 if (FStringView(It.Key()).StartsWith(RelSearchPath))
159 {
160 FindFilesAtPathInPakDirectoryInternal(MountPoint, It.Key(), It.Value(), OutFiles, OutDirectories,
162 }
163 }
164}
165
166template <typename ShouldVisitFunc, class ContainerType>
167void FPakFile::FindFilesAtPathInPakDirectoryInternal(const FString& MountPoint, FStringView RelPathInIndex,
170{
171 FString FullPathInIndex = PakPathCombine(MountPoint, RelPathInIndex);
172 if (VisitFilter.bRecursive == true)
173 {
174 // Add everything
175 if (VisitFilter.bIncludeFiles)
176 {
178 for (FPakDirectory::TConstIterator FileIt(PakDirectory); FileIt; ++FileIt)
179 {
180 FilePathUnderDirectory << FileIt.Key();
181 if (VisitFilter.ShouldVisit(FilePathUnderDirectory.ToView()))
182 {
184 }
185
187 }
188 }
189 if (VisitFilter.bIncludeDirectories)
190 {
192 {
193 if (VisitFilter.ShouldVisit(FullPathInIndex))
194 {
196 }
197 }
198 }
199 }
200 else
201 {
204 : INDEX_NONE;
205 // Add files in the specified folder only.
206 if (VisitFilter.bIncludeFiles && SubDirIndex == INDEX_NONE)
207 {
209 for (FPakDirectory::TConstIterator FileIt(PakDirectory); FileIt; ++FileIt)
210 {
211 FilePathUnderDirectory << FileIt.Key();
212 if (VisitFilter.ShouldVisit(FilePathUnderDirectory.ToView()))
213 {
215 }
216
218 }
219 }
220 // Add sub-folders in the specified folder only
221 if (VisitFilter.bIncludeDirectories && SubDirIndex >= 0)
222 {
223 FString SubDirPath = FullPathInIndex.Left(SubDirIndex + 1);
224 if (VisitFilter.ShouldVisit(SubDirPath))
225 {
227 }
228 }
229 }
230}
231
232template <typename ShouldVisitFunc>
233FPakFile::FVisitFilter<ShouldVisitFunc>::FVisitFilter(const ShouldVisitFunc& InShouldVisit, bool bInIncludeFiles, bool bInIncludeDirectories, bool bInRecursive)
234 : ShouldVisit(InShouldVisit)
235 , bIncludeFiles(bInIncludeFiles)
236 , bIncludeDirectories(bInIncludeDirectories)
237 , bRecursive(bInRecursive)
238{
239
240}
241
242template <typename ShouldVisitFunc, class ContainerType>
243void FPakFile::FindPrunedFilesAtPathInternal(const TCHAR* InPath, ContainerType& OutFiles, const FVisitFilter<ShouldVisitFunc>& VisitFilter) const
244{
245 // Make sure all directory names end with '/'.
246 FString FullSearchPath(InPath);
248
249 // Check the specified path is under the mount point of this pak file.
250 // The reverse case (MountPoint StartsWith Directory) is needed to properly handle
251 // pak files that are a subdirectory of the actual directory.
252 if (!FullSearchPath.StartsWith(MountPoint) && !MountPoint.StartsWith(FullSearchPath))
253 {
254 return;
255 }
256
257 FScopedPakDirectoryIndexAccess ScopeAccess(*this);
258#if ENABLE_PAKFILE_RUNTIME_PRUNING_VALIDATE
259 if (ShouldValidatePrunedDirectory())
260 {
262 FindFilesAtPathInIndex(DirectoryIndex, DirectoryTreeIndex, FullFoundFiles, FullSearchPath, VisitFilter);
263 FindFilesAtPathInIndex(PrunedDirectoryIndex, PrunedDirectoryTreeIndex, PrunedFoundFiles, FullSearchPath, VisitFilter);
264 ValidateDirectorySearch(FullFoundFiles, PrunedFoundFiles, InPath);
265
266 for (const FString& FoundFile : FullFoundFiles)
267 {
268 OutFiles.Add(FoundFile);
269 }
270 }
271 else
272#endif
273 {
274 FindFilesAtPathInIndex(DirectoryIndex, DirectoryTreeIndex, OutFiles, FullSearchPath, VisitFilter);
275 }
276}
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
EDirectoryTreeGetFlags
Definition DirectoryTree.h:28
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
TStringView< TCHAR > FStringView
Definition StringFwd.h:45
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
const FString & GetFilename() const
Definition IPlatformFilePak.h:1005
static void MakeDirectoryFromPath(FString &Path)
Definition IPlatformFilePak.h:1402
static FString PakPathCombine(FStringView Parent, FStringView Child)
Definition PakFile.cpp:1319
Definition Array.h:670
Definition UnrealString.h.inl:34
auto Add(AppendedCharType Char) -> decltype(AppendChar(Char),(void) 0)
Definition StringBuilder.h:330
Definition StringBuilder.h:509
ViewType RightChop(int32 CharCount) const
Definition StringView.h:599
bool StartsWith(CharType Prefix) const
Definition StringView.h:366
@ CaseSensitive
Definition CString.h:23
@ FromStart
Definition CString.h:36
Definition Tuple.h:652