00001 #include "xmltk.h"
00002
00003 class CFileStream : public IFileStream
00004 {
00005 public:
00006
00007 CL_STDMETHOD(QueryInterface) (RCLIID riid, void **ppvObj);
00008 CL_STDMETHOD_(ULONG,AddRef) ();
00009 CL_STDMETHOD_(ULONG,Release) ();
00010
00011
00012 CL_STDMETHOD_(long, CopyTo) (IStream *pstm, long cb);
00013 CL_STDMETHOD_(long, Peek) (void *pv, long cb);
00014 CL_STDMETHOD_(long, Read) (void *pv, long cb);
00015 CL_STDMETHOD_(int, ReadChar) ();
00016 CL_STDMETHOD_(int, Seek) (long offset, int origin);
00017 CL_STDMETHOD_(long, SetSize) (long lsize);
00018 CL_STDMETHOD_(long, Tell) ();
00019 CL_STDMETHOD_(long, Write) (void *pv, long cb);
00020 CL_STDMETHOD(WriteChar) (int ch);
00021
00022
00023 CL_STDMETHOD_(int, CloseFile) ();
00024 CL_STDMETHOD_(FILE*, GetFile) ();
00025 CL_STDMETHOD(SetFile) (FILE* pfile);
00026 CL_STDMETHOD_(char*, GetFileName) ();
00027 CL_STDMETHOD(OpenFile) (char *pszFile, char *pszMode);
00028
00029 CFileStream() : m_cRef(1), m_pfile(NULL), m_pszFile(NULL) {}
00030
00031 virtual ~CFileStream()
00032 {
00033 if (m_pszFile)
00034 {
00035
00036
00037
00038 if (m_pfile)
00039 fclose(m_pfile);
00040
00041 free(m_pszFile);
00042 }
00043 }
00044
00045 private:
00046
00047
00048
00049 ULONG m_cRef;
00050 FILE *m_pfile;
00051 char *m_pszFile;
00052 };
00053
00054
00055
00056 bool CFileStream::QueryInterface(RCLIID riid, void **ppvObj)
00057 {
00058 if (IsEqualCLIID(riid, &IID_IUnknownCL) ||
00059 IsEqualCLIID(riid, &IID_IStream) ||
00060 IsEqualCLIID(riid, &IID_IFileStream))
00061 {
00062 *ppvObj = static_cast<IFileStream*>(this);
00063 }
00064 else
00065 {
00066 *ppvObj = NULL;
00067 return false;
00068 }
00069 AddRef();
00070 return true;
00071 }
00072
00073 ULONG CFileStream::AddRef()
00074 {
00075 return ++m_cRef;
00076 }
00077
00078 ULONG CFileStream::Release()
00079 {
00080 if (--m_cRef > 0)
00081 return m_cRef;
00082
00083 delete this;
00084 return 0;
00085 }
00086
00087
00088
00089 long CFileStream::CopyTo(IStream *pstm, long cb)
00090 {
00091 myassert(0);
00092 return 0;
00093 }
00094
00095 long CFileStream::Peek(void *pv, long cb)
00096 {
00097 long lRet = fread(pv, cb, 1, m_pfile);
00098 funread(pv, cb, 1, m_pfile);
00099 return lRet;
00100 }
00101
00102 long CFileStream::Read(void *pv, long cb)
00103 {
00104 return fread(pv, cb, 1, m_pfile);
00105 }
00106
00107 int CFileStream::ReadChar()
00108 {
00109 return fgetc(m_pfile);
00110 }
00111
00112 int CFileStream::Seek(long offset, int origin)
00113 {
00114 return fseek(m_pfile, offset, origin);
00115 }
00116
00117 long CFileStream::SetSize(long lSize)
00118 {
00119
00120
00121
00122
00123 long lSizeCur = ftell(m_pfile);
00124 if (lSize < lSizeCur)
00125 {
00126 fseek(m_pfile, SEEK_CUR, lSizeCur - lSize);
00127 }
00128 return true;
00129 }
00130
00131 long CFileStream::Tell()
00132 {
00133 return ftell(m_pfile);
00134 }
00135
00136 long CFileStream::Write(void *pv, long cb)
00137 {
00138 return fwrite(pv, cb, 1, m_pfile);
00139 }
00140
00141 bool CFileStream::WriteChar(int ch)
00142 {
00143 return fputc(ch, m_pfile) != EOF;
00144 }
00145
00146
00147 int CFileStream::CloseFile()
00148 {
00149 int iRet = EOF;
00150 if (m_pfile)
00151 {
00152 iRet = fclose(m_pfile);
00153 m_pfile = NULL;
00154 }
00155 return iRet;
00156 }
00157
00158 FILE *CFileStream::GetFile()
00159 {
00160 return m_pfile;
00161 }
00162
00163 bool CFileStream::SetFile(FILE *pfile)
00164 {
00165 m_pfile = pfile;
00166 return true;
00167 }
00168
00169 char *CFileStream::GetFileName()
00170 {
00171 return m_pszFile;
00172 }
00173
00174 bool CFileStream::OpenFile(char *pszName, char *pszMode)
00175 {
00176 if (m_pszFile)
00177 {
00178 free(m_pszFile);
00179 if (m_pfile)
00180 fclose(m_pfile);
00181 }
00182
00183 m_pszFile = mystrdup(pszName);
00184 m_pfile = fopen(m_pszFile, pszMode);
00185
00186 return m_pfile != NULL;
00187 }
00188
00189 bool CreateFileStream(RCLIID riid, void **ppvObj)
00190 {
00191 bool bRet = false;
00192
00193 CFileStream* pfs = new CFileStream();
00194 if (pfs)
00195 {
00196 bRet = pfs->QueryInterface(riid, ppvObj);
00197 pfs->Release();
00198 }
00199
00200 return bRet;
00201 }
00202