🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.multimedia
Article #284

Re: initializing interfaces

#284
From: Remy Lebeau (TeamB)
Date: Fri, 31 Dec 2004 02:11
162 lines
5333 bytes
"Jonathan Benedicto" <incorrect@no.server> wrote in message
news:41d4a5cc$1@newsgroups.borland.com...

> I have to override the function AllocateDataUnit in the
> IWMWriterSink interface to provide a pointer to a allocated
> INSSBuffer. How do I allocate a INSSBuffer interface

You need to write your own INSSBuffer-derived class.  Then you can
instantiate a new instance of that class when needed, just like you would do
for any other C++ class - via the 'new' operator.  For example:

    class TMyNSSBuffer : public INSSBuffer
    {
    private:
        ULONG fRefCount;
        BYTE* fBuffer;
        DWORD fAllocatedSize;
        DWORD fLength;
    public:
        TMyNSSBuffer(DWORD dwMaxSize);
        ~TMyNSSBuffer();

        ULONG __stdcall AddRef();
        ULONG __stdcall Release();
        HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv);

        HRESULT __stdcall GetBuffer(BYTE** ppdwBuffer);
        HRESULT __stdcall GetBufferAndLength(BYTE** ppdwBuffer, DWORD*
pdwLength);
        HRESULT __stdcall GetLength(DWORD* pdwLength);
        HRESULT __stdcall GetMaxLength(DWORD* pdwLength);
        HRESULT __stdcall SetLength(DWORD dwLength);
    };


    TMyNSSBuffer::TMyNSSBuffer(DWORD dwMaxSize)
        : fRefCount(1), fAllocatedSize(dwMaxSize), fLength(0)
    {
        fBuffer = new BYTE[dwMaxSize];
    }

    TMyNSSBuffer::~TMyNSSBuffer()
    {
        delete[] fBuffer;
    }

    ULONG __stdcall TMyNSSBuffer::AddRef()
    {
        return ++fRefCount;
    }

    ULONG __stdcall TMyNSSBuffer::Release()
    {
        if( --fRefCount == 0 )
        {
            delete this;
            return 0;
        }
        return fRefCount;
    }

    HRESULT __stdcall TMyNSSBuffer::QueryInterface(REFIID riid, LPVOID* ppv)
    {
        if( ppv == NULL )
            return E_POINTER;

        *ppv = NULL;

        if( IsEqualIID(riid, IID_IUnknown) )
            *ppv = (IUnknown*) this;
        else if( IsEqualIID(riid, IID_INSSBuffer) )
            *ppv = (INNSBuffer*) this;

        if( *ppv != NULL )
        {
            AddRef();
            return S_OK;
        }

        return E_NOINTERFACE;
    }

    HRESULT __stdcall TMyNSSBuffer::GetBuffer(BYTE** ppdwBuffer)
    {
        if( ppdwBuffer == NULL )
            return E_POINTER;
        *ppdwBuffer = fBuffer;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetBufferAndLength(BYTE** ppdwBuffer,
DWORD* pdwLength)
    {
        if( (ppdwBuffer == NULL) || (pdwLength == NULL) )
            return E_POINTER;
        *ppdwBuffer = fBuffer;
        *pdwLength = fLength;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetLength(DWORD* pdwLength)
    {
        if( pdwLength == NULL )
            return E_POINTER;
        *pdwLength = fLength;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetMaxLength(DWORD* pdwLength)
    {
        if( pdwLength == NULL )
            return E_POINTER;
        *pdwLength = fAllocatedSize;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::SetLength(DWORD dwLength)
    {
        if( dwLength > fAllocatedSize )
            return E_INVALIDARG;
        fLength = dwLength;
        return S_OK;
    }


Then your IWMWriterSink can do the following:

    class TMyWMWriterSink : public IWMWriterSink
    {
    public:
        HRESULT __stdcall AllocateDataUnit(DWORD cbDataUnit, INSSBuffer**
ppDataUnit);
        //...
    };

    HRESULT __stdcall TMyWMWriterSink::AllocateDataUnit(DWORD cbDataUnit,
INSSBuffer** ppDataUnit)
    {
        if ( *ppDataUnit == NULL )
            return E_POINTER;

        try
        {
            *ppDataUnit = new TMyNSSBuffer(cbDataUnit);
            return S_OK;
        }
        catch(...) {
            return E_FAIL;
        }
    }

> I've tried IWMWriter's AllocateSample method, but it the app just hangs.

You are deadlocking your code with an endless recursion loop.
IWMWriter::AllocateSample() calls IWMWriterSink::AllocateDataUnit()
internally.  So by having your IWMWriterSink interface call
AllocateSample(), you are calling back into IWMWriterSink over and over
endlessly.


Gambit
Technical Details
Message-ID: <41d4b51d$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news.glorb.com!feeder.enertel.nl!nntpfeed-01.ops.asmr-01.energis-idc.net!216.196.110.149.MISMATCH!border2.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <41d4a5cc$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10d0fc,cae848f2dfdb6cb2
X-Google-Attributes: gid10d0fc,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.multimedia
References: <41d4a5cc$1@newsgroups.borland.com>
Subject: Re: initializing interfaces
Date: Thu, 30 Dec 2004 18:11:55 -0800
Lines: 164
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 68.69.17.41
Message-ID: <41d4b51d$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1104459037 68.69.17.41 (30 Dec 2004 18:10:37 -0800)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news.glorb.com!feeder.enertel.nl!nntpfeed-01.ops.asmr-01.energis-idc.net!216.196.110.149.MISMATCH!border2.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail