bool FLocalTitleFile::ReadFile(const FString& DLName) { const TArray< uint8 >* ExistingFileContents = DLNameToFileContents.Find(DLName); if (ExistingFileContents != nullptr) { TriggerOnReadFileCompleteDelegates(true, DLName); return true; } const FString FileName = GetFileNameFromDLName(DLName); TArray<uint8> FileContents; if (!FFileHelper::LoadFileToArray(FileContents, *(RootDirectory + FileName))) { TriggerOnReadFileCompleteDelegates(false, DLName); return false; } DLNameToFileContents.Add(DLName, FileContents); TriggerOnReadFileCompleteDelegates(true, DLName); return true; }
void FSurveyTitleCdnStorage::ReadFile_HttpRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { bool bResult = false; FString ResponseStr, ErrorStr; // should have a pending Http request FPendingFileRequest PendingRequest = FileRequests.FindChecked(HttpRequest.Get()); FileRequests.Remove(HttpRequest.Get()); // Cloud file being operated on FCloudFile* CloudFile = GetCloudFile(PendingRequest.FileName, true); CloudFile->AsyncState = EOnlineAsyncTaskState::Failed; CloudFile->Data.Empty(); if (bSucceeded && HttpResponse.IsValid()) { if (EHttpResponseCodes::IsOk(HttpResponse->GetResponseCode())) { UE_LOG(LogEpicSurvey, Verbose, TEXT("ReadFile request complete. url=%s code=%d"), *HttpRequest->GetURL(), HttpResponse->GetResponseCode()); // update the memory copy of the file with data that was just downloaded CloudFile = GetCloudFile(PendingRequest.FileName, true); CloudFile->AsyncState = EOnlineAsyncTaskState::Done; CloudFile->Data = HttpResponse->GetContent(); // cache to disk on successful download SaveCloudFileToDisk(CloudFile->FileName,CloudFile->Data); bResult = true; } else { ErrorStr = FString::Printf(TEXT("Invalid response. code=%d error=%s"), HttpResponse->GetResponseCode(), *HttpResponse->GetContentAsString()); } } else { ErrorStr = TEXT("No response"); } if (!ErrorStr.IsEmpty()) { UE_LOG(LogEpicSurvey, Verbose, TEXT("ReadFile request failed. %s"), *ErrorStr); } TriggerOnReadFileCompleteDelegates(bResult, PendingRequest.FileName); }
bool FCdnNewsFeedTitleFile::ReadFile(const FString& FileName) { FString ErrorStr; // Make sure valid filename was specified if (FileName.IsEmpty() || FileName.Contains(TEXT(" "))) { ErrorStr = FString::Printf(TEXT("Invalid filename filename=%s"), *FileName); } // Make sure a file request for this file is not currently pending for (TMap<IHttpRequest*, FPendingFileRequest>::TConstIterator It(FileRequests); It; ++It) { if (It.Value() == FPendingFileRequest(FileName)) { ErrorStr = FString::Printf(TEXT("File request already pending for filename=%s"), *FileName); break; } } if (!ErrorStr.IsEmpty()) { UE_LOG(LogEpicStorage, Warning, TEXT("ReadFile request failed. %s"), *ErrorStr); TriggerOnReadFileCompleteDelegates(false, FileName); return false; } // Mark file entry as in progress FCloudFile* CloudFile = GetCloudFile(FileName, true); CloudFile->AsyncState = EOnlineAsyncTaskState::InProgress; // load file from disk FString LocalFilePath = GetLocalFilePath(FileName); bool bLoadedFile = FFileHelper::LoadFileToArray(CloudFile->Data, *LocalFilePath, FILEREAD_Silent); if (bLoadedFile) { UE_LOG(LogEpicStorage, Verbose, TEXT("ReadFile request. Local file read from cache =%s"), *LocalFilePath); //@todo samz - move reading/hashing of local file to async task // verify hash of file if it exists FCloudFileHeader* CloudFileHeader = GetCloudFileHeader( FileName); if (CloudFileHeader != NULL && !CloudFileHeader->Hash.IsEmpty()) { uint8 LocalHash[20]; FSHA1::HashBuffer(CloudFile->Data.GetData(), CloudFile->Data.Num(), LocalHash); // concatenate 20 bye SHA1 hash to string FString LocalHashStr; for (int Idx=0; Idx < 20; Idx++) { LocalHashStr += FString::Printf(TEXT("%02x"),LocalHash[Idx]); } // if hash matches then just use the local file if (CloudFileHeader->Hash == LocalHashStr) { UE_LOG(LogEpicStorage, Verbose, TEXT("Local file hash matches cloud header. No need to download for filename=%s"), *FileName); CloudFile->AsyncState = EOnlineAsyncTaskState::Done; TriggerOnReadFileCompleteDelegates(true, FileName); return true; } } } else { UE_LOG(LogEpicStorage, Verbose, TEXT("ReadFile request. Local file failed to read from cache =%s"), *LocalFilePath); } // Empty local that was loaded CloudFile->Data.Empty(); // Create the Http request and add to pending request list TSharedRef<class IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest(); FileRequests.Add(&HttpRequest.Get(), FPendingFileRequest(FileName)); HttpRequest->OnProcessRequestComplete().BindThreadSafeSP(this, &FCdnNewsFeedTitleFile::ReadFile_HttpRequestComplete); HttpRequest->SetURL( FileName ); HttpRequest->SetVerb(TEXT("GET")); return HttpRequest->ProcessRequest(); }