#ifndef AEEWEBOPTS_H
#define AEEWEBOPTS_H
/*======================================================

FILE:  AEEWebOpts.h

SERVICES:
        IWebOpts

GENERAL DESCRIPTION:
        WebOpts stuff.  Retrieval/transaction/utility APIs for anything
           that can be addressed by a URL.

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

      Copyright © 1999-2002 QUALCOMM Incorporated 
              All Rights Reserved.
           QUALCOMM Proprietary/GTDR

=====================================================*/
#include "AEE.h"
#include "AEEError.h"


/* ======================================================================= 
   Type Declarations
   ======================================================================= */

/*
  ||
  || WebOpt
  ||
  || used to hold an id-value pair, for Get/SetOpt
  ||
*/
typedef struct WebOpt
{
   int32  nId;   /* from above defines */
   void  *pVal;  /* depends on optname */
} WebOpt;

/*
  ||
  || WebOpt nOptIds
  ||
  || WebOpt ids fall in ranges that are designed to keep the pVal data opaque 
  ||  while helping IWeb deal with copying the data if necessary.  
  ||
  || During a Web transaction the data in options passed to GetResponse 
  ||  are not copied by default, they must stay valid until the GetResponse 
  ||  callback fires.  Data passed as options to IWeb *are* copied by default,
  ||  so it needn't be kept around, unless you specifically turn off 
  ||  COPYOPTS on the IWeb.
  ||
*/
/*
  || pVals are reserved, as are ids, up to 0x0ffff
*/
#define WEBOPT_RESERVED       0
#define WEBOPT_RESERVED_LAST  0x0ffff
#define WEBOPT_END            0 /* no pVal, ignore rest, used for terminating 
                                   a vector of WebOpts */
#define WEBOPT_ANY            1 /* no pVal, matches any opt, used for 
                                   enumeration */
#define WEBOPT_REMOVED        2 /* not used */
#define WEBOPT_COPYOPTS       3 /* (boolean) if set to TRUE, causes the 
                                   IWebOpts to copy current and future WebOpt
                                   values.  Unfortunately, it is almost a 
                                   one-way street, since only an empty 
                                   IWebOpts may be changed from copy to 
                                   non-copy */

/* 
   || pVals are null-terminated strings, valid ids up to 0x01ffff
*/
#define WEBOPT_SZ             0x00010000
#define WEBOPT_SZ_LAST        0x0001ffff

/*
  || pVals are 32-bit quantities, no need to copy, valid ids up to 
  ||  0x02ffff
*/
#define WEBOPT_32BIT            0x00020000
#define WEBOPT_32BIT_LAST       0x0002ffff

/*
  || pVals are pointers to interfaces, which are AddRef'd to copy
  || valid ids up to 0x03ffff
*/
#define WEBOPT_INTERFACE      0x00030000
#define WEBOPT_INTERFACE_LAST 0x0003ffff

/*
  || Following WebOpts are pointers to interfaces, which are AddRef'd to copy
  || valid ids up to 0x03ffff
*/
/* (WEBOPT_INTERFACE+1) is already taken as WEBOPT_BODY defined AEEWeb.h */
#define WEBOPT_DEFAULTS       (WEBOPT_INTERFACE+2) /* (IWebOpt *), used for 
                                                      chaining IWebOpts */



/*
  || pVals are pointers to opaque, but copyable structures, 
  || the first two bytes give the length of the following data.
  || The length is little-endian, low byte first.
*/
#define WEBOPT_VARBUFFER      0x00040000
#define WEBOPT_VARBUFFER_LAST 0x0004ffff


/*
  || pVals are pointers to opaque ASN.1, but copyable structures 
  || The length of the object comes from the ASN.1 length of the
  || object which starts at the second byte of the data. The
  || first byte is the type (it doesn't matter what the type of
  || the object is). The length is in the standard ASN.1 length
  || format. (At present there is a 64Kb limit on the length).
  || To derive the total length of the object, take the ASN.1
  || length of the object, add one for the type and then the
  || length of the length. Note this is for DER & BER encoded
  || objects. Note that it is a good idea to check the 
  || length and be sure it is valid before adding such options,
  || especially if copy opts is set. If the length is wilde
  || a malloc of a large amount of memory may be attempted
  || and/or a copy off the end of a buffer may be attempted.
*/
#define WEBOPT_ASN1      0x00050000
#define WEBOPT_ASN1_LAST 0x0005ffff

/* 
   || pVals are null-terminated AECHAR strings, valid ids up to 0x06ffff
*/
#define WEBOPT_WSZ       0x00060000
#define WEBOPT_WSZ_LAST  0x0006ffff


/*
  || pVals are pointers to opaque, but copyable structures, 
  || the low 12 bits of the id specify length of the option, in bytes
  || valid ids up to 0x1ffff000
*/
#define WEBOPT_VARIABLE       0x10000000
#define WEBOPT_VARIABLE_LAST  0x1ffff000
#define WEBOPT_VARIABLE_INC   0x00001000



/*=====================================================================
  function declarations and inline function definitions
  ===================================================================== */

/*
  ||
  || The IWebOpts base class
  ||
  || WebOpts is intended to lend some power and flexibility to 
  ||   implementations.  IWeb and IWebResponse descend from it.
  ||
*/
/* ############ deprecated, use INHERIT_IWebOpts instead */
#define DECLARE_IWEBOPTS(iname)\
   int (*AddOpt)(iname *po, WebOpt *apwoz); \
   int (*RemoveOpt)(iname *po, int32 nOptId, int32 nIndex); \
   int (*GetOpt)(iname *po, int32 nOptId, int32 nIndex, WebOpt *pwo)

#define INHERIT_IWebOpts(iname)\
   INHERIT_IQueryInterface(iname);\
   int (*AddOpt)(iname *po, WebOpt *apwoz); \
   int (*RemoveOpt)(iname *po, int32 nOptId, int32 nIndex); \
   int (*GetOpt)(iname *po, int32 nOptId, int32 nIndex, WebOpt *pwo)


typedef struct IWebOpts IWebOpts;
AEEINTERFACE(IWebOpts) {
   INHERIT_IWebOpts(IWebOpts);
};

#define IWEBOPTS_AddRef(p)               AEEGETPVTBL((p),IWebOpts)->AddRef((p))
#define IWEBOPTS_Release(p)              AEEGETPVTBL((p),IWebOpts)->Release((p))
#define IWEBOPTS_QueryInterface(p,i,ppo) AEEGETPVTBL((p),IWebOpts)->QueryInterface((p),(i),(ppo))
#define IWEBOPTS_AddOpt(p,o)             AEEGETPVTBL((p),IWebOpts)->AddOpt((p),(o))
#define IWEBOPTS_RemoveOpt(p,i,n)        AEEGETPVTBL((p),IWebOpts)->RemoveOpt((p),(i),(n))
#define IWEBOPTS_GetOpt(p,i,n,o)         AEEGETPVTBL((p),IWebOpts)->GetOpt((p),(i),(n),(o))

#define WEBOPT_GETVARBUFFERLENGTH(pbuf)            (uint16)(((unsigned char *)(pbuf))[0] + (((unsigned char *)(pbuf))[1] << 8))
#define WEBOPT_GETVARBUFFERDATA(pbuf)              (unsigned char *)((unsigned char*)(pbuf) + sizeof(uint16))
#define WEBOPT_SETVARBUFFER(pbuf,pdata,len)        do {((unsigned char*)(pbuf))[0] = (unsigned char)((len) & 0x00ff); ((unsigned char*)(pbuf))[1] = (unsigned char)((len) >> 8); MEMCPY(((unsigned char*)(pbuf) + sizeof(uint16)),(pdata),(len));} while(0)

/*
=======================================================================
  DATA STRUCTURES DOCUMENTATION
=======================================================================

WebOpt

Description:
   Holds an id, value pair for IWebOpts

Definition:
   typedef struct WebOpt
   {
      int32        nId;   
      void        *pVal;  
   } WebOpt;

Members:
   nId: option id, chosen from on of the WEBOPT_* defines in IWeb.h

   pVal: option value, depends on nId

Comments:
   WebOpt structures are the basic communication building block for
   talking to IWeb.  The structures, when passed to AddOpt, are not 
   themselves copied, the contents are copied out

See Also:
   IWEBOPTS_AddOpt()

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

*/

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

IWebOpts Interface

Description: WebOpt (web option) management API, used to manipulate 
        IWeb/IWebResp configuration.  IWebOpts represents a 
        stack or list of options, which may be single- or multi-valued.  
        IWebOpt does not enforce semantics of single- or multi-valued
        options.  Access to the options stack is dictated by the order
        in which the options are added.

Example:
===pre>

   A list built with:
        AddOpt({OPT1, x})            ==> push {OPT1, x}
        AddOpt({OPT1, y})            ==> push {OPT1, y}
        AddOpt({OPT1, z})            ==> push {OPT1, z}
        RemoveOpt(OPT1, 0)           ==> remove 0th OPT1 (which is {OPT1, z})
        AddOpt({OPT2, b},{OPT2, a}}) ==> push {OPT2, a}, then push {OPT2, b}

   Yields answers:
        GetOpt(OPT1, 0) ==> find 0th OPT1 => {OPT1, y}
        GetOpt(OPT1, 1) ==> find 1st OPT1 => {OPT1, x}
        GetOpt(OPT1, 2) ==> find 2nd OPT1 => EFAILED
        GetOpt(OPT1, 3) ==> find 3rd OPT1 => EFAILED
        GetOpt(OPT2, 1) ==> find 1st OPT2 => {OPT2, a}

   IWebOpts is the base class of IWeb and IWebResp, which use IWebOpts 
   methods to communicate all kinds of stuff.


   IWebOpt nOptIds
   ===============

   WebOpt ids fall in ranges that are designed to keep the pVal data opaque 
     while helping IWeb deal with copying the data if necessary.  
    
   During a Web transaction the data in options passed to GetResponse 
     are not copied by default, they must stay valid until the GetResponse 
     callback fires.  Data passed as options to IWeb *are* copied by default,
     so it needn't be kept around, unless you specifically turn off 
     COPYOPTS on the IWeb.
    
   Here are the ranges and to-date defined WEBOPT id values and ranges:

    ** RESERVED range: pVals are reserved, as are ids, up to 0x0ffff, used 
                   for control of the IWebOpts, markers in internal lists

       WEBOPT_RESERVED       0 
       WEBOPT_RESERVED_LAST  0x0ffff

       WEBOPT_END - no pVal, used for terminating a vector of WebOpts

       WEBOPT_ANY - no pVal, matches any opt, used for enumeration

       WEBOPT_REMOVED - no pVal, means skip or ignore, is deleted

       WEBOPT_COPYOPTS - (boolean) if set to TRUE, causes the IWebOpts
                  to copy current and future WebOpt values.
                  Unfortunately, it is almost a one-way street, since
                  only an empty IWebOpts may be changed from copy to
                  non-copy

    ** SZ RANGE: pVals are null-terminated strings, valid ids up to 0x01ffff

        WEBOPT_SZ             0x00010000
        WEBOPT_SZ_LAST        0x0001ffff


    ** 32-bit range: pVals 32-bit quantities, no need to (actually can't) 
                        copy, valid ids up to 0x02ffff

        WEBOPT_32BIT            0x00020000
        WEBOPT_32BIT_LAST       0x0002ffff

     ** BREW Interface range: pVals are pointers to interfaces, which are 
                        AddRef'd to copy valid ids up to 0x03ffff

        WEBOPT_INTERFACE      0x00030000
        WEBOPT_INTERFACE_LAST 0x0003ffff

     ** variable size range:  pVals are pointers to opaque, but copyable 
                       structures, the low 12 bits of the id specify length 
                       of the option, in bytes. Valid ids up to 0x1ffff000,
                       spaced by 0x1000.

        WEBOPT_VARIABLE       0x10000000
        WEBOPT_VARIABLE_LAST  0x1ffff000

    ** variable buffer range: pVals are pointers to opaque, but
                 copyable structures, the first two bytes give the
                 length of the following data. The length is
                 little-endian, low byte first.  Valid ids up to 
                 0x0004ffff.

        WEBOPT_VARBUFFER      0x00040000
        WEBOPT_VARBUFFER_LAST 0x0004ffff

    ** ASN.1 range: pVals are pointers to opaque ASN.1, but copyable
                 structures. The length of the object comes from the
                 ASN.1 length of the object which starts at the second
                 byte of the data. The first byte is the type (it
                 doesn't matter what the type of the object is). The
                 length is in the standard ASN.1 length format. (At
                 present there is a 64Kb limit on the length).  To
                 derive the total length of the object, take the ASN.1
                 length of the object, add one for the type and then
                 the length of the length. Note this is for DER & BER
                 encoded objects. Note that it is a good idea to check
                 the length and be sure it is valid before adding such
                 options, especially if copy opts is set. If the
                 length is wilde a malloc of a large amount of memory
                 may be attempted and/or a copy off the end of a
                 buffer may be attempted.  Valid ids up to 0x0005ffff.

        WEBOPT_ASN1      0x00050000
        WEBOPT_ASN1_LAST 0x0005ffff

    ** WSZ RANGE: pVals are null-terminated AECHAR strings, valid ids up to 
                0x06ffff

        WEBOPT_WSZ             0x00060000
        WEBOPT_WSZ_LAST        0x0006ffff

===/pre>

Header files:

   AEEWebOpts.h

See Also:
   IWeb

======================================================================= 
IWEBOPTS_AddRef()
This function is inherited from IBASE_AddRef().
======================================================================= 
IWEBOPTS_Release()
This function is inherited from IBASE_Release().
======================================================================= 
IWEBOPTS_QueryInterface()
This function is inherited from IQI_QueryInterface().
======================================================================= 

IWEBOPTS_AddOpt()

Description: 
   Adds the list of WebOpts to the current web option set.

Prototype:

    int IWEBOPTS_AddOpt(IWebOpts *pIWebOpts, WebOpt *apwoz);

Parameters:

  pIWebOpts: the interface pointer

  apwoz: array of WebOpt structs, terminated by a WebOpt with
                   nId set to WEBOPT_END

Return Value:  
   SUCCESS if the options could be added successfully
   ENOMEMORY if enough memory couldn't be allocated
    
Comments:
   None

Side Effects:
   None

Version:
   Introduced BREW Client 1.1

See Also:
   None

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

IWEBOPTS_RemoveOpt()

Description: 
   remove the nIndex'th WebOpt matching nOptId

Prototype:

   int IWEBOPTS_RemoveOpt(IWebOpts *pIWebOpts, int nOptId, int nIndex);

Parameters:

  pIWebOpts:  the interface pointer

  nOptId: id of the option to remove from the options list
  
  nIndex: which (if there are multiple WebOpts of the same id) to 
                  remove nIndex counts from most recently AddOpt()ed option

Return Value:  
   SUCCESS if the options could be added successfully
   EFAILED if the specified WebOpt couldn't be found
    
Comments:
   None

Side Effects:
   None

Version:
   Introduced BREW Client 1.1

See Also:
   None

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

IWEBOPTS_GetOpt()

Description: 
    
   Find a WebOpt in the list of WebOpts in po matching nOptId.  There
   may be multiple matches (either in the case of a multi-valued
   WebOpt, or in the case of overrides).  In this case nIndex
   specifies how far into the list of WebOpts that match nOptId to
   look.  pwo is filled in with a the matching WebOpt contents.
   nIndex is zero-based.

Prototype:

   int IWEBOPTS_GetOpt(IWebOpts *pIWebOpts, int32 nOptId, int32 nIndex, 
                       WebOpt *pwo)

Parameters:

  pIWebOpts:  the interface pointer

  nOptId:  id of the option to find in the options list, WEBOPT_ANY 
                 returns the nIndexth option, if there is one...
  
  nIndex:  which (if there are multiple WebOpts of the same id) to get
                   nIndex counts from most recently AddOpt()ed option, it is
                   zero-based

  pwo:  where to stick the found WebOpt

Return Value:  
   SUCCESS if the options could be added successfully
   EFAILED if the specified WebOpt couldn't be found
   EBADPARM if pwo is NULL
    
Comments:
   None

Side Effects:
   None

Version:
   Introduced BREW Client 1.1

See Also:
   None

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

*/

#endif /* AEEWEBOPTS_H */
