/************************************************
*
* File Data Source
* Copyright (C) 2020
* John Ryland
* All rights reserved
*
************************************************/
#include "FileDataSource.hpp"
#include "ChunkedDataSource.hpp"
class ChunkedFileDataSource : public ChunkedDataSource
{
public:
ChunkedFileDataSource(FILE* aFileDescriptor)
: ChunkedDataSource()
, mFileDescriptor(aFileDescriptor)
{
}
~ChunkedFileDataSource() override
{
}
size_t GetDataSize() override
{
loff_t originalOffset = ftello64(mFileDescriptor);
fseeko64(mFileDescriptor, 0ULL, SEEK_END);
loff_t off = ftello64(mFileDescriptor);
fseeko64(mFileDescriptor, originalOffset, SEEK_SET);
return static_cast<size_t>(off);
}
ReadResult ReadChunk(std::vector<uint8_t>& aBuffer) override
{
size_t start = aBuffer.size();
aBuffer.resize(start + mChunkSize);
size_t bytesRead = fread(&aBuffer[start], 1, mChunkSize, mFileDescriptor);
aBuffer.resize(start + bytesRead);
// retries?
return ((bytesRead == mChunkSize) || feof(mFileDescriptor)) ? ReadResult::eSuccess : ReadResult::eError;
}
// O_DIRECT flag
// OS read/write vs stdio fread/fwrite
// network read/write vs filesystem
private:
FILE* mFileDescriptor;
size_t mChunkSize;
unsigned mRetryAttempts;
};
/*
bool GetNextLine(ReadCompleteCallback aCallback) override
{
char buf[512];
bool res = mFileDescriptor && fgets(buf, 511, mFileDescriptor);
aCallback(res, res ? removeCRLF(buf) : "");
return res;
}
*/
void FileDataSource::Open(const char* aResourceLocator, OpenedCallback aCallback)
{
std::string f;// = "../../Data/";
f += aResourceLocator;
FILE* fileDescriptor = fopen(f.c_str(), "rb");
if (fileDescriptor == nullptr)
{
//Log(LL_Error, "OBJ", "failed to open file");
aCallback(nullptr);
return;
}
ChunkedFileDataSource fileSource(fileDescriptor);
ChunkedReaderProxy file(fileSource);
aCallback(&file);
fclose(fileDescriptor);
}