Default IStream Implementation

 

This example contains a default implementation of a class that implements the IStream interface. You can use this class in your programs to read and write streams for XmlLite.

This example works with Visual Studio 2005 and later.

//implement filestream that derives from IStream  
class FileStream : public IStream  
{  
    FileStream(HANDLE hFile)   
    {  
        _refcount = 1;  
        _hFile = hFile;  
    }  
  
    ~FileStream()  
    {  
        if (_hFile != INVALID_HANDLE_VALUE)  
        {  
            ::CloseHandle(_hFile);  
        }  
    }  
  
public:  
    HRESULT static OpenFile(LPCWSTR pName, IStream ** ppStream, bool fWrite)  
    {  
        HANDLE hFile = ::CreateFileW(pName, fWrite ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,  
            NULL, fWrite ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  
  
        if (hFile == INVALID_HANDLE_VALUE)  
            return HRESULT_FROM_WIN32(GetLastError());  
  
        *ppStream = new FileStream(hFile);  
  
        if(*ppStream == NULL)  
            CloseHandle(hFile);  
  
        return S_OK;  
    }  
  
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject)  
    {   
        if (iid == __uuidof(IUnknown)  
            || iid == __uuidof(IStream)  
            || iid == __uuidof(ISequentialStream))  
        {  
            *ppvObject = static_cast<IStream*>(this);  
            AddRef();  
            return S_OK;  
        } else  
            return E_NOINTERFACE;   
    }  
  
    virtual ULONG STDMETHODCALLTYPE AddRef(void)   
    {   
        return (ULONG)InterlockedIncrement(&_refcount);   
    }  
  
    virtual ULONG STDMETHODCALLTYPE Release(void)   
    {  
        ULONG res = (ULONG) InterlockedDecrement(&_refcount);  
        if (res == 0)   
            delete this;  
        return res;  
    }  
  
    // ISequentialStream Interface  
public:  
    virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead)  
    {  
        BOOL rc = ReadFile(_hFile, pv, cb, pcbRead, NULL);  
        return (rc) ? S_OK : HRESULT_FROM_WIN32(GetLastError());  
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Write(void const* pv, ULONG cb, ULONG* pcbWritten)  
    {  
        BOOL rc = WriteFile(_hFile, pv, cb, pcbWritten, NULL);  
        return rc ? S_OK : HRESULT_FROM_WIN32(GetLastError());  
    }  
  
    // IStream Interface  
public:  
    virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)  
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*,  
        ULARGE_INTEGER*)   
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)                                        
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Revert(void)                                         
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)                
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)              
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)                                    
    {   
        return E_NOTIMPL;     
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin,  
        ULARGE_INTEGER* lpNewFilePointer)  
    {   
        DWORD dwMoveMethod;  
  
        switch(dwOrigin)  
        {  
        case STREAM_SEEK_SET:  
            dwMoveMethod = FILE_BEGIN;  
            break;  
        case STREAM_SEEK_CUR:  
            dwMoveMethod = FILE_CURRENT;  
            break;  
        case STREAM_SEEK_END:  
            dwMoveMethod = FILE_END;  
            break;  
        default:     
            return STG_E_INVALIDFUNCTION;  
            break;  
        }  
  
        if (SetFilePointerEx(_hFile, liDistanceToMove, (PLARGE_INTEGER) lpNewFilePointer,  
                             dwMoveMethod) == 0)  
            return HRESULT_FROM_WIN32(GetLastError());  
        return S_OK;  
    }  
  
    virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag)   
    {  
        if (GetFileSizeEx(_hFile, (PLARGE_INTEGER) &pStatstg->cbSize) == 0)  
            return HRESULT_FROM_WIN32(GetLastError());  
        return S_OK;  
    }  
  
private:  
    HANDLE _hFile;  
    LONG _refcount;  
};  

XmlLite Reader Programming Overview

Show: