File: nvo_sizeof.sru
Size: 6428
Date: Mon, 11 Feb 2019 15:14:32 +0100
$PBExportHeader$nvo_sizeof.sru
$PBExportComments$Non visual user object that implements the SizeOf function present on other languages - By Rui Cruz.
forward
global type nvo_sizeof from nonvisualobject
end type
end forward

global type nvo_sizeof from nonvisualobject autoinstantiate
end type

type variables
Private:

// I found this code on the internet with a comment that it was
// written by Rui Cruz. I added BYTE, LONGLONG, and LONGPTR(12.6+).

// Supported DataType Byte Lengths
Constant Integer SIZE_BOOLEAN    = 1   // Boolean
Constant Integer SIZE_BYTE       = 1   // Byte
Constant Integer SIZE_CHAR       = 2   // Unicode 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_LONGLONG   = 8   // LongLong
Constant Integer SIZE_STRING     = 4   // Assume as string pointer
Constant Integer SIZE_ULONG      = 4   // Unsigned Long

// Supported DataTypes
boolean  BOOLEAN
byte     BYTE
char     CHAR
integer  INTEGER
uint     UINT
long     LONG
longlong LONGLONG
ulong    ULONG
string   STRING

end variables

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

public function long sizeof (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
Environment le_env

ll_Count = UpperBound(Data)

For ll_Index = 1 To ll_Count
   Choose Case ClassName(Data[ll_Index])
      Case "boolean"
         ll_Size += SizeOf(BOOLEAN)
      Case "byte"
         ll_Size += SizeOf(BYTE)
      Case "char", "character"
         ll_Size += SizeOf(CHAR)
      Case "int", "integer"
         ll_Size += SizeOf(INTEGER)
      Case "long"
         ll_Size += SizeOf(LONG)
      Case "longlong"
         ll_Size += SizeOf(LONGLONG)
      Case "longptr"
         GetEnvironment(le_env)
         If le_env.ProcessBitness = 64 Then
            ll_Size += SizeOf(LONG) * 2
         End If
         ll_Size += SizeOf(LONG)
      Case "string"
         ll_Size += SizeOf(CHAR) * SizeOf(String(Data[ll_Index]))
      Case "uint", "unsignedinteger", "unsignedint"
         ll_Size += SizeOf(UINT)
      Case "ulong", "unsignedlong"
         ll_Size += SizeOf(ULONG)
      Case Else
         MessageBox("SizeOf Error", &
            "Type is not supported, possibly variable sized or object type!", StopSign!)
         Return -1
   End Choose
Next

Return ll_Size
end function

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

public function long sizeof (byte data);Return SIZE_BYTE
end function

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

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

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

public function long sizeof (longlong data);Return SIZE_LONGLONG
end function

public function long sizeof (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

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

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

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

public function long sizeof (variabledefinition vardef[]);// Internal calculations for structure sizes
// Variable length arrays will be reported as zero
Long ll_Index, ll_Count, ll_Size, ll_Array = 0
ClassDefinition TypeInfo
VariableDefinition VarList[]
VariableCardinalityDefinition VarCarDef
ArrayBounds ArrBounds[]
Environment le_env

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 "boolean"
         ll_Size += SizeOf(BOOLEAN) * ll_Array
      Case "byte"
         ll_Size += SizeOf(BYTE) * ll_Array
      Case "char", "character"
         ll_Size += SizeOf(CHAR) * ll_Array
      Case "int", "integer"
         ll_Size += SizeOf(INTEGER) * ll_Array
      Case "long"
         ll_Size += SizeOf(LONG) * ll_Array
      Case "longlong"
         ll_Size += SizeOf(LONGLONG) * ll_Array
      Case "longptr"
         GetEnvironment(le_env)
         If le_env.ProcessBitness = 64 Then
            ll_Size += (SizeOf(LONG) * 2) * ll_Array
         Else
            ll_Size += SizeOf(LONG) * ll_Array
         End If
      Case "string"
         ll_Size += SizeOf(STRING) * ll_Array
      Case "structure"
         TypeInfo = VarDef[ll_Index].TypeInfo
         VarList = TypeInfo.VariableList
         ll_Size += SizeOf(VarList)
      Case "uint", "unsignedinteger", "unsignedint"
         ll_Size += SizeOf(UINT) * ll_Array
      Case "ulong", "unsignedlong"
         ll_Size += SizeOf(ULONG) * ll_Array
      Case Else
         MessageBox("SizeOf Error", &
            "Type is not supported, possibly variable sized or object type!", StopSign!)
         Return -1
   End Choose
Next

Return ll_Size
end function

on nvo_sizeof.create
call super::create
TriggerEvent( this, "constructor" )
end on

on nvo_sizeof.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on