/*======================================================

FILE:      AEEQueryInterface.h

SERVICES:  @@@TODO: fill me in!

GENERAL DESCRIPTION:

  @@@TODO: fill me in!

PUBLIC CLASSES AND STATIC FUNCTIONS:

    @@@TODO: fill me in!

INITIALIZATION & SEQUENCING REQUIREMENTS:

	See Exported Routines

        Copyright © 2004 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
=====================================================*/
#ifndef AEEQUERYINTERFACE_H
#define AEEQUERYINTERFACE_H /* #ifndef AEEQUERYINTERFACE_H */

#include "AEEInterface.h"

//***********************************************************************************************
//
//  IQueryInterface Base Class - This class is exposed as a base
//                                   extension mechanism, this should be added
//                                   to IBase, eventually, prolly
//
//***********************************************************************************************

// ### Deprecated ### - Use INHERIT_IQueryInterface from AEEInterface.h
#define DECLARE_IQIBASE(iname) \
   DECLARE_IBASE(iname)\
   int (*QueryInterface)(iname *, AEECLSID, void **)

#define INHERIT_IQueryInterface(iname) \
   INHERIT_IBase(iname); \
   int (*QueryInterface)(iname *, AEECLSID, void **)

AEEINTERFACE_DEFINE(IQueryInterface);

#define IQI_AddRef(p)                  AEEGETPVTBL((p),IQueryInterface)->AddRef((p))
#define IQI_Release(p)                 AEEGETPVTBL((p),IQueryInterface)->Release((p))
#define IQI_QueryInterface(p,clsid,pp) AEEGETPVTBL((p),IQueryInterface)->QueryInterface((p),(clsid),(pp))

#define IQI_SELF(p,idReq,pp,idImp) (*(pp)=((((idReq)==(idImp))||((idReq)==AEECLSID_QUERYINTERFACE))?(p):0))

/*
=======================================================================
 INTERFACES DOCUMENTATION
=======================================================================

IQI Interface

Description:
   IQI (IQueryInterface) is the base level object class from which extensible
   API object classes should be derived.  It supplies a standard
   mechanism to accomplish object extensibility while maintaining
   binary compatibility

See Also:
   IWebOpts,IWebResp

=======================================================================
IQI_AddRef()
This function is inherited from IBASE_AddRef().
=======================================================================
IQI_Release()
This function is inherited from IBASE_Release().
=======================================================================
IQI_QueryInterface()

Description:
   This method asks an object for another API contract from the object in
   question.

Prototype:

   int IQI_QueryInterface(IQueryInterface *po, AEECLSID idReq, void **ppo)

Parameters:
   po: Pointer to the object
   idReq:  Requested class ID exposed by the object
   ppo: (out) Returned object.  Filled by this method

Return Value:
   SUCCESS - Interface found
   ENOMEMORY - Insufficient memory
   ECLASSNOTSUPPORT - Requested interface is unsupported

Comments:

   If the resulting *ppo is an interface pointer, then the pointer in
   *ppo is set to the new interface (with refcount accordingly
   positive), or NULL if the class ID is not supported by the object.

   If the resulting *ppo is a data structure pointer, then *ppo is set
   to the internal data represended by the classID or set to NULL if
   classID is not supported by the object.  The lifetime of *ppo is the
   same as the interface on which QueryInterface() was called.

   The macro IQI_SELF() can be used as the body of the QueryInterface()
   method in any IQI descendant that implements only one interface.

   To use the macro:

    int ISomething_QueryInterface(ISomething *me, AEECLSID idReq, void **ppo)
    {
       if (NULL != IQI_SELF(me,idReq,ppo,AEECLSID_SOMETHING)) {
          IBASE_AddRef(*ppo);
          return SUCCESS;
       } else {
          return ECLASSNOTSUPPORT;
       }
    }

Side Effects:
   None

See Also:
   None

=======================================================================
IQI_SELF()

Description:
   This is a helper macro for those implementing an object with a single interface.
===pre>
Definition:
   IQI_SELF(p,idReq,pp,idImp) (*(pp)=((((idReq)==(idImp))||((idReq)==AEECLSID_QUERYINTERFACE))?(p):0))

===/pre>
Parameters:
  p: the object

  idReq: the clsid passed to QueryInterface, the requested clsid

  pp: output interface pointer

  idImpl: the clsid of the interface (other than IQueryInterface) that
           the object implements

Evaluation Value:
   p if the object is either idReq or idImpl

Comments:
   Use it like so:

   int ISomething_QueryInterface(ISomething *me, AEECLSID idReq, void **ppo)
   {
      if (NULL != IQI_SELF(me,idReq,ppo,AEECLSID_SOMETHING)) {
         IBASE_AddRef(*ppo);
         return SUCCESS;
      } else {
         return ECLASSNOTSUPPORT;
      }
   }


Side Effects:
   ppo is set to p or NULL

See Also:
   IQI_QueryInterface()

=======================================================================

*/

#endif /* #ifndef AEEQUERYINTERFACE_H */
