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
LVL 3
romanmAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bird__Commented:
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/
0
romanmAuthor Commented:
No, IStream an interface used by structured storage.
0
_ys_Commented:
Of course it's possible. Albeit quite a bit of work.

You need to:
- [obviously] create your component and implement IStorage.
- roll out your own IMoniker implementation (typically on your class factory)
- implement IMoniker::BindToStorage to specifically return your custom IStorage implementation

Of course, anyone using your component would then have know how to use monikers properly in order to create your component.

Implementations of IMoniker and IStorate et al. are non-trivial. What's wrong with the default implementation? You just playing around?

I presented a write up on monikers before, although you need to know the basics well to read it:
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20775283.html
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
romanmAuthor Commented:
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.
0
romanmAuthor Commented:
// 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 ;)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.