You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
11 KiB
306 lines
11 KiB
//
|
|
// 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_
|