Author Topic: FB Data Structures: Data Object  (Read 3809 times)

0 Members and 4 Guests are viewing this topic.

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
FB Data Structures: Data Object
« on: December 02, 2009 »
The Data Object

In order to make the data structures presented in these tutorials as general as possible, each of the data structures will use the data object presented here as the basic data repository. The data object can handle all of the basic data types available in FreeBasic, and is implemented as a FreeBasic object with a set of associated properties, subroutines and operators. Using a standard data object will make using the data structures presented in this wikibook able to handle any of the standard FreeBasic data types, and is useful as a standalone object in the case where a typeless data object might be used (for example, within a script language).

The complete object code is listed, followed by an in-depth examination of the code.

The Data Object Code
Filename: dataobj.bi

Code: [Select]
/'****************************************************************************
*
* Name: dataobj.bi
*
* Synopsis: Data object used in various data structures.
*
* Description: The data object is a variant data object that can hold one of
*              the standard FreeBasic data types.
*             
*
* Copyright 2009, Richard D. Clark
*
*                          The Wide Open License (WOL)
*
* Permission to use, copy, modify, distribute and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
*
*****************************************************************************'/
'Create a NULL value.
#Ifndef NULL
    #Define NULL 0
#EndIf

'Enumeration of allowable types in each data object.
Enum cdatatype
    tNull
    tByte
    tUByte
    tShort
    tUShort
    tInteger
    tUInteger
    tLong
    tUlong
    tLongint
    tUlongint
    tSingle
    tDouble
    tString
End Enum

'Data object type definition.
Type dataobj
    Private:
    _ctype As cdatatype 'Current type of data, default is null.
    Union
        _clbyte As Byte     'Depending on the value of ctype, _cl* will contain the data.
        _clubyte As UByte    'If ctype is tNull, the object will not contain any valid data.
        _clshort As Short
        _clushort As UShort
        _clinteger As Integer
        _cluinteger As UInteger
        _cllong As Long
        _clulong As ULong
        _cllongint As LongInt
        _clulongint As ULongInt
        _clsingle As Single
        _cldouble As Double
        _clstring As ZString Ptr
    End Union
    Declare Sub _ClearData ()
    Public:
    Declare Constructor ()
    Declare Destructor ()
    Declare Property DataType () As cdatatype 'Returns the object data type.
    Declare Sub ClearData ()
    Declare Operator Let (rhs As dataobj) 'Sets data using a dataobj object.
    Declare Operator Let (rhs As Byte)    'Sets object data using variable.
    Declare Operator Let (rhs As UByte)
    Declare Operator Let (rhs As Short)
    Declare Operator Let (rhs As UShort)
    Declare Operator Let (rhs As Integer)
    Declare Operator Let (rhs As UInteger)
    Declare Operator Let (rhs As Long)
    Declare Operator Let (rhs As ULong)
    Declare Operator Let (rhs As LongInt)
    Declare Operator Let (rhs As ULongInt)
    Declare Operator Let (rhs As Single)
    Declare Operator Let (rhs As Double)
    Declare Operator Let (rhs As String)
    Declare Operator Cast () As Byte     'Cast to a particular data type.
    Declare Operator Cast () As UByte
    Declare Operator Cast () As Short
    Declare Operator Cast () As UShort
    Declare Operator Cast () As Integer
    Declare Operator Cast () As UInteger
    Declare Operator Cast () As Long
    Declare Operator Cast () As ULong
    Declare Operator Cast () As LongInt
    Declare Operator Cast () As ULongInt
    Declare Operator Cast () As Single
    Declare Operator Cast () As Double
    Declare Operator Cast () As String
End Type

'Clears any data in object and sets to Null.
Sub dataobj._ClearData()

    'Based on what the type is, clear the data.
    Select Case _ctype
        Case tNull
            'Nothing to do here.
        Case tByte
            _clbyte = 0
        Case tUByte
            _clubyte = 0
        Case tShort
            _clshort = 0
        Case tUShort
            _clushort = 0
        Case tInteger
            _clinteger = 0
        Case tUInteger
            _cluinteger = 0
        Case tLong
            _cllong = 0
        Case tUlong
            _clulong = 0
        Case tLongint
            _cllongint = 0
        Case tUlongint
            _cllongint = 0
        Case tSingle
            _clsingle = 0
        Case tDouble
            _cldouble = 0
        Case tString
            'Deallocate string if present and set ptr to null.
            If _clstring <> NULL Then
                DeAllocate _clstring
                _clstring = NULL
            EndIf
    End Select
    'Set data type to Null.
    _ctype = tNull
End Sub

'Object constructor sets object to Null.
Constructor dataobj ()
    _ctype = tNull
End Constructor

'Calls _ClearData to clear contents.
Destructor dataobj ()
    _ClearData
End Destructor

'Calls _ClearData to clear contents.
Sub dataobj.ClearData ()
    _ClearData
End Sub

'Returns the object data type.
Property dataobj.DataType () As cdatatype
    Return _ctype
End Property

'Set the value of the data object using another data object.
Operator dataobj.Let (rhs As dataobj)
   
   'Clears any current data and set object to NULL.
   _ClearData
   'Based on what the passed type is, set the data.
   _ctype = rhs.DataType
   Select Case _ctype
    Case tNull
        'Nothing to do here.
    Case tByte
         _clbyte = rhs
    Case tUByte
      _clubyte = rhs
      Case tShort
         _clshort = rhs
      Case tUShort
         _clushort = rhs
      Case tInteger
         _clinteger = rhs
      Case tUInteger
         _cluinteger = rhs
      Case tLong
         _cllong = rhs
      Case tUlong
         _clulong = rhs
      Case tLongint
         _cllongint = rhs
      Case tUlongint
         _clulongint = rhs
      Case tSingle
         _clsingle = rhs
      Case tDouble
         _cldouble = rhs
    Case tString 'If a string is passed, allocate space for new string, else set to NULL.
         Dim As String s = rhs
         Dim As Integer l = Len(s)
         If l > 0 Then
            _clstring = Allocate(l + 1)
            *_clstring = s
         Else
            _clstring = NULL
         EndIf
   End Select
   
End Operator

'Sets object data using variable.
Operator dataobj.Let (rhs As Byte)
   
   'Clear any existing data.
   _ClearData
   _ctype = tByte
   _clbyte = rhs
   
End Operator

Operator dataobj.Let (rhs As UByte)
   
   'Clear any existing data.
   _ClearData
   _ctype = tUByte
   _clubyte = rhs

End Operator

Operator dataobj.Let (rhs As Short)
   
   'Clear any existing data.
   _ClearData
   _ctype = tShort
   _clshort = rhs

End Operator

Operator dataobj.Let (rhs As UShort)
   
   'Clear any existing data.
   _ClearData
   _ctype = tUShort
   _clushort = rhs

End Operator

Operator dataobj.Let (rhs As Integer)
   
   'Clear any existing data.
   _ClearData
   _ctype = tInteger
   _clinteger = rhs

End Operator

Operator dataobj.Let (rhs As UInteger)
   
   'Clear any existing data.
   _ClearData
   _ctype = tUinteger 
   _cluinteger = rhs
End Operator

Operator dataobj.Let (rhs As Long)
   
   'Clear any existing data.
   _ClearData
   _ctype = tLong
   _cllong = rhs

End Operator

Operator dataobj.Let (rhs As ULong)
   
   'Clear any existing data.
   _ClearData
   _ctype = tULong
   _clulong = rhs

End Operator

Operator dataobj.Let (rhs As LongInt)
   
   'Clear any existing data.
   _ClearData
   _ctype = tLongint
   _cllongint = rhs

End Operator

Operator dataobj.Let (rhs As ULongInt)
   
   'Clear any existing data.
   _ClearData
   _ctype = tULongint
   _clulongint = rhs

End Operator

Operator dataobj.Let (rhs As Single)
   
   'Clear any existing data.
   _ClearData
   _ctype = tSingle
   _clsingle = rhs

End Operator

Operator dataobj.Let (rhs As Double)
   
   'Clear any existing data.
   _ClearData
   _ctype = tDouble
   _cldouble = rhs
   
End Operator

Operator dataobj.Let (rhs As String)
   Dim As Integer l = Len(rhs)
   
    'Clear any existing data.
   _ClearData
    'Akllocate spaxe for string, or NULL for empty string.
   _ctype = tString
   If l > 0 Then
      _clstring = Allocate(l + 1)
      *_clstring = rhs
   Else
      _clstring = NULL
   EndIf
   
End Operator

'Cast to data type. Allows returning data into a simple variable of type.
Operator dataobj.Cast () As Byte
   If _ctype = tByte Then
      Return _clbyte
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As UByte
   If _ctype = tuByte Then
       Return _clubyte
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As Short
   If _ctype = tShort Then
       Return _clshort
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As UShort
   If _ctype = tUShort Then
       Return _clushort
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As Integer
   If _ctype = tInteger Then
       Return _clinteger
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As UInteger
   If _ctype = tUInteger Then
       Return _cluinteger
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As Long
   If _ctype = tLong Then
       Return _cllong
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As ULong
   If _ctype = tULong Then
       Return _clulong
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As LongInt
   If _ctype = tLongInt Then
       Return _cllongint
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As ULongInt
   If _ctype = tUlongInt Then
       Return _clulongint
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As Single
   If _ctype = tSingle Then
       Return _clsingle
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As Double
   If _ctype = tDouble Then
       Return _cldouble
   Else
    Return 0
   EndIf
End Operator

Operator dataobj.Cast () As String
'Return string id present or empty string if NULL.
   If _ctype = tString Then
      If _clstring <> NULL Then
         Return *_clstring
      Else
         Return ""
      EndIf
   EndIf
End Operator

Code Review

Code: [Select]
'Create a NULL value.
#Ifndef NULL
    #Define NULL 0
#EndIf

In this section of the code, the special data type *NULL* is defined. Since NULL may be defined by other sections of code, or within a library, the NULL definition is wrapped within the preprocessor IF statement to prevent conflicts. NULL represents the uninitialized state of the data object and means that the data object does not contain a valid value. Whenever a data object is created or cleared, the value of the data object becomes NULL.

Code: [Select]
'Enumeration of allowable types in each data object.
Enum cdatatype
    tNull
    tByte
    tUByte
    tShort
    tUShort
    tInteger
    tUInteger
    tLong
    tUlong
    tLongint
    tUlongint
    tSingle
    tDouble
    tString
End Enum

This enumeration is used as the data type id and is stored in the private variable _ctype. The underscore is used as a reminder that this is a private variable and can only be accessed from within the type definition. To determine the current data type, use the public property DataType, which will return one of these enumerated values.

The object definition, the code delimited by the Type-End Type keywords, is contains both Private: and Public: members. The Private: members cannot be accessed from outside the object code, and is used to maintain data integrity within the object. The Public: members comprise the object's public interface and allows a program to interact with the object. Any Private: data that is stored or retrieved from the data object must pass through the Public: interface. This ensures that the integrity of the data is maintained for the life of the object.

Private Members

Code: [Select]
    Private:
    _ctype As cdatatype 'Current type of data, default is null.
    Union
        _clbyte As Byte     'Depending on the value of ctype, _cl* will contain the data.
        _clubyte As UByte    'If ctype is tNull, the object will not contain any valid data.
        _clshort As Short
        _clushort As UShort
        _clinteger As Integer
        _cluinteger As UInteger
        _cllong As Long
        _clulong As ULong
        _cllongint As LongInt
        _clulongint As ULongInt
        _clsingle As Single
        _cldouble As Double
        _clstring As ZString Ptr
    End Union
    Declare Sub _ClearCell ()

The _ctype variable is defined as cdatatype, the enumeration defined earlier in the code. This is the data type id and is used to reference the proper _cl* variable within the Union if the value of _cltype is not tNull. If _cltype's value is tNull then the Union is not accessed as the data object does not contain any valid value.

Since the data object can only contain a single type of data, the Union allows for efficient storage space while also providing the flexibility using any of the standard data types. Within a Union, all the variables share the same space in memory. The number of bytes allocated for the Union is the number of bytes of the largest variable, which in this case would be the Double which is 8 bytes or 64 bits. So, even though there are 13 variables defined in the Union, the total memory allocated for the data is only 8 bytes.

Code: [Select]
'Clears any data in object and sets to Null.
Sub dataobj._ClearData()

    'Based on what the type is, clear the data.
    Select Case _ctype
        Case tNull
            'Nothing to do here.
        Case tByte
            _clbyte = 0
        Case tUByte
            _clubyte = 0
        Case tShort
            _clshort = 0
        Case tUShort
            _clushort = 0
        Case tInteger
            _clinteger = 0
        Case tUInteger
            _cluinteger = 0
        Case tLong
            _cllong = 0
        Case tUlong
            _clulong = 0
        Case tLongint
            _cllongint = 0
        Case tUlongint
            _cllongint = 0
        Case tSingle
            _clsingle = 0
        Case tDouble
            _cldouble = 0
        Case tString
            'Deallocate string if present and set ptr to null.
            If _clstring <> NULL Then
                DeAllocate _clstring
                _clstring = NULL
            EndIf
    End Select
    'Set data type to Null.
    _ctype = tNull
End Sub

The subroutine _ClearData clears any data within the data object and then sets the type id to tNull. The current id is examined and if it is not tNull, the proper variable is set to 0, in the case of non-string data, or if the object contains string data, the string is deallocated and the zstring pointer is set to NULL. The the object is already NULL, there is no need to reset the internal data.

The _ClearData is called in the object's Destructor and can also be called through the public interface via the ClearData subroutine.

Public Members

Code: [Select]
'Object constructor sets object to Null.
Constructor dataobj ()
    _ctype = tNull
End Constructor

'Calls _ClearData to clear contents.
Destructor dataobj ()
    _ClearData
End Destructor

The object Constructor is called when the object is created and the object Destructor is called when the object is destroyed either by going out of scope or when deleted. The Constructor sets the object to tNull since at this point since the object does not contain any valid data. The Destructor calls the private _ClearData subroutine to clear the data in the object.

There are several Let (assignment) operators defined for the data object, one for each variable type, and one for setting the data based on another data object.

Code: [Select]
'Sets object data using variable.
Operator dataobj.Let (rhs As Byte)
   
   'Clear any existing data.
   _ClearData
   _ctype = tByte
   _clbyte = rhs
   
End Operator

All of the variable-based assignment operators are codes the same, except for the passed parmeter type. Each assignment clears any data using the _ClearData subroutine, then sets the data type id and copies the actual data from the rhs variable into the appropriate _cl* varibale within the Union.

The Let operators are overloaded, which means the compiler will pick the appropriate Let based on the data type of the rhs parameter. There is one note of caution here: If a constant value is used in an assignment, the compiler will pick the closest data type to the value which usually will result in an Integer, Double or String assignment being selected. For example, if the constant value is 200, an Integer assignment will be selected even though the value could fit within a byte. The best practice is to use a standard variable in an assignment, or use one of the data suffixes when using a constant value so that the appropriate assignment operator is used.

Code: [Select]
Operator dataobj.Let (rhs As String)
   Dim As Integer l = Len(rhs)
   
    'Clear any existing data.
   _ClearData
    'Allocate space for string, or NULL for empty string.
   _ctype = tString
   If l > 0 Then
      _clstring = Allocate(l + 1)
      *_clstring = rhs
   Else
      _clstring = NULL
   EndIf
   
End Operator

The string assignment operates in the same manner as the other assignment statements, except that a string is stored as a zstring, so the string space must be allocated to hold the string data. The amount of space allocated for the string is the length of the string + 1 byte for the terminating NULL character that a zstring requires.

Since a variable-length string cannot be contained within a Union, a zstring pointer is used as the internal string data type. This does add some slight overhead to the program, but not much more than using a variable-length string, since FreeBasic uses zstrings internally to store strings.

Code: [Select]
'Set the value of the data object using another data object.
Operator dataobj.Let (rhs As dataobj)
   
   'Clears any current data and set object to NULL.
   _ClearData
   'Based on what the passed type is, set the data.
   _ctype = rhs.DataType
   Select Case _ctype
    Case tNull
        'Nothing to do here.
    Case tByte
         _clbyte = rhs
    Case tUByte
      _clubyte = rhs
      Case tShort
         _clshort = rhs
      Case tUShort
         _clushort = rhs
      Case tInteger
         _clinteger = rhs
      Case tUInteger
         _cluinteger = rhs
      Case tLong
         _cllong = rhs
      Case tUlong
         _clulong = rhs
      Case tLongint
         _cllongint = rhs
      Case tUlongint
         _clulongint = rhs
      Case tSingle
         _clsingle = rhs
      Case tDouble
         _cldouble = rhs
    Case tString 'If a string is passed, allocate space for new string, else set to NULL.
         Dim As String s = rhs
         Dim As Integer l = Len(s)
         If l > 0 Then
            _clstring = Allocate(l + 1)
            *_clstring = s
         Else
            _clstring = NULL
         EndIf
   End Select
   
End Operator

In addition to the standard variable assignments, the data object can be assigned the value of an existing data object. The code looks almost the same as the _ClearData code, except that the string is allocated and initialized rather than deallocated. If an empty string is passed to the object, the zstring pointer is set to NULL to signify an empty string.

While the Let operators act as the assignment operators, and the set of defined Cast operators return the object's data. Like the Let operators, the Cast operators are overloaded and the compiler selects the appropriate Cast based on the target variable type.

Code: [Select]
'Cast to data type. Allows returning data into a simple variable of type.
Operator dataobj.Cast () As Byte
   If _ctype = tByte Then
      Return _clbyte
   Else
    Return 0
   EndIf
End Operator

The Cast operators first check to make sure that the object is of the appropriate data type, and then returns the current value. If the object is not of the appropriate type, either 0 is returned in the case of non-string data, or an empty string is returned in the case of string data. The data type of an object can be checked using the DataType property and should be checked if there is a question as to what type of data an object contains.

Code: [Select]
Operator dataobj.Cast () As String
   If _ctype = tString Then
      If _clstring <> NULL Then
         Return *_clstring
      Else
         Return ""
      EndIf
   Else
      Return ""
   EndIf
End Operator

For string data, the zstring pointer is dereferenced, if not NULL, using the * operator and returned as a standard string if the object. If the zstring pointer is NULL or the object is not a string, then an empty string is returned.

Test Program

The following test program exercises the various members of the data object.

Filename: testdata.bas

Code: [Select]
/'****************************************************************************
*
* Name: testdata.bas
*
* Synopsis: Test program for dataobj.bi.
*
* Description: This program exercises the members of dataobj.bi file.
*               
*             
*
* Copyright 2009, Richard D. Clark
*
*                          The Wide Open License (WOL)
*
* Permission to use, copy, modify, distribute and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
*
*****************************************************************************'/

#Include Once "dataobj.bi"

'Data Values.
Dim clbyte As Byte = -127
Dim clubyte As UByte = 127   
Dim clshort As Short = -1000
Dim clushort As UShort = 1000
Dim clinteger As Integer = -200000 
Dim cluinteger As UInteger = 200000
Dim cllong As Long = -300000000 
Dim clulong As ULong = 3000000000
Dim cllongint As LongInt = -40000000000
Dim clulongint As ULongInt = 40000000000
Dim clsingle As Single = -100.2345
Dim cldouble As Double = 2345.6789
Dim clstring As String = "This is a string value"

Dim clbyte2 As Byte
Dim clubyte2 As UByte   
Dim clshort2 As Short
Dim clushort2 As UShort
Dim clinteger2 As Integer 
Dim cluinteger2 As UInteger
Dim cllong2 As Long 
Dim clulong2 As ULong
Dim cllongint2 As LongInt
Dim clulongint2 As ULongInt
Dim clsingle2 As Single
Dim cldouble2 As Double
Dim clstring2 As String



'Unitialized Data object.
Dim myDO As dataobj

'Initlaized data object.
Dim myDO1 As dataobj
myDo1 = clstring

'Current value should be NULL.
If myDO.DataType = tNull Then
Print "Data object myDO is NULL."
Else
Print "myDO is type: " & myDO.DataType & "."
EndIf

'Current type should be string.
If myDO1.DataType = tString Then
Print "Data object myDO1 is a string."
Print "myDO1 data is: " & myDO1 & "."
Else
Print "myDO1 is type: " & myDO1.DataType & "."
EndIf
Print

'Print out values of each of the data type enum values.
Print "tNull = " & tNull
Print "tByte = " & tByte
Print "tUByte = " & tUByte
Print "tShort = " & tShort
Print "tUShort = " & tUShort
Print "tInteger = " & tInteger
Print "tUInteger = " & tUInteger
Print "tLong = " & tLong
Print "tUlong = " & tUlong
Print "tLongint = " & tLongint
Print "tUlongint = " & tUlongint
Print "tSingle = " & tSingle
Print "tDouble = " & tDouble
Print "tString = " & tString
Print
'Set myDO to each of the data types.
myDO = clbyte
Print "myDO is type: " & myDO.DataType
clbyte2 = myDO
Print "myDO data is: " & clbyte2
Print

myDO = clubyte
Print "myDO is type: " & myDO.DataType
clubyte2 = myDO
Print "myDO data is: " & clubyte2
Print

myDO = clshort
Print "myDO is type: " & myDO.DataType
clshort2 = myDO
Print "myDO data is: " & clshort2
Print

myDO = clushort
Print "myDO is type: " & myDO.DataType
clushort2 = myDO
Print "myDO data is: " & clushort2
Print

myDO = clinteger
Print "myDO is type: " & myDO.DataType
clinteger2 = myDO
Print "myDO data is: " & clinteger2
Print

myDO = cluinteger
Print "myDO is type: " & myDO.DataType
cluinteger2 = myDO
Print "myDO data is: " & cluinteger2
Print

myDO = cllong
Print "myDO is type: " & myDO.DataType
cllong2 = myDO
Print "myDO data is: " & cllong2
Print

myDO = clulong
Print "myDO is type: " & myDO.DataType
clulong2 = myDO
Print "myDO data is: " & clulong2
Print

myDO = cllongint
Print "myDO is type: " & myDO.DataType
cllongint2 = myDO
Print "myDO data is: " & cllongint2
Print

myDO = clulongint
Print "myDO is type: " & myDO.DataType
clulongint2 = myDO
Print "myDO data is: " & clulongint2
Print

myDO = clsingle
Print "myDO is type: " & myDO.DataType
clsingle2 = myDO
Print "myDO data is: " & clsingle2
Print

myDO = cldouble
Print "myDO is type: " & myDO.DataType
cldouble2 = myDO
Print "myDO data is: " & cldouble2
Print

'Test the object assignment.
myDO = myDO1
Print "myDO is type: " & myDO.DataType
clstring2 = myDO
Print "myDO data is: " & clstring2
Print

'Clear the data in both objects.
myDO.ClearData
Print "myDO is type: " & myDO.DataType

myDO1.ClearData
Print "myDO1 is type: " & myDO1.DataType

Sleep

The output of the program:

Quote
Data object myDO is NULL.
Data object myDO1 is a string.
myDO1 data is: This is a string value.

tNull = 0
tByte = 1
tUByte = 2
tShort = 3
tUShort = 4
tInteger = 5
tUInteger = 6
tLong = 7
tUlong = 8
tLongint = 9
tUlongint = 10
tSingle = 11
tDouble = 12
tString = 13

myDO is type: 1
myDO data is: -127

myDO is type: 2
myDO data is: 127

myDO is type: 3
myDO data is: -1000

myDO is type: 4
myDO data is: 1000

myDO is type: 5
myDO data is: -200000

myDO is type: 6
myDO data is: 200000

myDO is type: 7
myDO data is: -300000000

myDO is type: 8
myDO data is: 3000000000

myDO is type: 9
myDO data is: -40000000000

myDO is type: 10
myDO data is: 40000000000

myDO is type: 11
myDO data is: -100.2345

myDO is type: 12
myDO data is: 2345.6789

myDO is type: 13
myDO data is: This is a string value

myDO is type: 0
myDO1 is type: 0