//
//  Copyright © 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   DataCallback.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:      
//

#if !defined(AFX_DATACALLBACK_H__96E5F1BA_7F0F_44AD_865F_FB81B8DA7DCC__INCLUDED_)
#define AFX_DATACALLBACK_H__96E5F1BA_7F0F_44AD_865F_FB81B8DA7DCC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// General (typical) prototype for data callback.

typedef bool ( *PFN_DATACALLBACK ) (    const void             *pvParam,            // Optional parameter; typically a this pointer of owner class.
                                        const BYTE             *pbyData,            // Pointer to binary data.
                                        const unsigned long    &rulBytes,           // Bytes in stream.
                                        const unsigned long    &rulTimeStamp );     // Millisecond time stamp.

// Helper class to simplify callback setup.

template <class tPFNCALLBACK = PFN_DATACALLBACK>
class CDataCallback
{
protected:

    ///////////////
    // Attributes.

    const tPFNCALLBACK  m_pfnCallback;                                              // Callback function pointer.
    const void         *m_pvParam1;                                                 // Optional parameter, typically this pointer for callback class.

    ///////////////
    // Services.

    CDataCallback   (   void );                                                     // Not implemented thus private.

public:

    ///////////////
    // Services.

    CDataCallback   (   const tPFNCALLBACK      pfnCallback,
                        const void             *pvParam )

        :m_pfnCallback(   pfnCallback ),
         m_pvParam1   (  pvParam )
    {
        ASSERT( m_pfnCallback != NULL );
    }

    virtual ~CDataCallback( void )
    {
    }

    bool IsValid ( void ) const
    {
        return ( m_pfnCallback != NULL );
    }

    virtual bool operator() (   const BYTE          *pbyData,
                                const unsigned long &rulBytes,
                                const unsigned long &rulTimeStamp )
    {
        // Note: operator () is vitual so that it may be overridden in cases where 
        // callback type has different number of parameters or special handling requirements etc.

        bool bSuccess = false;

        try
        {
            if ( rulBytes == 0 )
            {
                bSuccess = true;        // Nothing to do.
            }
            else
            {
                if ( m_pfnCallback == NULL )
                {
                    ThrowMessage_m( "m_pfnCallback is NULL" );
                }

                if ( pbyData == NULL )
                {
                    ThrowMessage_m( "pbyData is NULL" );
                }

                bSuccess = ( m_pfnCallback ) ( m_pvParam1, pbyData, rulBytes, rulTimeStamp );
            }
        }
        catch ( LPCTSTR lpszMessage )
        {
            bSuccess = false;
            TRACE( _T( "CDataCallback::operator(), %s.\n" ), lpszMessage );
        }
        catch ( ... )
        {
            bSuccess = false;
            TRACE( _T( "CDataCallback::operator(), Unspecified exception caught.\n" ) );
        }

        return bSuccess;
    }
};

#endif // !defined(AFX_DATACALLBACK_H__96E5F1BA_7F0F_44AD_865F_FB81B8DA7DCC__INCLUDED_)
