INIT

 (Available in 01 TS COM - TS_COM_InterfaceSafe)

Purpose

Safe for interface object and pointers

Syntax

oInterfaceSafe:=TS_InterfaceSafe{ [oOwner], oAIUnknown | pAIUnknown, TRUE }

Arguments

uoOwner
NIL, OBJECT
uupoAIUnknown
PTR(AIUnknown), OBJECT(AIUnknown,IUnknown)
ulAddRef
LOGIC
udwGets
NIL|DWORD

Description

The 'TS_InterfaceSafe'-class can be used to 'transport' interfaces in a secure way ( with proper refcounting, and the application dous not have to bother about memory allocation etc. ). The example below shows how the 'TS_InterfaceSafe' is used ( by the library ) to convert a pointer to a 'TS_DelegateIDispatch' ( or 'TS_DelegateIDispatchAuto') instance.

Note: The 'ulAddRef' parameter should normaly be TRUE, If the parameter is TRUE then the 'TS_InterfaceSafe' object will increment 'ref-count' on the in 'uupoAIUnknown' specified interface. The 'ref-count' on the interface is always decremented ( using 'Release()' ) when the interface safe is destroyed.

The 'udwGets' parameter can limit the number of interfaces that can be get from this safe. If this parameter is 1 then only one interface can requested from the safe. When the 'Gets' counter is counted down to zero the safe will release the enclased interface.

Note: All interfaces that are handed out by the 'TS_InterfaceSafe' object will be ref-counted ( using 'AddRef()' ) and the application must 'Release()' the interface that was received from the interface safe.

Example

oInterfaceSafe:=TS_InterfaceSafe{ oOwner, PTR( _CAST, LONG( pstruWinVariantArg.uVariant.ppDispVal  ; ...
...) ), TRUE, NIL }
IF oInterfaceSafe:FInit
   DO CASE
   CASE symClass==NULL_SYMBOL
      uRetVal:=TS_DelegateIDispatch{ oOwner, oInterfaceSafe }
   CASE TS_IsClassOfClass( symClass, #TS_DelegateIDispatch )
      uRetVal:=CreateInstance( symClass, oOwner, oInterfaceSafe )
      TSTrace SetCreatedAt uRetVal
   CASE TS_IsClassOfClass( symClass, #TS_DelegateIDispatchAuto )
      uRetVal:=CreateInstance( symClass, oOwner, oInterfaceSafe )
      TSTrace SetCreatedAt uRetVal
   OTHERWISE
      TSTrace Warning "!TS_IsClassOfClass(symClass,oOwner,#TS_DelegateIDispatch)"
      uRetVal:=TS_DelegateIDispatch{ oOwner, oInterfaceSafe }
   END
   IF !( IsObject( uRetVal ) .AND. uRetVal<>NULL_OBJECT .AND. uRetVal:IsValidObject  ; ...
  ... )
      TSTrace Warning "!(IsObject(uRetVal) .AND. uRetVal<>NULL_OBJECT .AND. uRetVal" ; ...
     ... +":IsValidObject)"
      IF IsObject( uRetVal ) .AND. uRetVal<>NULL_OBJECT
         DO CASE
         CASE IsMethod( uRetVal, #Axit )
            Send( uRetVal, #Axit )
         CASE IsMethod( uRetVal, #Destroy )
            Send( uRetVal, #Destroy )
         OTHERWISE
            TSTrace Warning "!IsMethod(uRetVal,#Axit) .AND. !IsMethod(uRetVal,#Destroy)"
         END
      END
      uRetVal:=NIL
   END
ELSE
   TSTrace Warning "!TS_InterfaceSafe{oOwner,PTR(_CAST,LONG(pstruWinVariantArg.uVariant" ; ...
  ... +".ppDispVal)),TRUE}:FInit"
   uRetVal:=NIL
END
oInterfaceSafe:Axit( )
oInterfaceSafe:=NULL_OBJECT

Source

METHOD INIT( uoOwner, uupoAIUnknown, ulAddRef, udwGets ) CLASS TS_InterfaceSafe
LOCAL cAccessTypeList AS STRING
LOCAL upoAIUnknown AS USUAL
LOCAL poAIUnknown AS TS_AbstractIUnknown PTR
LOCAL oAIUnknown AS TS_AbstractIUnknown
LOCAL lInit AS LOGIC
   TSTrace Enter CREATE
   upoAIUnknown:=UsualVal( uupoAIUnknown )
   IF LOGIC( _CAST, _AND( SELF:_ObjectStat1, TS_OBJSTAT1_ININIT  ; ...
  ... ) )
      SELF:_ObjectStat1+=TS_OBJSTAT1_COUNTVALUE
      cAccessTypeList:=TS_AccessTypeList( uoOwner, uupoAIUnknown, ulAddRef, udwGets  ; ...
     ... )
      DO CASE
      CASE cAccessTypeList=="U-LU" .OR. cAccessTypeList=="O-LU"
         lInit:=TRUE
      CASE cAccessTypeList=="UOLU" .OR. cAccessTypeList=="OOLU"
         lInit:=TRUE
      CASE cAccessTypeList=="U-LN" .OR. cAccessTypeList=="O-LN"
         lInit:=TRUE
      CASE cAccessTypeList=="UOLN" .OR. cAccessTypeList=="OOLN"
         lInit:=TRUE
      OTHERWISE
         TSTrace Warning "Invalid parameter(s), Expected 'U|O', 'O|-', 'L' and 'U|N'" ; ...
        ... +", Found '"+cAccessTypeList+"'"
         SELF:_VT:=VT_EMPTY
         SELF:InvalidateObject( )
         lInit:=FALSE
      END
      IF IsNumeric( udwGets )
         SELF:_Gets:=TS_SafeDWORD( udwGets, NULL_PTR )
      ELSE
         SELF:_Gets:=TS_DW_MAX
      END
      DO CASE
      CASE SELF:_Gets==0U
         TSTrace Warning "SELF:_Gets==0U"
         SELF:_VT:=VT_EMPTY
         SELF:InvalidateObject( )
         lInit:=FALSE
      CASE lInit
         SELF:_VT:=TS_VariantType( upoAIUnknown )
         DO CASE
         CASE SELF:_VT<>VT_DISPATCH .AND. SELF:_VT ; ...
        ... <>VT_UNKNOWN
            TSTrace Warning "SELF:_VT<>VT_DISPATCH .AND. SELF:_VT<>VT_UNKNOWN"
            SELF:_VT:=VT_EMPTY
            SELF:InvalidateObject( )
         CASE IsPtr( upoAIUnknown )
            poAIUnknown:=upoAIUnknown
            PTR( @oAIUnknown ):=poAIUnknown
            IF TS_IsValidObject( oAIUnknown, TS_ISVALID_STATIC_XIUNKNOWN )
               SUPER:INIT( uoOwner, NIL, NIL )
               IF SELF:IsInvalidated
                  TSTrace Warning "SELF:IsInvalidated"
                  SELF:_VT:=VT_EMPTY
                  SELF:InvalidateObject( )
               ELSE
                  IF ulAddRef
                     #IFDEF TS_TRACETIMED_ENABLE
                        _TS_TraceTimedEnter( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN ; ...
                       ... , #AddRef )
                     #ENDIF
                     oAIUnknown:AddRef( )
                     #IFDEF TS_TRACETIMED_ENABLE
                        _TS_TraceTimedLeave( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN ; ...
                       ... , #AddRef )
                     #ENDIF
                  END
                  SELF:_AIUnknown:=oAIUnknown
                  SELF:RegisterAxit( )
                  upoAIUnknown:=NIL
               END
            ELSE
               TSTrace Warning "!TS_IsValidObject(oAIUnknown,TS_ISVALID_STATIC_XIUNKNOWN)"
               SELF:_VT:=VT_EMPTY
               SELF:InvalidateObject( )
               upoAIUnknown:=NIL
            END
         CASE IsObject( upoAIUnknown )
            IF TS_IsValidObject( upoAIUnknown, TS_ISVALID_STATIC_XIUNKNOWN )
               SUPER:INIT( uoOwner, NIL, NIL )
               IF SELF:IsInvalidated
                  TSTrace Warning "SELF:IsInvalidated"
                  SELF:_VT:=VT_EMPTY
                  SELF:InvalidateObject( )
               ELSE
                  oAIUnknown:=upoAIUnknown
                  IF ulAddRef
                     #IFDEF TS_TRACETIMED_ENABLE
                        _TS_TraceTimedEnter( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN ; ...
                       ... , #AddRef )
                     #ENDIF
                     oAIUnknown:AddRef( )
                     #IFDEF TS_TRACETIMED_ENABLE
                        _TS_TraceTimedLeave( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN ; ...
                       ... , #AddRef )
                     #ENDIF
                  END
                  SELF:_AIUnknown:=oAIUnknown
                  SELF:RegisterAxit( )
                  upoAIUnknown:=NIL
               END
            ELSE
               TSTrace Warning "!TS_IsValidObject(upoAIUnknown,TS_ISVALID_STATIC_XIUNKNOWN)"
               SELF:_VT:=VT_EMPTY
               SELF:InvalidateObject( )
               upoAIUnknown:=NIL
            END
         OTHERWISE
            TSTrace Warning "!IsPtr(upoAIUnknown) .AND. !IsObject(upoAIUnknown)"
            SELF:_VT:=VT_EMPTY
            SELF:InvalidateObject( )
            upoAIUnknown:=NIL
         END
      END
      SELF:_ObjectStat1-=TS_OBJSTAT1_COUNTVALUE
      IF _AND( SELF:_ObjectStat1, TS_OBJSTAT1_NEWTEST )==TS_OBJSTAT1_NEEDNEW
         SELF:_ObjectStat1:=_AND( SELF:_ObjectStat1 ; ...
        ... , _NOT( TS_OBJSTAT1_NEEDNEW ) )
         IF SELF:IsValidObject
            SELF:NEW( uoOwner, uupoAIUnknown, ulAddRef ; ...
           ... , udwGets )
         ELSE
            TSTrace Warning TS_TEXT_GEN_CAN_NOT_INITIALIZE
            SELF:_VT:=VT_EMPTY
            SELF:InvalidateObject( )
         END
      END
   ELSE
      TSTrace Warning "!LOGIC(_CAST,_And(SELF:_ObjectStat1,TS_OBJECT_STATUS_ININIT))"
   END
   IF !IsNil( upoAIUnknown )
      SELF:_VT:=VT_EMPTY
      SELF:InvalidateObject( )
      DO CASE
      CASE IsPtr( upoAIUnknown )
         poAIUnknown:=upoAIUnknown
         PTR( @oAIUnknown ):=poAIUnknown
         IF TS_IsValidObject( oAIUnknown, TS_ISVALID_STATIC_XIUNKNOWN )
            #IFDEF TS_TRACETIMED_ENABLE
               _TS_TraceTimedEnter( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN, #Release  ; ...
              ... )
            #ENDIF
            oAIUnknown:Release( )
            #IFDEF TS_TRACETIMED_ENABLE
               _TS_TraceTimedLeave( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN, #Release  ; ...
              ... )
            #ENDIF
         ELSE
            TSTrace Warning "!TS_IsValidObject(oAIUnknown,TS_ISVALID_STATIC_XIUNKNOWN)"
         END
      CASE IsObject( upoAIUnknown )
         IF TS_IsValidObject( upoAIUnknown, TS_ISVALID_STATIC_XIUNKNOWN )
            oAIUnknown:=upoAIUnknown
            #IFDEF TS_TRACETIMED_ENABLE
               _TS_TraceTimedEnter( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN, #Release  ; ...
              ... )
            #ENDIF
            oAIUnknown:Release( )
            #IFDEF TS_TRACETIMED_ENABLE
               _TS_TraceTimedLeave( TS_TT_SYM_EXTERNAL, TS_TT_SYM_IUNKNOWN, #Release  ; ...
              ... )
            #ENDIF
         ELSE
            TSTrace Warning "!TS_IsValidObject(upoAIUnknown,TS_ISVALID_STATIC_XIUNKNOWN)"
         END
      OTHERWISE
         TSTrace Warning "!IsPtr(upoAIUnknown) .AND. !IsObject(upoAIUnknown)"
      END
   END
   TSTrace Leave
RETURN SELF