File: n_svc_sizeof.sru
Size: 5458
Date: Mon, 07 Apr 2008 21:31:26 +0200
$PBExportHeader$n_svc_sizeof.sru
$PBExportComments$Non visual user object that implements the SizeOf function present on other languages (C, Delphi, VB)
forward
global type n_svc_sizeof from n_svc_base
end type
end forward

global type n_svc_sizeof from n_svc_base
end type
global n_svc_sizeof n_svc_sizeof

type variables
Private:
// Supported DataTypes
integer  INTEGER
uint  UINT
long  LONG
ulong    ULONG
char  CHAR
string   STRING
boolean  BOOLEAN

Protected:
//size of
CONSTANT integer SIZE_BOOLEAN = 1   // Boolean
CONSTANT integer SIZE_CHAR = 1   // Char
CONSTANT integer SIZE_INT  = 2   // Signed integer
CONSTANT integer SIZE_UINT = 2   // Unsigned integer
CONSTANT integer SIZE_LONG    = 4   // Signed Long
CONSTANT integer SIZE_ULONG   = 4   // Unsigned Long
CONSTANT integer SIZE_STRING  = 4   // Assume as string pointer
end variables

forward prototypes
public function long sizeof (readonly any data[])
public function long sizeof (readonly boolean data)
public function long sizeof (readonly character data)
public function long sizeof (readonly integer data)
public function long sizeof (readonly long data)
public function long sizeof (readonly string data)
public function long sizeof (readonly unsignedinteger data)
public function long sizeof (readonly unsignedlong data)
private function long sizeof (readonly variabledefinition vardef[])
public function long sizeof (readonly powerobject data)
end prototypes

public function long sizeof (readonly any data[]);// Gives the dimension of an array
//
// Arguments: Data[] => Array to know the dimension
//
// Returns: Size of the array
//
// Notes: 
//    1) Supports mixed type arrays (and variable sized strings within the array)
//    2) DOESN'T support multi-dimension arrays;
long ll_Index, ll_Count, ll_Size = 0

ll_Count = UpperBound(Data)

For ll_Index = 1 To ll_Count

   Choose Case ClassName(Data[ll_Index])
      Case CDatatype.long
         ll_Size += SizeOf(LONG)
      Case CDatatype.unsignedlong, CDatatype.ulong
         ll_Size += SizeOf(ULONG)
      Case CDatatype.int, CDatatype.integer
         ll_Size += SizeOf(INTEGER) 
      Case CDatatype.uint, CDatatype.unsignedinteger, CDatatype.unsignedint
         ll_Size += SizeOf(UINT)
      Case CDatatype.char, CDatatype.character
         ll_Size += SizeOf(CHAR)
      Case CDatatype.string
         ll_Size += SizeOf(CHAR) * SizeOf(String(Data[ll_Index]))
      Case CDatatype.boolean
         ll_Size += SizeOf(BOOLEAN) 
   End Choose

Next

Return(ll_Size)
end function

public function long sizeof (readonly boolean data);Return(SIZE_BOOLEAN)
end function

public function long sizeof (readonly character data);Return(SIZE_CHAR)
end function

public function long sizeof (readonly integer data);Return(SIZE_INT)
end function

public function long sizeof (readonly long data);Return(SIZE_LONG)
end function

public function long sizeof (readonly string data);Return(SIZE_STRING)
end function

public function long sizeof (readonly unsignedinteger data);Return(SIZE_UINT)
end function

public function long sizeof (readonly unsignedlong data);Return(SIZE_ULONG)
end function

private function long sizeof (readonly variabledefinition vardef[]);// Internal calculations for structure sizes
long ll_Index, ll_Count, ll_Size, ll_Array = 0
ClassDefinition TypeInfo
VariableDefinition VarList[]
VariableCardinalityDefinition VarCarDef
ArrayBounds ArrBounds[]

ll_Count = Upperbound(VarDef)

For ll_Index = 2 To ll_Count
   
   VarCarDef = VarDef[ll_Index].Cardinality
   ArrBounds = VarCarDef.ArrayDefinition
   
   If Upperbound(ArrBounds) > 0 Then 
      ll_Array = ArrBounds[1].UpperBound 
   Else 
      ll_Array = 1
   End If

   Choose Case VarDef[ll_Index].TypeInfo.DataTypeOf
      Case CDatatype.long
         ll_Size += SizeOf(LONG) * ll_Array
      Case CDatatype.ulong, CDatatype.unsignedlong
         ll_Size += SizeOf(ULONG) * ll_Array
      Case CDatatype.int, CDatatype.integer
         ll_Size += SizeOf(INTEGER) * ll_Array
      Case CDatatype.uint, CDatatype.unsignedint, CDatatype.unsignedinteger
         ll_Size += SizeOf(UINT) * ll_Array
      Case CDatatype.char, CDatatype.character
         ll_Size += SizeOf(CHAR)  * ll_Array
      Case CDatatype.string
         ll_Size += SizeOf(STRING) * ll_Array
      CASE CDatatype.boolean
         ll_size += SizeOf(BOOLEAN) * ll_Array
      Case "structure"
         TypeInfo = VarDef[ll_Index].TypeInfo
         VarList = TypeInfo.VariableList
         ll_Size += SizeOf(VarList)
      Case Else
         MessageBox("SizeOf error","Type is not supported, possibly variable sized or object type!",StopSign!,Ok!)
         Return CRet.FAILURE
   End Choose
   
Next

Return(ll_Size)
end function

public function long sizeof (readonly powerobject data);// This function calculates the size of a structure
//
// The structure can contain simple datatypes (long, integer, boolean), arrays or
// other structures within it
//
// Arguments: Data   => Structure to know the size of..
//
// Returns: Size of the structure or -1 if error
//
// Notes: 
//
// 1) Cannot calculate the size of a structure with strings (variable size), for fixed
//  sized strings use a char array;
// 2) CAN calculate the size of multi-dimension arrays within the structures
ClassDefinition ClassDef
VariableDefinition VarDef[]

ClassDef = Data.ClassDefinition
VarDef   = ClassDef.VariableList

Return(SizeOf(VarDef))

end function

on n_svc_sizeof.create
call super::create
end on

on n_svc_sizeof.destroy
call super::destroy
end on