|
|
//
// MODULE: FILEREAD.H
//
// PURPOSE: file reading classes
//
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
//
// AUTHOR: Oleg Kalosha
//
// ORIGINAL DATE: 7-29-98
//
// NOTES:
//
// Version Date By Comments
//--------------------------------------------------------------------
// V3.0 08-04-98 OK
// V3.1 01-08-99 JM improving abstraction so CHMs can be worked into this.
//
#ifndef __FILEREAD_H_
#define __FILEREAD_H_
#include "BaseException.h"
#include "stateless.h"
#include <sstream>
#include <vector>
using namespace std;
namespace std { typedef basic_string<TCHAR> tstring; typedef basic_stringbuf<TCHAR> tstringbuf; typedef basic_istream<TCHAR> tistream; typedef basic_ostream<TCHAR> tostream; typedef basic_iostream<TCHAR> tiostream; typedef basic_istringstream<TCHAR> tistringstream; typedef basic_ostringstream<TCHAR> tostringstream; typedef basic_stringstream<TCHAR> tstringstream; };
////////////////////////////////////////////////////////////////////////////////////
// CFileReaderException
////////////////////////////////////////////////////////////////////////////////////
class CPhysicalFileReader; class CFileReader; class CFileReaderException : public CBaseException { public: enum eErr {eErrOpen, eErrClose, eErrRead, eErrAllocateToRead, eErrGetSize, eErrGetDateTime, eErrParse } m_eErr;
protected: CPhysicalFileReader* m_pFileReader;
public: // source_file is LPCSTR rather than LPCTSTR because __FILE__ is char[35]
CFileReaderException(CPhysicalFileReader* reader, eErr err, LPCSTR source_file, int line); CFileReaderException(CFileReader* reader, eErr err, LPCSTR source_file, int line); virtual ~CFileReaderException();
public: virtual void CloseFile(); void LogEvent() const; // Function used to write CFileReader exceptions to the event log.
};
////////////////////////////////////////////////////////////////////////////////////
// CAbstractFileReader
// This abstract class manages a file, which is initially read into a memory buffer, then
// copied into a stream.
// It can be renewed from stream without reading file.
// It checks file for existance.
// This class is abstract, in that it doesn't consider whether the file is in normal
// file storage or in a CHM. It must be specialized to handle those two cases. Since
// it must be specialized to one or the other, this class should never be directly instantiated.
////////////////////////////////////////////////////////////////////////////////////
class CAbstractFileReader : public CStateless { private: bool m_bIsValid; // file data is consistent - no errors arose during reading and parsing
bool m_bIsRead; // file has been read
public: enum EFileTime {eFileTimeCreated, eFileTimeModified, eFileTimeAccessed};
// static utilities
static CString GetJustPath(const CString& full_path); static CString GetJustName(const CString& full_path); static CString GetJustNameWithoutExtension(const CString& full_path); static CString GetJustExtension(const CString& full_path); static bool GetFileTime(const CString& full_path, EFileTime type, time_t& out);
public: CAbstractFileReader(); ~CAbstractFileReader();
public: virtual CString GetPathName() const =0; virtual CString GetJustPath() const =0; virtual CString GetJustName() const =0; virtual CString GetJustNameWithoutExtension() const =0; virtual CString GetJustExtension() const =0; virtual bool GetFileTime(EFileTime type, time_t& out) const =0;
public: // I (Oleg) designed these functions to be the only way to perform file access.
// That is, you cannot call (say) Open or ReadData.
// The locking is designed accordingly.
// In inherited classes there might be function to access results
// of reading and parsing - in this case user is responsible for properly
// locking the results while they are being used
// These functions are NOT intended to be virtual and overridden!
bool Exists(); bool Read(); bool IsRead() {return m_bIsRead;} bool IsValid() {return m_bIsValid;}
protected: virtual void Open()=0; virtual void ReadData(LPTSTR * ppBuf) =0; virtual void StreamData(LPTSTR * ppBuf)=0; virtual void Parse()=0; virtual bool UseDefault()=0; virtual void Close()=0; // unlike CPhysicalFileReader::Close(), this throws exception if
// it cannot close the file
};
////////////////////////////////////////////////////////////////////////////////////
// CPhysicalFileReader
// This is an abstract class. Classes that provide physical access to a file should inherit
// from this class.
// A pointer to this class can be used by CFileReader to get a physical instantiation of file
// access. The idea is that CPhysicalFileReader will have one descendant
// (CNormalFileReader) to access files in normal directories and another
// (CCHMFileReader) to access files drawn from a CHM.
// CHMs don't arise in the Online Troubleshooter, but they do in the Local Troubleshooter.
////////////////////////////////////////////////////////////////////////////////////
class CPhysicalFileReader { public: CPhysicalFileReader(); virtual ~CPhysicalFileReader();
static CPhysicalFileReader * makeReader( const CString& strFileName );
protected: friend class CFileReader; friend class CFileReaderException; //
// only CFileReader class is meant to access these functions
virtual void Open()=0; virtual void ReadData(LPTSTR * ppBuf) =0; virtual bool CloseHandle()=0; // doesn't throw exception, therefore may be used by exception class.
//
public: virtual CString GetPathName() const =0; virtual CString GetJustPath() const =0; virtual CString GetJustName() const =0; virtual CString GetJustNameWithoutExtension() const =0; virtual CString GetJustExtension() const =0; virtual bool GetFileTime(CAbstractFileReader::EFileTime type, time_t& out) const =0; virtual CString GetNameToLog() const =0; };
////////////////////////////////////////////////////////////////////////////////////
// CNormalFileReader
// This class manages a file from ordinary storage.
// Do not use this for files within a CHM
////////////////////////////////////////////////////////////////////////////////////
class CNormalFileReader : public CPhysicalFileReader { private: CString m_strPath; // full path and name
HANDLE m_hFile; // handle corresponding to m_strPath (if open)
public: CNormalFileReader(LPCTSTR path); ~CNormalFileReader();
protected: //
// only CFileReader class is meant to access these functions
virtual bool CloseHandle(); // doesn't throw exception, therefore may be used by exception class.
virtual void Open(); virtual void ReadData(LPTSTR * ppBuf); //
public: // return full file path and its components
CString GetPathName() const {return m_strPath;} CString GetJustPath() const; CString GetJustName() const; CString GetJustNameWithoutExtension() const; CString GetJustExtension() const; bool GetFileTime(CAbstractFileReader::EFileTime type, time_t& out) const; CString GetNameToLog() const; };
////////////////////////////////////////////////////////////////////////////////////
// CFileReader
// This class manages a file from ordinary storage, which is initially read into a memory buffer, then
// copied into a stream.
// It can be renewed from stream without reading file.
// It checks file for existance.
// Do not use this for files within a CHM
////////////////////////////////////////////////////////////////////////////////////
class CFileReader : public CAbstractFileReader { private: CPhysicalFileReader *m_pPhysicalFileReader; bool m_bDeletePhysicalFileReader;
public: CFileReader(CPhysicalFileReader * pPhysicalFileReader, bool bDeletePhysicalFileReader =true); ~CFileReader();
public: // This function exists only so that CFileReaderException can reinterpret a CFileReader as
// a CPhysicalFileReader
CPhysicalFileReader * GetPhysicalFileReader() {return m_pPhysicalFileReader;}
public: // return full file path and its components
CString GetPathName() const {return m_pPhysicalFileReader->GetPathName();} CString GetJustPath() const {return m_pPhysicalFileReader->GetJustPath();} CString GetJustName() const {return m_pPhysicalFileReader->GetJustName();} CString GetJustNameWithoutExtension() const {return m_pPhysicalFileReader->GetJustNameWithoutExtension();} CString GetJustExtension() const {return m_pPhysicalFileReader->GetJustExtension();} bool GetFileTime(EFileTime type, time_t& out) const {return m_pPhysicalFileReader->GetFileTime(type, out);}
public: tstring& GetContent(tstring&); // Data access in form of tstring
CString& GetContent(CString&); // Data access in form of CString
protected: virtual void Open() {m_pPhysicalFileReader->Open();} virtual void ReadData(LPTSTR * ppBuf) {m_pPhysicalFileReader->ReadData(ppBuf);} virtual void StreamData(LPTSTR * ppBuf); virtual void Parse(); // is empty for this class
virtual bool UseDefault(); // is empty for this class
virtual void Close();
protected: tistringstream m_StreamData;
};
////////////////////////////////////////////////////////////////////////////////////
// CTextFileReader
// Specialize CFileReader to a text file
////////////////////////////////////////////////////////////////////////////////////
class CTextFileReader : public CFileReader { protected: static bool IsAmongSeparators(TCHAR separatorCandidate, const vector<TCHAR>& separator_arr); CString m_strDefaultContents; // default contents to use if there is no such file.
public: // static utilities
static void GetWords(const CString& text, vector<CString>& out, const vector<TCHAR>& separators); // extract words from string
static long GetPos(tistream&); static bool SetPos(tistream&, long pos);
static bool GetLine(tistream&, CString&); static bool Find(tistream&, const CString&, bool from_stream_begin =true); static bool NextLine(tistream&); static bool PrevLine(tistream&); static void SetAtLineBegin(tistream&);
public: CTextFileReader(CPhysicalFileReader * pPhysicalFileReader, LPCTSTR szDefaultContents = NULL, bool bDeletePhysicalFileReader =true); ~CTextFileReader();
#ifdef __DEBUG_CUSTOM
public: #else
protected: #endif
long GetPos(); bool SetPos(long pos);
#ifdef __DEBUG_CUSTOM
public: #else
protected: #endif
bool GetLine(CString&); bool Find(const CString&, bool from_stream_begin =true); bool NextLine(); bool PrevLine(); void SetAtLineBegin();
protected: bool UseDefault(); // Note: not virtual. No further inheritance intended.
};
#endif __FILEREAD_H_
|