#pragma once
#include "../Include.h"
#include "TickEntry.h"
#include "SlidingWindow.h"
template <std::size_t Size>
class CSV
{
public:
CSV(const CSV&) = delete;
CSV& operator=(const CSV&) = delete;
CSV(CSV&&) = default;
CSV& operator=(CSV&&) = default;
explicit CSV(const std::string& file)
: mFile(file, std::ios::binary)
, mCurrentBufSize(0)
{
assert(mFile.is_open());
}
bool push(const TickEntry& tick, const SlidingWindowData& data)
{
if(!mFile.good()) return false;
char tsBuf[32];
char tradeIdBuf[32];
char pxBuf[32];
char meanBuf[32];
char medianBuf[32];
char lowBuf[32];
char highBuf[32];
size_t tsBufSize = Helper::parseNsTs(tick.mTsNano, tsBuf);
auto [tradeIdEnd, tradeIdEc] = std::to_chars(tradeIdBuf, tradeIdBuf + sizeof(tradeIdBuf), tick.mTradeId);
if(tradeIdEc != std::errc{}) return false;
size_t tradeIdBufSize = static_cast<size_t>(tradeIdEnd - tradeIdBuf);
size_t pxBufSize = Helper::parseFromPx(tick.mPrice, pxBuf);
size_t meanBufSize = Helper::parseFromPx(data.mMean, meanBuf);
size_t medianBufSize = Helper::parseFromPx(data.mMedian, medianBuf);
size_t lowBufSize = Helper::parseFromPx(data.mLow, lowBuf);
size_t highBufSize = Helper::parseFromPx(data.mHigh, highBuf);
size_t totalSize = tsBufSize + tradeIdBufSize + pxBufSize +
meanBufSize + medianBufSize + lowBufSize +
highBufSize;
const size_t rowSize = totalSize + 6 + 1; // separators + newline
assert(rowSize <= Size);
if(mCurrentBufSize + rowSize > Size)
flush();
char* dst = mBuf + mCurrentBufSize;
std::copy(tsBuf, tsBuf + tsBufSize, dst);
dst += tsBufSize;
*dst = ','; dst++;
std::copy(tradeIdBuf, tradeIdBuf + tradeIdBufSize, dst);
dst += tradeIdBufSize;
*dst = ','; dst++;
std::copy(pxBuf, pxBuf + pxBufSize, dst);
dst += pxBufSize;
*dst = ','; dst++;
std::copy(meanBuf, meanBuf + meanBufSize, dst);
dst += meanBufSize;
*dst = ','; dst++;
std::copy(medianBuf, medianBuf + medianBufSize, dst);
dst += medianBufSize;
*dst = ','; dst++;
std::copy(lowBuf, lowBuf + lowBufSize, dst);
dst += lowBufSize;
*dst = ','; dst++;
std::copy(highBuf, highBuf + highBufSize, dst);
dst += highBufSize;
*dst++ = '\n';
mCurrentBufSize += rowSize;
return true;
}
~CSV()
{
flush();
if(mFile.good()) mFile.close();
}
private:
void flush()
{
if(!mFile.good()) return;
mFile.write(mBuf, mCurrentBufSize);
mFile.flush();
mCurrentBufSize = 0;
}
private:
std::ofstream mFile;
size_t mCurrentBufSize;
char mBuf[Size];
};