Newer
Older
Import / research / framework / source / FileDataSource.cpp
/************************************************
*
*  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);        
}