Link to home
Start Free TrialLog in
Avatar of romanm
romanm

asked on

How to implement my own IStream derived object

Hi,
I want to implement a class derived from the IStream interface?
I want this to be used as the stream of an IStorage object .

Possible?

cheers
-Roman
Avatar of Bird__
Bird__

do you mean istream? (not capital IStream)

if so, then check out this site.
it's a good (and the only one i can find online) guide to how the iostream works, and how to derive a class from it
http://spec.winprog.org/streams/
Avatar of romanm

ASKER

No, IStream an interface used by structured storage.
ASKER CERTIFIED SOLUTION
Avatar of _ys_
_ys_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of romanm

ASKER

What I am trying to do is to make a source/write filter for msxml,
I want to create an encrypted form of a file that I could use as a source file for SAX parsing.
Avatar of romanm

ASKER

// I have found a simple solution to my problem:

class CMyXMLSourceFilter : public CUnknown, public ISequentialStream
{
public:
      long __stdcall Read(void* pv, unsigned long cb, unsigned long* pcbRead);
      long __stdcall Write(const void* pv, unsigned long cb, unsigned long* pcbRead);
      static HRESULT CreateInstance(IUnknown * pUnknownOuter, CUnknown ** ppNewComponent);
      
      DECLARE_IUNKNOWN      // IUnknown

      void open(bool b);
            
protected:
      CMyXMLSourceFilter(IUnknown* pUnknpwnOuter);
      virtual ~CMyXMLSourceFilter() {};
      
private:
      FILE*      f;
      
      // INondelegatingUnknown
      virtual HRESULT __stdcall  NondelegatingQueryInterface( const IID& iid, void ** ppv);
      virtual void FinalRelease();
};

CMyXMLSourceFilter::CMyXMLSourceFilter(IUnknown* pUnknpwnOuter) : CUnknown(pUnknpwnOuter)
{
}

void CMyXMLSourceFilter::open(bool b)
{
      if( b )
            f = fopen("C:\\test.stg", "wb" );
      else
            f = fopen("C:\\test.stg", "rb" );
}

HRESULT CMyXMLSourceFilter::CreateInstance(IUnknown * pUnknownOuter, CUnknown ** ppNewComponent)
{
      *ppNewComponent = new CMyXMLSourceFilter(pUnknownOuter);

      return S_OK;
}

// INondelegatingUnknown
HRESULT CMyXMLSourceFilter::NondelegatingQueryInterface( const IID& iid, void ** ppv)
{
      if(iid == __uuidof(ISequentialStream))
      {
            return FinishQI(static_cast<ISequentialStream*>(this),ppv);
      }
      else
      {
            return CUnknown::NondelegatingQueryInterface(iid,ppv);
      }
}

void CMyXMLSourceFilter::FinalRelease()
{
      fclose(f);
}

long CMyXMLSourceFilter::Read(void* pv, unsigned long cb, unsigned long* pcbRead)
{
      size_t l = fread(pv, 1, cb, f);
      if( pcbRead != NULL )
            *pcbRead = l;
      return 0;
}
long CMyXMLSourceFilter::Write(const void* pv, unsigned long cb, unsigned long* pcbRead)
{
      size_t l = fwrite(pv, 1, cb, f);
      if( pcbRead != NULL )
            *pcbRead = l;
      return 0;
}

//
// And the usage:
//

      ISAXXMLReaderPtr pSax;
      pSax.CreateInstance(CLSID_SAXXMLReader30);
      CMyXMLSourceFilter* cc1;
      CMyXMLSourceFilter::CreateInstance(NULL, (CUnknown**)&cc1);
      cc1->open(false);
      pcc.Attach(cc1,false);
      _variant_t var1(pcc);
      pSax->parse(var1);
      pcc = NULL;


I'll award the points for effort ;)