The StringBuilder class allocates huge blocks of memory at once, then keeps writing into this memory block.
DEFINE CLASS StringBuilder AS CUSTOM
nBlockSize = 64 * 1024
nNextChar = 0
nAllocated = 0
nPointer = 0
* Allocate memory. Initial size can be specified.
PROCEDURE Init(tnInitialSize AS NUMBER)
DECLARE LONG GetProcessHeap IN Win32API
DECLARE LONG HeapAlloc IN Win32API LONG, LONG, LONG
IF VARTYPE(m.tnInitialSize) == "N"
THIS.nAllocated = m.tnInitialSize
ELSE
THIS.nAllocated = THIS.nBlockSize
ENDIF
THIS.nPointer = HeapAlloc(GetProcessHeap(), 0, THIS.nAllocated)
THIS.nNextChar = THIS.nPointer
IF THIS.nPointer == 0
ERROR "Out of memory"
ENDIF
ENDPROC
* Free all resources
PROCEDURE Destroy
DECLARE LONG GetProcessHeap IN Win32API
DECLARE LONG HeapFree IN Win32API LONG, LONG, LONG
IF THIS.nPointer # 0
HeapFree(GetProcessHeap(), 0, THIS.nPointer)
ENDIF
ENDPROC
* Adds a new substring. Pass string by reference.
PROCEDURE Append(rcString)
DECLARE LONG GetProcessHeap IN Win32API
DECLARE LONG HeapReAlloc IN Win32API LONG, LONG, LONG, LONG
LOCAL lnLength, lnSize
lnLength = LEN(m.rcString)
IF THIS.nNextChar + m.lnLength > THIS.nPointer + THIS.nAllocated
lnSize = THIS.nNextChar - THIS.nPointer
THIS.nAllocated = THIS.nAllocated + THIS.nBlockSize
THIS.nPointer = HeapReAlloc(GetProcessHeap(), 0, THIS.nPointer, THIS.nAllocated)
IF THIS.nPointer == 0
ERROR "Out of memory"
ENDIF
THIS.nNextChar = THIS.nPointer + m.lnSize
ENDIF
SYS(2600, THIS.nNextCHar, m.lnLength, m.rcString
ENDPROC
* Returns the whole string
FUNCTION GetString
RETURN SYS(2600, THIS.nPointer, THIS.nNextChar - THIS.nPointer)
ENDDEFINE
To Use:
loSB = NewObject("StringBuilder", "StringBuilder.PRG")
loSB.Append("Hello ")
loSB.Append("world")
? loSB.GetString() && Prints "Hello world"
Notes:
Performance drastically depends on the nBlockSize property. In the worst case, this parameter matches the
size of the string to add. This forces StringBuilder to re-allocate memory for each call to Append. The
ideal case if if nBlockSize matches the size of the final string. Then no re-allocation is necessary. The key to
succeeding is to keep your working strings relatively small compared to the final result string, and reduce the
number of times you append to the result.
|