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
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
ASKER
No, IStream an interface used by structured storage.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
I want to create an encrypted form of a file that I could use as a source file for SAX parsing.
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(IUnknow n* pUnknpwnOuter);
virtual ~CMyXMLSourceFilter() {};
private:
FILE* f;
// INondelegatingUnknown
virtual HRESULT __stdcall NondelegatingQueryInterfac e( const IID& iid, void ** ppv);
virtual void FinalRelease();
};
CMyXMLSourceFilter::CMyXML SourceFilt er(IUnknow n* pUnknpwnOuter) : CUnknown(pUnknpwnOuter)
{
}
void CMyXMLSourceFilter::open(b ool b)
{
if( b )
f = fopen("C:\\test.stg", "wb" );
else
f = fopen("C:\\test.stg", "rb" );
}
HRESULT CMyXMLSourceFilter::Create Instance(I Unknown * pUnknownOuter, CUnknown ** ppNewComponent)
{
*ppNewComponent = new CMyXMLSourceFilter(pUnknow nOuter);
return S_OK;
}
// INondelegatingUnknown
HRESULT CMyXMLSourceFilter::Nondel egatingQue ryInterfac e( const IID& iid, void ** ppv)
{
if(iid == __uuidof(ISequentialStream ))
{
return FinishQI(static_cast<ISequ entialStre am*>(this) ,ppv);
}
else
{
return CUnknown::NondelegatingQue ryInterfac e(iid,ppv) ;
}
}
void CMyXMLSourceFilter::FinalR elease()
{
fclose(f);
}
long CMyXMLSourceFilter::Read(v oid* 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_ SAXXMLRead er30);
CMyXMLSourceFilter* cc1;
CMyXMLSourceFilter::Create Instance(N ULL, (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 ;)
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(IUnknow
virtual ~CMyXMLSourceFilter() {};
private:
FILE* f;
// INondelegatingUnknown
virtual HRESULT __stdcall NondelegatingQueryInterfac
virtual void FinalRelease();
};
CMyXMLSourceFilter::CMyXML
{
}
void CMyXMLSourceFilter::open(b
{
if( b )
f = fopen("C:\\test.stg", "wb" );
else
f = fopen("C:\\test.stg", "rb" );
}
HRESULT CMyXMLSourceFilter::Create
{
*ppNewComponent = new CMyXMLSourceFilter(pUnknow
return S_OK;
}
// INondelegatingUnknown
HRESULT CMyXMLSourceFilter::Nondel
{
if(iid == __uuidof(ISequentialStream
{
return FinishQI(static_cast<ISequ
}
else
{
return CUnknown::NondelegatingQue
}
}
void CMyXMLSourceFilter::FinalR
{
fclose(f);
}
long CMyXMLSourceFilter::Read(v
{
size_t l = fread(pv, 1, cb, f);
if( pcbRead != NULL )
*pcbRead = l;
return 0;
}
long CMyXMLSourceFilter::Write(
{
size_t l = fwrite(pv, 1, cb, f);
if( pcbRead != NULL )
*pcbRead = l;
return 0;
}
//
// And the usage:
//
ISAXXMLReaderPtr pSax;
pSax.CreateInstance(CLSID_
CMyXMLSourceFilter* cc1;
CMyXMLSourceFilter::Create
cc1->open(false);
pcc.Attach(cc1,false);
_variant_t var1(pcc);
pSax->parse(var1);
pcc = NULL;
I'll award the points for effort ;)
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/