Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
IPlatformFileOpenLogWrapper.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Async/AsyncFileHandle.h"
6#include "Containers/Array.h"
7#include "Containers/Map.h"
8#include "Containers/StringConv.h"
9#include "Containers/UnrealString.h"
10#include "CoreTypes.h"
11#include "GenericPlatform/GenericPlatformFile.h"
12#include "HAL/CriticalSection.h"
13#include "HAL/PlatformCrt.h"
14#include "HAL/PlatformMisc.h"
15#include "HAL/PlatformProperties.h"
16#include "Misc/DataDrivenPlatformInfoRegistry.h"
17#include "Misc/DateTime.h"
18#include "Misc/Parse.h"
19#include "Misc/Paths.h"
20
21class FPlatformFileOpenLog;
22class IAsyncReadFileHandle;
23class IMappedFileHandle;
24
26
27class FLoggingAsyncReadFileHandle final : public IAsyncReadFileHandle
28{
29 FPlatformFileOpenLog* Owner;
30 FString Filename;
31 IAsyncReadFileHandle* ActualRequest;
32public:
33 FLoggingAsyncReadFileHandle(FPlatformFileOpenLog* InOwner, const TCHAR* InFilename, IAsyncReadFileHandle* InActualRequest)
34 : Owner(InOwner)
35 , Filename(InFilename)
36 , ActualRequest(InActualRequest)
37 {
38 }
39 ~FLoggingAsyncReadFileHandle()
40 {
41 delete ActualRequest;
42 }
43 virtual IAsyncReadRequest* SizeRequest(FAsyncFileCallBack* CompleteCallback = nullptr) override
44 {
45 return ActualRequest->SizeRequest(CompleteCallback);
46 }
47 virtual IAsyncReadRequest* ReadRequest(int64 Offset, int64 BytesToRead, EAsyncIOPriorityAndFlags PriorityAndFlags = AIOP_Normal, FAsyncFileCallBack* CompleteCallback = nullptr, uint8* UserSuppliedMemory = nullptr) override;
48};
49
50
51class FPlatformFileOpenLog : public IPlatformFile
52{
53protected:
54
55 IPlatformFile* LowerLevel;
56 FCriticalSection CriticalSection;
57 int64 OpenOrder;
58 TMap<FString, int64> FilenameAccessMap;
59 TArray<IFileHandle*> LogOutput;
60
61public:
62
63 FPlatformFileOpenLog()
64 : LowerLevel(nullptr)
65 , OpenOrder(0)
66 {
67 }
68
69 virtual ~FPlatformFileOpenLog()
70 {
71 }
72
73 //~ For visibility of overloads we don't override
74 using IPlatformFile::IterateDirectory;
75 using IPlatformFile::IterateDirectoryRecursively;
76 using IPlatformFile::IterateDirectoryStat;
77 using IPlatformFile::IterateDirectoryStatRecursively;
78
79 virtual bool ShouldBeUsed(IPlatformFile* Inner, const TCHAR* CmdLine) const override
80 {
81 bool bResult = FParse::Param(CmdLine, TEXT("FileOpenLog")) || FParse::Param(CmdLine, TEXT("FilePackageOpenLog"));
82 return bResult;
83 }
84
85 virtual bool Initialize(IPlatformFile* Inner, const TCHAR* CommandLineParam) override
86 {
87 LowerLevel = Inner;
88 FString LogFileDirectory;
89 FString LogFilePath;
90 FString PlatformStr;
91 FString OutputDirectoryBase;
92
93 if (!FParse::Value(CommandLineParam, TEXT("FOOBASEDIR="), OutputDirectoryBase))
94 {
95 if (FParse::Param(CommandLineParam, TEXT("FOOUSESAVEDDIR")))
96 {
97 OutputDirectoryBase = FPaths::ProjectSavedDir();
98 }
99 else
100 {
101 OutputDirectoryBase = FPlatformMisc::ProjectDir();
102 }
103 }
104
105 if (FParse::Value(CommandLineParam, TEXT("TARGETPLATFORM="), PlatformStr))
106 {
107 TArray<FString> PlatformNames;
108 if (!(PlatformStr == TEXT("None") || PlatformStr == TEXT("All")))
109 {
110 PlatformStr.ParseIntoArray(PlatformNames, TEXT("+"), true);
111 }
112
113 for (int32 Platform = 0;Platform < PlatformNames.Num(); ++Platform)
114 {
115 if (FDataDrivenPlatformInfoRegistry::GetPlatformInfo(PlatformNames[Platform]).bIsConfidential)
116 {
117 LogFileDirectory = FPaths::Combine(OutputDirectoryBase, TEXT("Platforms"), *PlatformNames[Platform], TEXT("Build"), TEXT("FileOpenOrder"));
118 }
119 else
120 {
121 LogFileDirectory = FPaths::Combine(OutputDirectoryBase, TEXT( "Build" ), *PlatformNames[Platform], TEXT("FileOpenOrder"));
122 }
123#if WITH_EDITOR
124 LogFilePath = FPaths::Combine( *LogFileDirectory, TEXT("EditorOpenOrder.log"));
125#else
126 FString OrderSuffix = TEXT("");
127 FParse::Value(CommandLineParam, TEXT("FooSuffix="), OrderSuffix);
128
129 FString GameOpenOrderFileName = FString::Printf(TEXT("GameOpenOrder%s.log"), *OrderSuffix);
130 LogFilePath = FPaths::Combine( *LogFileDirectory, *GameOpenOrderFileName);
131#endif
132 Inner->CreateDirectoryTree(*LogFileDirectory);
133 auto* FileHandle = Inner->OpenWrite(*LogFilePath, false, false);
134 if (FileHandle)
135 {
136 LogOutput.Add(FileHandle);
137 }
138 }
139 }
140 else
141 {
142 if (FDataDrivenPlatformInfoRegistry::GetPlatformInfo(FPlatformProperties::IniPlatformName()).bIsConfidential)
143 {
144 LogFileDirectory = FPaths::Combine(OutputDirectoryBase, TEXT("Platforms"), StringCast<TCHAR>(FPlatformProperties::PlatformName()).Get(), TEXT("Build"), TEXT("FileOpenOrder"));
145 }
146 else
147 {
148 LogFileDirectory = FPaths::Combine(OutputDirectoryBase, TEXT("Build"), StringCast<TCHAR>(FPlatformProperties::PlatformName()).Get(), TEXT("FileOpenOrder"));
149 }
150#if WITH_EDITOR
151 LogFilePath = FPaths::Combine( *LogFileDirectory, TEXT("EditorOpenOrder.log"));
152#else
153 LogFilePath = FPaths::Combine( *LogFileDirectory, TEXT("GameOpenOrder.log"));
154#endif
155 Inner->CreateDirectoryTree(*LogFileDirectory);
156 auto* FileHandle = Inner->OpenWrite(*LogFilePath, false, false);
157 if (FileHandle)
158 {
159 LogOutput.Add(FileHandle);
160 }
161 }
162 return true;
163 }
164 virtual IPlatformFile* GetLowerLevel() override
165 {
166 return LowerLevel;
167 }
168 virtual void SetLowerLevel(IPlatformFile* NewLowerLevel) override
169 {
170 LowerLevel = NewLowerLevel;
171 }
172 static const TCHAR* GetTypeName()
173 {
174 return TEXT("FileOpenLog");
175 }
176 virtual const TCHAR* GetName() const override
177 {
178 return GetTypeName();
179 }
180 virtual bool FileExists(const TCHAR* Filename) override
181 {
182 return LowerLevel->FileExists(Filename);
183 }
184 virtual int64 FileSize(const TCHAR* Filename) override
185 {
186 return LowerLevel->FileSize(Filename);
187 }
188 virtual bool DeleteFile(const TCHAR* Filename) override
189 {
190 return LowerLevel->DeleteFile(Filename);
191 }
192 virtual bool IsReadOnly(const TCHAR* Filename) override
193 {
194 return LowerLevel->IsReadOnly(Filename);
195 }
196 virtual bool MoveFile(const TCHAR* To, const TCHAR* From) override
197 {
198 return LowerLevel->MoveFile(To, From);
199 }
200 virtual bool SetReadOnly(const TCHAR* Filename, bool bNewReadOnlyValue) override
201 {
202 return LowerLevel->SetReadOnly(Filename, bNewReadOnlyValue);
203 }
204 virtual FDateTime GetTimeStamp(const TCHAR* Filename) override
205 {
206 return LowerLevel->GetTimeStamp(Filename);
207 }
208 virtual void SetTimeStamp(const TCHAR* Filename, FDateTime DateTime) override
209 {
210 LowerLevel->SetTimeStamp(Filename, DateTime);
211 }
212 virtual FDateTime GetAccessTimeStamp(const TCHAR* Filename) override
213 {
214 return LowerLevel->GetAccessTimeStamp(Filename);
215 }
216 virtual FString GetFilenameOnDisk(const TCHAR* Filename) override
217 {
218 return LowerLevel->GetFilenameOnDisk(Filename);
219 }
220 virtual IFileHandle* OpenRead(const TCHAR* Filename, bool bAllowWrite) override
221 {
222 IFileHandle* Result = LowerLevel->OpenRead(Filename, bAllowWrite);
223 if (Result)
224 {
225 AddToOpenLog(Filename);
226 }
227 return Result;
228 }
229 virtual IFileHandle* OpenWrite(const TCHAR* Filename, bool bAppend = false, bool bAllowRead = false) override
230 {
231 return LowerLevel->OpenWrite(Filename, bAppend, bAllowRead);
232 }
233 virtual bool DirectoryExists(const TCHAR* Directory) override
234 {
235 return LowerLevel->DirectoryExists(Directory);
236 }
237 virtual bool CreateDirectory(const TCHAR* Directory) override
238 {
239 return LowerLevel->CreateDirectory(Directory);
240 }
241 virtual bool DeleteDirectory(const TCHAR* Directory) override
242 {
243 return LowerLevel->DeleteDirectory(Directory);
244 }
245 virtual FFileStatData GetStatData(const TCHAR* FilenameOrDirectory) override
246 {
247 return LowerLevel->GetStatData(FilenameOrDirectory);
248 }
249 virtual bool IterateDirectory(const TCHAR* Directory, IPlatformFile::FDirectoryVisitor& Visitor) override
250 {
251 return LowerLevel->IterateDirectory( Directory, Visitor );
252 }
253 virtual bool IterateDirectoryRecursively(const TCHAR* Directory, IPlatformFile::FDirectoryVisitor& Visitor) override
254 {
255 return LowerLevel->IterateDirectoryRecursively( Directory, Visitor );
256 }
257 virtual bool IterateDirectoryStat(const TCHAR* Directory, IPlatformFile::FDirectoryStatVisitor& Visitor) override
258 {
259 return LowerLevel->IterateDirectoryStat( Directory, Visitor );
260 }
261 virtual bool IterateDirectoryStatRecursively(const TCHAR* Directory, IPlatformFile::FDirectoryStatVisitor& Visitor) override
262 {
263 return LowerLevel->IterateDirectoryStatRecursively( Directory, Visitor );
264 }
265 virtual bool DeleteDirectoryRecursively(const TCHAR* Directory) override
266 {
267 return LowerLevel->DeleteDirectoryRecursively( Directory );
268 }
269 virtual bool CopyFile(const TCHAR* To, const TCHAR* From, EPlatformFileRead ReadFlags = EPlatformFileRead::None, EPlatformFileWrite WriteFlags = EPlatformFileWrite::None) override
270 {
271 return LowerLevel->CopyFile( To, From, ReadFlags, WriteFlags);
272 }
273 virtual bool CreateDirectoryTree(const TCHAR* Directory) override
274 {
275 return LowerLevel->CreateDirectoryTree(Directory);
276 }
277 virtual bool CopyDirectoryTree(const TCHAR* DestinationDirectory, const TCHAR* Source, bool bOverwriteAllExisting) override
278 {
279 return LowerLevel->CopyDirectoryTree(DestinationDirectory, Source, bOverwriteAllExisting);
280 }
281 virtual FString ConvertToAbsolutePathForExternalAppForRead( const TCHAR* Filename ) override
282 {
283 return LowerLevel->ConvertToAbsolutePathForExternalAppForRead(Filename);
284 }
285 virtual FString ConvertToAbsolutePathForExternalAppForWrite( const TCHAR* Filename ) override
286 {
287 return LowerLevel->ConvertToAbsolutePathForExternalAppForWrite(Filename);
288 }
289 virtual bool SendMessageToServer(const TCHAR* Message, IFileServerMessageHandler* Handler) override
290 {
291 return LowerLevel->SendMessageToServer(Message, Handler);
292 }
293 virtual IAsyncReadFileHandle* OpenAsyncRead(const TCHAR* Filename) override
294 {
295 // we must not record the "open" here...what matters is when we start reading the file!
296 return new FLoggingAsyncReadFileHandle(this, Filename, LowerLevel->OpenAsyncRead(Filename));
297 }
298 virtual IMappedFileHandle* OpenMapped(const TCHAR* Filename) override
299 {
300 return LowerLevel->OpenMapped(Filename);
301 }
302
303 void AddToOpenLog(const TCHAR* Filename)
304 {
305 CriticalSection.Lock();
306 if (FilenameAccessMap.Find(Filename) == nullptr)
307 {
308 FilenameAccessMap.Emplace(Filename, ++OpenOrder);
309 FString Text = FString::Printf(TEXT("\"%s\" %llu\n"), Filename, OpenOrder);
310 for (auto File = LogOutput.CreateIterator(); File; ++File)
311 {
312 (*File)->Write((uint8*)StringCast<ANSICHAR>(*Text).Get(), Text.Len());
313 }
314 }
315 CriticalSection.Unlock();
316 }
317
318 void AddPackageToOpenLog(const TCHAR* Filename)
319 {
320 CriticalSection.Lock();
321 if (FilenameAccessMap.Find(Filename) == nullptr)
322 {
323 FilenameAccessMap.Emplace(Filename, ++OpenOrder);
324 FString Text = FString::Printf(TEXT("\"%s\" %llu\n"), Filename, OpenOrder);
325 for (auto File = LogOutput.CreateIterator(); File; ++File)
326 {
327 (*File)->Write((uint8*)StringCast<ANSICHAR>(*Text).Get(), Text.Len());
328 }
329 }
330 CriticalSection.Unlock();
331 }
332};
333#endif // !UE_BUILD_SHIPPING
#define UE_BUILD_SHIPPING
Definition Build.h:4