EAFileStream

Introduction

EAFileStream is an IStream which reads and writes disk files. It is your typical C++ File class. It is the C++ equivalent of the C FILE struct and associated API. We use a FileStream class instead of using C or C++ file IO primarily because our FileStream class takes advantage of system specific high performance IO, whereas the C and C++ IO functionality is slow and limited in extensibility.

Example usage

Here we provide an example of using a FileStream:

bool Application::SaveGame(const char16_t* pFilePath)
{
    bool result = false;
 
    AutoRefCount<FileStream> pStream = new FileStream(pFilePath);
 
    if(pStream->Open(kAccessFlagReadWrite, kCDOpenAlways))
    {
        result = mAI.Save(pStream);
 
        if(result)
            result = mSimulation.Save(pStream);
 
        if(result)
            result = mSceneManager.Save(pStream);
 
        // The stream will close itself when it is released.
    }
 
    return result;
}

Here's an example of using FileStream as an automatic variable as opposed to allocated by operator new:

bool Application::ReadText(const char16_t* pFilePath)
{
    bool result = false;
 
    FileStream fileStream(pFilePath);
    fileStream.AddRef();   // Causes the object to be destroyed only when it goes out of scope.
 
    if(fileStream.Open(kAccessFlagRead))
    {
        char buffer[256];
IO::size_type size;
while((size = IO::ReadLine(&fileStream, buffer, 256)) != kSizeTypeDone)
printf("%s", buffer);
result = true; } return result; }

Interface

FileStream error codes:

enum IOResultCode
{
    kFSErrorBase = 0xcfde0000,      /// Error code base for this module
    kFSErrorNotOpen,                /// Attempt to read a stream that hasn't been opened
    kFSErrorNoMemory,               /// Insufficient memory to perform operation
    kFSErrorInvalidName,            /// Invalid file name
    kFSErrorFileNotFound,           /// Attempt to open a nonexistent file for reading
    kFSErrorPathNotFound,           /// Attempt to access a file in a non-existent directory
    kFSErrorAccessDenied,           /// Insufficient privileges to open the file
    kFSErrorWriteProtect,           /// Attempt to open a read-only file for writing
    kFSErrorSharingViolation,       /// Attempt to modify a file that is in use
    kFSErrorDiskFull,               /// Out of space on the device
    kFSErrorFileAlreadyExists,      /// Attempt to create a new file with the same name as existing file
    kFSErrorDeviceNotReady,         /// Attempt to access a hardware device that isn't ready
    kFSErrorDataCRCError,           /// The data read off of the disk was corrupted in some way
    kFSErrorGeneral                 /// Catchall for all other errors
};

FileStream:

// We highlight parts of FileStream that are additions beyond IStream in blue.
 
class FileStream : public IStream
{
public:
    enum { kTypeFileStream = 0x34722300 };
 
    enum Share
    {
        kShareNone   = 0x00,     /// No sharing.
        kShareRead   = 0x01,     /// Allow sharing for reading.
        kShareWrite  = 0x02,     /// Allow sharing for writing.
        kShareDelete = 0x04      /// Allow sharing for deletion.
    };
 
    enum UsageHints
    {
        kUsageHintNone       = 0x00,
        kUsageHintSequential = 0x01,
        kUsageHintRandom     = 0x02
    };
 
public:
    FileStream(const char* pPath8 = NULL);
    FileStream(const char16_t* pPath16);
 
    // FileStream
    // Does not copy information related to an open file, such as the file handle.
    FileStream(const FileStream& fs);

    virtual ~FileStream();

    // operator=
    // Does not copy information related to an open file, such as the file handle.
    FileStream& operator=(const FileStream& fs);

    virtual int       AddRef();
    virtual int       Release();

    virtual void      SetPath(const char* pPath8);
    virtual void      SetPath(const char16_t* pPath16);
    virtual size_t    GetPath(char* pPath8, size_t nPathLength);
    virtual size_t    GetPath(char16_t* pPath16, size_t nPathLength);

    virtual bool      Open(int nAccessFlags = kAccessFlagRead, int nCreationDisposition = kCDDefault, 
                             int nSharing = kShareRead, int nUsageHints = kUsageHintNone); 
    virtual bool      Close();
    virtual uint32_t  GetType() const;
    virtual int       GetAccessFlags() const;
    virtual int       GetState() const;

    virtual size_type GetSize() const;
    virtual bool      SetSize(size_type size);

    virtual off_type  GetPosition(PositionType positionType = kPositionTypeBegin) const;
    virtual bool      SetPosition(off_type position, PositionType positionType = kPositionTypeBegin);

    virtual size_type GetAvailable() const;

    virtual size_type Read(void* pData, size_type nSize);
    virtual bool      Write(const void* pData, size_type nSize);
    virtual bool      Flush();
};