Agrarsense
CSVFile.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#include "CSVFile.h"
7
10
11#include "Misc/Paths.h"
12#include "HAL/PlatformFileManager.h"
13
14UCSVFile* UCSVFile::CreateCSVFile(const FString& FileNameWithoutExtension, const FCSVFileSettings& Settings)
15{
16 UCSVFile* CSVFile = NewObject<UCSVFile>(UCSVFile::StaticClass());
17 CSVFile->AddToRoot();
18 if (CSVFile)
19 {
20 CSVFile->Create(FileNameWithoutExtension, Settings);
21 }
22 return CSVFile;
23}
24
25void UCSVFile::Create(const FString& FileNameWithoutExtension, const FCSVFileSettings& Settings)
26{
27 CurrentSettings = Settings;
28
29 // Simulator data directory for this run. Returns SIMULATOR_ROOT/Data/Run_{NUM}
30 FString DataDirectory = UAgrarsensePaths::GetDataFolder();
31
32 FString BasePath = Settings.CustomPath.IsEmpty() ? DataDirectory + "/CSV/" : Settings.CustomPath;
33 IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
34 if (!PlatformFile.DirectoryExists(*BasePath))
35 {
36 PlatformFile.CreateDirectoryTree(*BasePath);
37 }
38
39 FString FullPath = FPaths::Combine(*BasePath, FileNameWithoutExtension + TEXT(".csv"));
40 UE_LOG(LogTemp, Warning, TEXT("FullPath: %s"), *FullPath);
41
42 if (Settings.CreateUnique)
43 {
44 int32 Counter = 0;
45 while (FPaths::FileExists(FullPath))
46 {
47 FullPath = FPaths::Combine(*BasePath, FileNameWithoutExtension + FString::Printf(TEXT("_%d.csv"), Counter++));
48 }
49 }
50
52 {
53 PendingRows.Reserve(Settings.QueueSize);
54 }
55
56 FilePath = FullPath;
57
58 OpenStream();
59}
60
62{
63 if (CSVStream.is_open())
64 {
65 CSVStream.close();
66 }
67
68 std::ios_base::openmode Mode = std::ios::out;
70 {
71 Mode |= std::ios::app;
72 }
73
74 CSVStream.open(TCHAR_TO_UTF8(*FilePath), Mode);
75}
76
77void UCSVFile::WriteRow(const TArray<FString>& Cells)
78{
79 if (!CSVStream.is_open()) OpenStream();
80 if (!CSVStream.is_open()) return;
81
82 // Determine delimiter
83 FString Delimiter = TEXT(",");
85 {
86 Delimiter = TEXT(";");
87 }
89 {
90 Delimiter = TEXT("\t");
91 }
92
93 // Join values using chosen delimiter
94 FString Line = FString::Join(Cells, *Delimiter);
95
97 {
98 WriteRaw(Line); // Write the line immediately
99 }
101 {
102 // Queue the line for later
103 PendingRows.Add(Line);
104 }
105}
106
107void UCSVFile::WriteRaw(const FString& Line)
108{
109 if (!CSVStream.is_open()) OpenStream();
110 if (!CSVStream.is_open()) return;
111
112 CSVStream << TCHAR_TO_UTF8(*Line) << std::endl;
113}
114
116{
117 if (CSVStream.is_open())
118 {
119 // If we have queued rows, write them out
121 {
122 for (const FString& Row : PendingRows)
123 {
124 WriteRaw(Row);
125 }
126 PendingRows.Empty();
127 }
128
129 CSVStream.close();
130 }
131}
132
134{
135 Close();
136 ConditionalBeginDestroy();
137}
static FString GetDataFolder()
static UCSVFile * CreateCSVFile(const FString &FileNameWithoutExtension, const FCSVFileSettings &Settings)
Definition: CSVFile.cpp:14
void WriteRaw(const FString &Line)
Definition: CSVFile.cpp:107
std::ofstream CSVStream
Definition: CSVFile.h:92
void Create(const FString &FileNameWithoutExtension, const FCSVFileSettings &Settings)
Definition: CSVFile.cpp:25
FString FilePath
Definition: CSVFile.h:88
TArray< FString > PendingRows
Definition: CSVFile.h:86
void Close()
Definition: CSVFile.cpp:115
void OpenStream()
Definition: CSVFile.cpp:61
FCSVFileSettings CurrentSettings
Definition: CSVFile.h:90
void WriteRow(const TArray< FString > &Cells)
Definition: CSVFile.cpp:77
void Destroy()
Definition: CSVFile.cpp:133
bool CreateUnique
Definition: CSVFile.h:42
ECSVDelimiter Delimiter
Definition: CSVFile.h:36
int32 QueueSize
Definition: CSVFile.h:48
FString CustomPath
Definition: CSVFile.h:51
FCSVFileWriteOptions FileWriteOption
Definition: CSVFile.h:45