Source code of Windows XP (NT5)
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
10 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_