/* * $Id$ */ /* * OBJFUNC * * Contains additional object oriented functions * * Copyright (C) 1999 Eddie Runia (eddie@runia.com) * Part of the Harbour Project www.harbour-project.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version, with one exception: * * The exception is that if you link the Harbour Runtime Library (HRL) * and/or the Harbour Virtual Machine (HVM) with other files to produce * an executable, this does not by itself cause the resulting executable * to be covered by the GNU General Public License. Your use of that * executable is in no way restricted on account of linking the HRL * and/or HVM code into it. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit * their web site at http://www.gnu.org/). * * Partial Copyright Antonio Linares (alinares@fivetech.com) * partial copyright regarding function : aoData */ #define MET_METHOD 0 #define MET_DATA 1 #define MET_CLASSDATA 2 #define MET_INLINE 3 #define MET_VIRTUAL 4 #define DATA_SYMBOL 1 #define DATA_VAL 2 // // := IsData( , ) // // Is the symbol present in the object as DATA ? // function IsData( oObject, cSymbol ) return IsMessage( oObject, cSymbol ) .and. IsMessage( oObject, "_" + cSymbol ) // // := IsMethod( , ) // // Is the symbol present in the object as METHOD ? // function IsMethod( oObject, cSymbol ) return IsMessage( oObject, cSymbol ) .and. !IsMessage( oObject, "_" + cSymbol ) // // aOData( , [lDataMethod] ) // // Return an array containing the names of all the data items of oObject. // // lDataMethod = .T. (default) Return all DATAs // .F. Return all METHODs // function aOData( oObject, lDataMethod ) local aInfo := aSort( oObject:ClassSel() ) local aData := {} local n := 1 local nLen := Len( aInfo ) local lFoundDM // Found DATA ? IF !(ValType(lDataMethod) == "L") lDataMethod := .T. ENDIF do while n <= nLen .and. Substr( aInfo[ n ], 1, 1 ) != "_" /* If in range and no set function found yet ( set functions begin with a */ /* leading underscore ). */ lFoundDM := !Empty( aScan( aInfo, "_" + aInfo[ n ], n + 1 ) ) /* Find position of matching set function in array with all symbols */ if lFoundDM == lDataMethod // If found -> DATA // else METHOD aAdd( aData, aInfo[ n ] ) endif n++ enddo return aData // // aData aOMethod( oObject ) // // Return an array containing the names of all the method of oObject. // function aOMethod( oObject ) return aOData( oObject, .F. ) // // aOGet( , [] ) // // Basically the same as aOData except that it returns a 2D array // containing : // // [x][1] Symbol name // [x][2] Value of DATA // // aExcept is an optional list of DATA you do not want to collect // function aOGet( oObject, aExcept ) local aDataSymbol := aoData( oObject ) local nLen := Len( aDataSymbol ) local aData := {} local cSymbol local n IF !(ValType(aExcept) == "A") aExcept := {} ENDIF for n := 1 to nLen cSymbol := aDataSymbol[ n ] if Empty( aScan( aExcept, cSymbol ) ) aAdd( aData, { cSymbol, oSend( oObject, cSymbol ) } ) endif next n return aData // // aOSet( , ) // // The reverse of aOGet. It puts an 2D array of DATA into an object. // function aOSet( oObject, aData ) aEval( aData, ; {|aItem| oSend( oObject, "_"+aItem[DATA_SYMBOL], aItem[DATA_VAL] ) } ) return oObject // // := oAddMethod( , , ) // // Add a method to an already existing class // function oAddMethod( oObj, cSymbol, nFuncPtr ) if IsMessage( oObj, cSymbol ) QOut( "OADDMETHOD: ", cSymbol, " already exists in class." ) elseif ValType( nFuncPtr ) != "N" QOut( "OADDMETHOD: Argument type error " ) elseif ValType( oObj ) != "O" QOut( "OADDMETHOD: Argument type error " ) else ClassAdd( oObj:ClassH, cSymbol, nFuncPtr, MET_METHOD ) endif return oObj // // := oAddInline( , , ) // // Add an INLINE to an already existing class // function oAddInline( oObj, cSymbol, bInline ) if IsMessage( oObj, cSymbol ) QOut( "OADDINLINE: ", cSymbol, " already exists in class." ) elseif ValType( bInline ) != "B" QOut( "OADDINLINE: Argument type error " ) elseif ValType( oObj ) != "O" QOut( "OADDINLINE: Argument type error " ) else ClassAdd( oObj:ClassH, cSymbol, bInline, MET_INLINE ) endif return oObj // // := oAddData( , ) // // Add a DATA to an already existing class // function oAddData( oObj, cSymbol ) local nSeq if IsMessage( oObj, cSymbol ) .or. IsMessage( oObj, "_" + cSymbol ) QOut( "OADDDATA: ", cSymbol, " already exists in class." ) elseif ValType( oObj ) != "O" QOut( "OADDDATA: Argument type error " ) else nSeq := __wDataInc( oObj:ClassH ) // Allocate new Seq# ClassAdd( oObj:ClassH, cSymbol, nSeq, MET_DATA ) ClassAdd( oObj:ClassH, "_" + cSymbol, nSeq, MET_DATA ) endif return oObj // // := oModMethod( , , ) // // Modify a method to an already existing class // function oModMethod( oObj, cSymbol, nFuncPtr ) if !IsMethod( oObj, cSymbol ) QOut( "OMODMETHOD: ", cSymbol, " does not exist in class." ) elseif ValType( nFuncPtr ) != "N" QOut( "OMODMETHOD: Argument type error " ) elseif ValType( oObj ) != "O" QOut( "OMODMETHOD: Argument type error " ) else ClassMod( oObj:ClassH, cSymbol, nFuncPtr ) endif return oObj // // := oModInline( , , ) // // Modify an INLINE to an already existing class // function oModInline( oObj, cSymbol, bInline ) if !IsMethod( oObj, cSymbol ) QOut( "OMODINLINE: ", cSymbol, " does not exist in class." ) elseif ValType( bInline ) != "B" QOut( "OMODINLINE: Argument type error " ) elseif ValType( oObj ) != "O" QOut( "OMODINLINE: Argument type error " ) else ClassMod( oObj:ClassH, cSymbol, bInline ) endif return oObj // // := oDelMethod( , ) // // Delete a method from an already existing class // function oDelMethod( oObj, cSymbol ) if !IsMethod( oObj, cSymbol ) QOut( "ODELMETHOD: ", cSymbol, " does not exist in class." ) elseif ValType( oObj ) != "O" QOut( "ODELMETHOD: Argument type error " ) else ClassDel( oObj:ClassH, cSymbol ) endif return oObj function oDelInline( oObj, cSymbol ) return oDelMethod( oObj, cSymbol ) // Same story // // := oDelData( , ) // // Delete a DATA from an already existing class // function oDelData( oObj, cSymbol ) local nSeq if !IsData( oObj, cSymbol ) QOut( "ODELDATA: ", cSymbol, " does not exist in class." ) elseif ValType( oObj ) != "O" QOut( "ODELDATA: Argument type error " ) else ClassDel( oObj:ClassH, cSymbol, ) ClassDel( oObj:ClassH, "_" + cSymbol ) nSeq := __wDataDec( oObj:ClassH ) // Decrease wData endif return oObj