Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

memstream.cpp

Go to the documentation of this file.
00001 #include "xmltk.h"
00002 
00003 class CMemoryStream : public IMemoryStream
00004 {
00005 public:
00006    // *** IUnknownCL methods ***
00007     CL_STDMETHOD(QueryInterface) (RCLIID riid, void **ppvObj);
00008     CL_STDMETHOD_(ULONG,AddRef) ();
00009     CL_STDMETHOD_(ULONG,Release) ();
00010 
00011     // *** IStream methods ***
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     // *** IMemoryStream methods ***
00023     CL_STDMETHOD_(int, getSize) ();
00024     CL_STDMETHOD_(char*, getBuffer) ();
00025     CL_STDMETHOD(setBuffer) (void *pv, int iSize);
00026     CL_STDMETHOD_(int, getGrowSize) ();
00027     CL_STDMETHOD(setGrowSize) (int cchGrow);
00028 
00029     // *** misc public methods ***
00030     CMemoryStream() : m_cRef(1),  m_pszBuf(NULL), m_cchBuf(0),
00031         m_iCur(0), m_cchGrow(256), m_iLast(0)
00032     {
00033     }
00034 
00035     virtual ~CMemoryStream()
00036     {
00037         if (m_pszBuf)
00038             free(m_pszBuf);
00039     }
00040 
00041 private:
00042 
00043     void _SetPosition(long iPos)
00044     {
00045         m_iCur = iPos;
00046         m_iLast = max(m_iCur, m_iLast);
00047     }
00048 
00049     bool _SizeBuffer(int cchNew)
00050     {
00051         bool bRet = false;
00052 
00053         if (m_pszBuf == NULL)
00054         {
00055             m_pszBuf = (char*)malloc(cchNew * sizeof(*m_pszBuf));
00056             if (m_pszBuf)
00057             {
00058                 m_cchBuf = cchNew;
00059                 bRet = true;
00060             }
00061         }
00062         else
00063         {
00064             char *pszNew = (char*)realloc(m_pszBuf, cchNew / sizeof(*pszNew));
00065             if (pszNew)
00066             {
00067                 m_pszBuf = pszNew;
00068                 m_cchBuf = cchNew;
00069                 bRet = true;
00070             }
00071         }
00072         return bRet;
00073     }
00074 
00075     bool _GrowBuffer(int cchNew)
00076     {
00077         cchNew += m_iCur;
00078         if (cchNew >= m_cchBuf)
00079         {
00080             cchNew += m_cchGrow - (cchNew % m_cchGrow);
00081             return _SizeBuffer(cchNew);
00082         }
00083 
00084         return true;
00085     }
00086 
00087     long _Read(void *pv, long cb, bool fUpdatePosition)
00088     {
00089         cb = min(cb, m_iLast - m_iCur);
00090         memcpy(pv, &m_pszBuf[m_iCur], cb);
00091         if (fUpdatePosition)
00092             _SetPosition(m_iCur + cb);
00093         return cb;
00094     }
00095 
00096     ULONG m_cRef;
00097     char *m_pszBuf;
00098     int m_cchBuf;
00099     int m_iCur;
00100     int m_cchGrow;
00101     int m_iLast;
00102 };
00103 
00104 // *** IUnknown methods ***
00105 //
00106 bool CMemoryStream::QueryInterface(RCLIID riid, void **ppvObj)
00107 {
00108     if (IsEqualCLIID(riid, &IID_IUnknownCL) ||
00109         IsEqualCLIID(riid, &IID_IStream) ||
00110         IsEqualCLIID(riid, &IID_IMemoryStream))
00111     {
00112         *ppvObj = static_cast<IMemoryStream*>(this);
00113     }
00114     else
00115     {
00116         *ppvObj = NULL;
00117         return false;
00118     }
00119     AddRef();
00120     return true;
00121 }
00122 
00123 ULONG CMemoryStream::AddRef()
00124 {
00125     return ++m_cRef;
00126 }
00127 
00128 ULONG CMemoryStream::Release()
00129 {
00130     if (--m_cRef > 0)
00131         return m_cRef;
00132 
00133     delete this;
00134     return 0;
00135 }
00136 
00137 // *** IStream methods ***
00138 long CMemoryStream::CopyTo(IStream *pstm, long cb)
00139 {
00140     cb = min(cb, (long)(m_iLast - m_iCur));
00141     return pstm->Write((void*)&m_pszBuf[m_iCur], cb);
00142 }
00143 
00144 long CMemoryStream::Peek(void *pv, long cb)
00145 {
00146     return _Read(pv, cb, false);
00147 }
00148 
00149 long CMemoryStream::Read(void *pv, long cb)
00150 {
00151     return _Read(pv, cb, true);
00152 }
00153 
00154 int CMemoryStream::ReadChar()
00155 {
00156     if (m_iCur < m_iLast)
00157     {
00158         int iRet = m_pszBuf[m_iCur];
00159         _SetPosition(m_iCur+1);
00160         return iRet;
00161     }
00162     return EOF;
00163 }
00164 
00165 int CMemoryStream::Seek(long offset, int origin)
00166 {
00167     switch (origin)
00168     {
00169     case SEEK_SET:
00170         _SetPosition(offset);
00171         break;
00172 
00173     case SEEK_END:
00174         _SetPosition(m_iLast - offset);
00175         break;
00176 
00177     case SEEK_CUR:
00178         _SetPosition(m_iCur + offset);
00179         break;
00180     }
00181 
00182     return 0;
00183 }
00184 
00185 long CMemoryStream::SetSize(long lsize)
00186 {
00187     _SetPosition(min(m_iCur, lsize-1));
00188     return _SizeBuffer(lsize) ? lsize : 0;
00189 }
00190 
00191 long CMemoryStream::Tell()
00192 {
00193     return m_iCur;
00194 }
00195 
00196 long CMemoryStream::Write(void *pv, long cb)
00197 {
00198     if (_GrowBuffer(cb))
00199     {
00200         memcpy(&m_pszBuf[m_iCur], pv, cb);
00201         _SetPosition(m_iCur + cb);
00202         return cb;
00203     }
00204     return EOF;
00205 }
00206 
00207 bool CMemoryStream::WriteChar(int ch)
00208 {
00209     if (_GrowBuffer(1))
00210     {
00211         m_pszBuf[m_iCur] = ch;
00212         _SetPosition(m_iCur+1);
00213         return true;
00214     }
00215     return false;
00216 }
00217 
00218 // *** IMemoryStream methods ***
00219 int CMemoryStream::getSize()
00220 {
00221     return m_iLast;
00222 }
00223 
00224 char *CMemoryStream::getBuffer()
00225 {
00226     return m_pszBuf;
00227 }
00228 
00229 bool CMemoryStream::setBuffer(void *pv, int iSize)
00230 {
00231     m_pszBuf = (char*)pv;
00232     m_cchBuf = iSize;
00233     m_iCur = 0;
00234     m_iLast = iSize - 1;
00235     return true;
00236 }
00237 
00238 int CMemoryStream::getGrowSize()
00239 {
00240     return m_cchGrow;
00241 }
00242 
00243 bool CMemoryStream::setGrowSize(int cchGrow)
00244 {
00245     m_cchGrow = cchGrow;
00246     return true;
00247 }
00248 
00249 
00250 bool CreateMemoryStream(RCLIID riid, void **ppvObj)
00251 {
00252     bool bRet = false;
00253     CMemoryStream* pms = new CMemoryStream();
00254     if (pms)
00255     {
00256         bRet = pms->QueryInterface(riid, ppvObj);
00257         pms->Release();
00258     }
00259 
00260     return bRet;
00261 }
00262 

Generated on Sat Dec 22 16:01:50 2001 for XMILLforBinaryFormat by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001