Code: Select all
' Auto-Sized Zstring Object
'
' Structure 'ZstringObject' defining a zstring object where memory allocation for the zstring is automatically handled:
' - A private member zstring descriptor is used, containing:
' - address of the character data of the string,
' - size of allocated memory.
' - Different public member procedures are defined:
' - default constructor,
' - conversion constructor (from zstring),
' - copy constructor (from another object),
' - conversion let operator (from zstring),
' - copy let operator (from another object),
' - cast operator (to zstring),
' - string index operator (to ubyte),
' - length property,
' - size property,
' - zstrptr property,
' - destroy sub,
' - destructor.
' - [Re]Allocation of memory (sized for the new zstring plus 12.5%):
' - if the required memory size is greater than the already allocated memory size,
' - or if the required memory size is less than the already allocated memory size minus 25%.
' - Note:
' - '@ZstringObject_instance' does not point to the character data of the string,
' - but it points to the member data of 'ZstringObject' corresponding to its zstring descriptor.
Type ZstringObject Extends Zstring
Public:
Declare Constructor()
Declare Constructor(Byref z As Zstring)
Declare Constructor(Byref zo As ZstringObject)
Declare Operator Let(Byref z As Zstring)
Declare Operator Let(byref zo As ZstringObject)
Declare Operator Cast() Byref As Const Zstring
Declare Operator [](Byval n As Integer) Byref As Ubyte
Declare Property Length() As Integer
Declare Property Size() As Integer
Declare Property ZstrPtr() As Zstring Const Ptr
Declare Sub Destroy()
Declare Destructor()
Private:
Dim As Zstring Ptr pdatazstring
Dim As Integer memoryallocated
End Type
Constructor ZstringObject()
This.destroy()
End Constructor
Constructor ZstringObject(Byref z As Zstring)
This = z '' using 'Operator Let(Byref As Zstring)'
End Constructor
Constructor ZstringObject(Byref zo As ZstringObject)
This = zo '' using 'Operator Let(byref As ZstringObject)'
End Constructor
Operator ZstringObject.Let(Byref z As Zstring)
If This.pdatazstring <> @z Then '' avoid self assignment destroying the chain
Dim As Integer lm = Len(z) + 1 '' '+ 1' advised for zstring character data
If (lm > This.memoryallocated) Or (lm < This.memoryallocated - This.memoryallocated Shr 2) Then
This.destroy()
This.memoryallocated = lm + lm Shr 3
This.pdatazstring = Callocate(This.memoryallocated)
End If
*This.pdatazstring = z
End If
End Operator
Operator ZstringObject.Let (byref zo As ZstringObject)
This = *zo.pdatazstring '' using 'Operator Let(Byref As Zstring)'
End Operator
Operator ZstringObject.Cast() Byref As Const Zstring
Return *This.pdatazstring
End Operator
Operator ZstringObject.[](Byval n As Integer) Byref As Ubyte
Return This.pdatazstring[n] '' inplicit conversion from Zstring to Ubyte
End Operator
Property ZstringObject.Length() As Integer
Return Len(*This.pdatazstring)
End Property
Property ZstringObject.Size() As Integer
Return This.memoryallocated
End Property
Property ZstringObject.ZstrPtr() As Zstring Const Ptr
Return This.pdatazstring
End Property
Sub ZstringObject.Destroy()
If This.pdatazstring <> 0 then
Deallocate This.pdatazstring
This.pdatazstring = 0
End If
End Sub
Destructor ZstringObject()
This.destroy()
End Destructor
'---------------------------------------------------------------------------------------------------------
Scope
Dim zo1 As ZstringObject = ZstringObject("123") '' using 'Constructor(Byref As Zstring)'
Print zo1 '' using 'Operator Cast() Byref As Const Zstring'
Dim zo2 As ZstringObject '' using 'Constructor()'
zo2 = ZstringObject("1234567") '' using 'Constructor(Byref As Zstring)'
' + 'Operator Let(Byref As ZstringObject)'
' + 'Destructor()'
Print zo2 '' using 'Operator Cast() Byref As Const Zstring'
Dim zo3 As ZstringObject = ZstringObject(zo1) '' using 'Constructor(Byref As ZstringObject)'
Print zo3 '' using 'Operator Cast() Byref As Const Zstring'
zo2 = zo1 '' using 'Operator Let(Byref As ZstringObject)'
Print zo2 '' using 'Operator Cast() Byref As Const Zstring'
zo2 = zo3 '' using 'Operator Let(Byref As ZstringObject)'
Print zo2 '' using 'Operator Cast() Byref As Const Zstring'
zo2 = "123456789" '' using 'Operator let(Byref As Zstring)'
Print zo2 & " "; '' using 'Operator Cast() Byref As Zstring'
For I As Integer = 0 To zo2.Length - 1 '' using 'Property Length() As Integer'
Print zo2[i] & " "; '' using 'Operator [](Byval n As Integer) Byref As Ubyte'
Next I
Print
Dim zo4 As ZstringObject '' using 'Constructor()'
zo4 = zo1 + zo2 & zo3 '' using 'Operator Cast() Byref As Const Zstring' x 3
' + 'Operator ZstringObject.Let(Byref z As Zstring)'
Print zo4 '' using 'Operator Cast() Byref As Const Zstring'
zo4 = zo2 '' using 'Operator Let(Byref As ZstringObject)'
Print *zo4.ZstrPtr & " "; '' using 'Property ZstrPtr() As Zstring Const Ptr'
Print zo4.Length & " "; '' using 'Property Length() As Integer'
Print zo4.Size '' using 'Property Size() As Integer'
End Scope '' using 'Destructor()' x 4
Sleep