Code: Alles auswählen
; ------------------------------------------------------------------------------------
; String-Pool
; Beliebig großer dynamischer String Pool
; ------------------------------------------------------------------------------------
#PoolSize = $4000
#ArraySize = $100
Structure _SP_Entry
Pos.i
Size.i
EndStructure
Structure _SP_Array
Entry._SP_Entry[0]
EndStructure
Structure _SP_Globals
*Info._SP_Array
*Data
Size.i
Count.i
PoolSize.i
ArraySize.i
EndStructure
Macro SP_Init()
_SPG_\PoolSize = #PoolSize
_SPG_\Data = Mem_Alloc(_SPG_\PoolSize)
_SPG_\ArraySize = #ArraySize
_SPG_\Info = Mem_Alloc(_SPG_\ArraySize*SizeOf(_SP_Entry))
_SPG_\Info\Entry[0]\Pos = 0
_SPG_\Info\Entry[0]\Size = 0
_SPG_\Size = 0
_SPG_\Count = 0
EndMacro
Global _SPG_._SP_Globals
; Startwerte setzen
SP_Init()
; Gibt den ganzen Speicher frei und stetzt alle Zähler zurück.
Procedure SP_Reset()
Mem_Free(_SPG_\Data)
Mem_Free(_SPG_\Info)
SP_Init()
EndProcedure
; Exportiert den Stringpool + Index in einen Speicher und gibt die Adresse darauf zurück
Procedure SP_Export()
Protected Info_Size = (_SPG_\Count + 1)*SizeOf(_SP_Entry)
Protected *ExportMem = Mem_Alloc(Info_Size + _SPG_\Size + 2*SizeOf(LONG))
PokeL(*ExportMem, _SPG_\Count)
CopyMemory(_SPG_\Info, *ExportMem + SizeOf(LONG), Info_Size)
PokeL(*ExportMem + SizeOf(LONG) + Info_Size, _SPG_\Size)
CopyMemory(_SPG_\Data, *ExportMem + 2*SizeOf(LONG) + Info_Size, _SPG_\Size)
ProcedureReturn *ExportMem
EndProcedure
; Importiert einen mit Sp_Export() erstellten Speicher
Procedure SP_Import(*Mem)
Protected Info_Size
Mem_Free(_SPG_\Data)
Mem_Free(_SPG_\Info)
_SPG_\Count = PeekL(*Mem)
Info_Size = (_SPG_\Count + 1)*SizeOf(_SP_Entry)
_SPG_\ArraySize = (Int(Info_Size/#ArraySize) + 1)*#ArraySize
_SPG_\Info = Mem_Alloc(_SPG_\ArraySize)
_SPG_\Size = PeekL(*Mem + SizeOf(LONG) + Info_Size)
_SPG_\PoolSize = (Int(_SPG_\Size/#PoolSize) + 1)*#PoolSize
_SPG_\Data = Mem_Alloc(_SPG_\PoolSize)
CopyMemory(*Mem + SizeOf(LONG), _SPG_\Info, Info_Size)
CopyMemory(*Mem + 2*SizeOf(LONG) + Info_Size, _SPG_\Data, _SPG_\Size)
Mem_Free(*Mem)
EndProcedure
; Holt den String: Index
Macro SP_Get(Index)
PeekS(_SPG_\Data + _SPG_\Info\Entry[Index]\Pos, _SPG_\Info\Entry[Index]\Size)
EndMacro
; Speichert einen String im Pool und gibt einen Index darauf zurück
Procedure SP_Add(String.s, Search = 0, DeepSearch = 0)
Protected *SMem = @String
Protected Slen = MemoryStringLength(*SMem)
Protected tpos, i
; Doppelte finden
If Search
For i = 1 To _SPG_\Count
If _SPG_\Info\Entry[i]\Size = Slen ; Zuerst nur Länge vergleichen
If CompareMemory(_SPG_\Data + _SPG_\Info\Entry[i]\Pos, *SMem, Slen) ; Dann ganzen String
ProcedureReturn i
EndIf
ElseIf DeepSearch And _SPG_\Info\Entry[i]\Size>Slen ; String in anderen Strings finden
tpos = FindString(PeekS(_SPG_\Data + _SPG_\Info\Entry[i]\Pos, _SPG_\Info\Entry[i]\Size), String, 1)-1
If tpos<>-1
_SPG_\Count + 1
If _SPG_\Count> = _SPG_\ArraySize
_SPG_\ArraySize + #ArraySize
_SPG_\Info = Mem_ReAlloc(_SPG_\Info, _SPG_\ArraySize*SizeOf(_SP_Entry))
EndIf
_SPG_\Info\Entry[_SPG_\Count]\Pos = _SPG_\Info\Entry[i]\Pos + tpos
_SPG_\Info\Entry[_SPG_\Count]\Size = Slen
ProcedureReturn _SPG_\Count
EndIf
EndIf
Next
EndIf
_SPG_\Count + 1
If Slen
If _SPG_\Count> = _SPG_\ArraySize ; Index vergrößern
_SPG_\ArraySize + #ArraySize
_SPG_\Info = Mem_ReAlloc(_SPG_\Info, _SPG_\ArraySize*SizeOf(_SP_Entry))
EndIf
While _SPG_\PoolSize<_SPG_\Size + Slen + SizeOf(CHARACTER) ; Pool vergrößern
_SPG_\PoolSize + #PoolSize
_SPG_\Data = Mem_ReAlloc(_SPG_\Data, _SPG_\PoolSize)
Wend
PokeS(_SPG_\Data + _SPG_\Size, String)
_SPG_\Info\Entry[_SPG_\Count]\Pos = _SPG_\Size
_SPG_\Info\Entry[_SPG_\Count]\Size = Slen
_SPG_\Size + Slen
ProcedureReturn _SPG_\Count
Else
ProcedureReturn 0
EndIf
EndProcedure