OpenQM Object Primer - The 'Array' Class

This is a class that is so simple, you may wonder wny you would ever use it. Basically, the Array Class just implements a dimensioned array, but with a couple of "features" that are very useful.

The array class is a bit slower than standard dimensioned arrays, but still performs very well. This class is used primarily when the save/restore functions are needed by the applications. But why would you ever need to turn an array into a single string. Perhaps you want to save it in a single item, or transmit it over the network to another computer. Being able to encapsulate an arbitrary amount of binary data into a single string can be very useful.

'Array' Class usage example:

array = object('Array')
array->val(1) = 'Value 1'
array->val(2) = 'Value 2'
...
array->val(999) = 'Value 999'
display 'The array now has ' : array->sz : ' elements.'
str = array->str
display 'The array is now saved in a single string that is ' : len(str) : ' characters long'
...
array->str = str
display 'The array has not been restored from str and is back to ' : array->sz : 'elements.'

'Array' Class formal property/method list:

Init
obj->Init
Method Initialize the array to zero size
val
obj->val(n) = value
result = obj->val(n)
Read/Write Property to reference an array element
sz
result = obj->sz
Read only The current upper limit of the array.
str
obj->str = value
result = obj->str
Read/Write Property that converts the entire array to and from a single packed string.
copy
obj->copy(obj2)
Method Method to copy one Array object into another

'Array' Class source code:

Class Array
 
$catalog local
 
* PUBLIC PublicVariable

 

PRIVATE sz, vals(20)

These variables are used to track the array and store values.

PUBLIC SUBROUTINE Init
   sz = 0
   dim vals(20)
end

We want a routine that will erase all data.

 
PUBLIC SUBROUTINE CREATE.OBJECT
   me->Init
end
We don't really need a CREATE.OBJECT routine, but call init anyway.
GET Val(n)
   if not(n matches '1N0N') then return('')
   if n < 1 then return('')
   if n > sz then return('')
   return(vals(n))
end

This gets a value.

SET Val(n,val)
   if not(n matches '1N0N') then return
   if n < 1 then return
   if n > inmat(vals) then dim(vals(n+19))
   for i = sz + 1 to n - 1
      val(i) = ''
   next i
   vals(n) = val
   if n > sz then sz = n
end

This is code that sets a value. There is logic to make sure that unused elements are set to null in case dim does not do this for you.

GET sz
   return(sz)
end

Let callers retrieve the array size.

GET str
   s = ''
   for i = 1 to sz
      s = s : len(vals(i)) 'r%8' : vals(i)
   next i
   return(s)
end

This code will pack the list of value together as a single string. The front of each value is prepended with the value's length, right justified in 8 digits. This 'encoding' allows any linear collection of data to be quickly saved into a single string, and just as quickly be extracted back into an array.

PUT str
   me->Init
   o = 1
   for i = 1 to 999999
      ln = s[o,8]
      if ln = '' then
         sz = i - 1
         exit
      end
      if i > inmat(vals) then dim vals(i+19)
      vals(i) = s[o+8,ln]
      o = o + 8 + ln
   next i
end

This code pulls and parses a prevsiously packed list back into the array.

PUBLIC FUNCTION copy(array2)
   me->Init
   sz2 = array2->sz
   for i = 1 to sz2
      me->val(i) = array2->val(i)
   next i
end
Public method to copy all of the elements from another array.
end