Create CsvStream class to replace CsvWriter

This commit is contained in:
Jan 2021-03-11 12:43:33 +01:00
parent 9b15afa70e
commit 88b5eefe24
7 changed files with 149 additions and 100 deletions

View File

@ -0,0 +1,115 @@
#include "CsvStream.h"
#include <sstream>
constexpr char CSV_SEPARATOR = ',';
CsvInputStream::CsvInputStream(std::istream& stream)
: m_stream(stream)
{
}
bool CsvInputStream::NextRow(std::vector<std::string>& out) const
{
if (!out.empty())
out.clear();
auto c = m_stream.get();
const auto isEof = c == EOF;
std::ostringstream col;
while(c != EOF)
{
if(c == CSV_SEPARATOR)
{
out.emplace_back(col.str());
col.clear();
col.str(std::string());
}
else
{
col << c;
}
c = m_stream.get();
}
if(!isEof)
{
const auto lastEntry = col.str();
if(!lastEntry.empty())
out.emplace_back(col.str());
}
return !isEof;
}
CsvOutputStream::CsvOutputStream(std::ostream& stream)
: m_stream(stream),
m_column_count(0),
m_current_column(0),
m_first_row(true)
{
}
void CsvOutputStream::WriteColumn(const std::string& value)
{
if (m_current_column++ > 0)
m_stream << CSV_SEPARATOR;
auto containsSeparator = false;
auto containsQuote = false;
for (const auto& c : value)
{
if (c == '"')
{
containsQuote = true;
break;
}
if (c == CSV_SEPARATOR)
containsSeparator = true;
}
if (containsQuote)
{
m_stream << "\"";
for (const auto& c : value)
{
if (c == '"')
m_stream << "\"\"";
else
m_stream << c;
}
m_stream << "\"";
}
else if (containsSeparator)
{
m_stream << "\"" << value << "\"";
}
else
{
m_stream << value;
}
}
void CsvOutputStream::NextRow()
{
if (m_first_row)
{
m_first_row = false;
m_column_count = m_current_column;
}
else
{
while (m_current_column < m_column_count)
{
m_stream << CSV_SEPARATOR;
m_current_column++;
}
}
m_stream << "\n";
m_current_column = 0;
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <iostream>
#include <string>
#include <vector>
class CsvInputStream
{
std::istream& m_stream;
public:
explicit CsvInputStream(std::istream& stream);
bool NextRow(std::vector<std::string>& out) const;
};
class CsvOutputStream
{
std::ostream& m_stream;
unsigned m_column_count;
unsigned m_current_column;
bool m_first_row;
public:
explicit CsvOutputStream(std::ostream& stream);
void WriteColumn(const std::string& value);
void NextRow();
};

View File

@ -1,74 +0,0 @@
#include "CsvWriter.h"
#include <sstream>
CsvWriter::CsvWriter(std::ostream& stream)
: m_stream(stream),
m_column_count(0),
m_current_column(0),
m_first_row(true)
{
}
void CsvWriter::WriteColumn(const std::string& value)
{
if (m_current_column++ > 0)
m_stream << ",";
auto containsSeparator = false;
auto containsQuote = false;
for (const auto& c : value)
{
if (c == '"')
{
containsQuote = true;
break;
}
if (c == SEPARATOR)
containsSeparator = true;
}
if (containsQuote)
{
std::ostringstream str;
for (const auto& c : value)
{
if (c == '"')
str << "\"\"";
else
str << c;
}
m_stream << "\"" << str.str() << "\"";
}
else if (containsSeparator)
{
m_stream << "\"" << value << "\"";
}
else
{
m_stream << value;
}
}
void CsvWriter::NextRow()
{
if (m_first_row)
{
m_first_row = false;
m_column_count = m_current_column;
}
else
{
while (m_current_column < m_column_count)
{
m_stream << ",";
m_current_column++;
}
}
m_stream << "\n";
m_current_column = 0;
}

View File

@ -1,20 +0,0 @@
#pragma once
#include <string>
#include <ostream>
class CsvWriter
{
static constexpr char SEPARATOR = ',';
std::ostream& m_stream;
unsigned m_column_count;
unsigned m_current_column;
bool m_first_row;
public:
explicit CsvWriter(std::ostream& stream);
void WriteColumn(const std::string& value);
void NextRow();
};

View File

@ -1,6 +1,6 @@
#include "AssetDumperStringTable.h" #include "AssetDumperStringTable.h"
#include "Dumping/CsvWriter.h" #include "Csv/CsvStream.h"
using namespace IW4; using namespace IW4;
@ -22,7 +22,7 @@ std::string AssetDumperStringTable::GetFileNameForAsset(Zone* zone, XAssetInfo<S
void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream) void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream)
{ {
const auto* stringTable = asset->Asset(); const auto* stringTable = asset->Asset();
CsvWriter csv(stream); CsvOutputStream csv(stream);
for (auto row = 0; row < stringTable->rowCount; row++) for (auto row = 0; row < stringTable->rowCount; row++)
{ {

View File

@ -1,6 +1,6 @@
#include "AssetDumperFontIcon.h" #include "AssetDumperFontIcon.h"
#include "Dumping/CsvWriter.h" #include "Csv/CsvStream.h"
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include <sstream> #include <sstream>
@ -141,7 +141,7 @@ class AssetDumperFontIconInternal
KnownAlias("Remote_LStick") KnownAlias("Remote_LStick")
}; };
CsvWriter m_csv; CsvOutputStream m_csv;
static FontIconEntry* FindEntryByHash(FontIcon* fontIcon, const int hash) static FontIconEntry* FindEntryByHash(FontIcon* fontIcon, const int hash)
{ {

View File

@ -1,6 +1,6 @@
#include "AssetDumperStringTable.h" #include "AssetDumperStringTable.h"
#include "Dumping/CsvWriter.h" #include "Csv/CsvStream.h"
using namespace T6; using namespace T6;
@ -22,7 +22,7 @@ std::string AssetDumperStringTable::GetFileNameForAsset(Zone* zone, XAssetInfo<S
void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream) void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream)
{ {
const auto* stringTable = asset->Asset(); const auto* stringTable = asset->Asset();
CsvWriter csv(stream); CsvOutputStream csv(stream);
for(auto row = 0; row < stringTable->rowCount; row++) for(auto row = 0; row < stringTable->rowCount; row++)
{ {