/' -------------------------------------------------------------------------------- This file is part of TOKGEN source distribution -------------------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -------------------------------------------------------------------------------- '/ #Ifndef __TOKGEN_DYNARRAY__ #Define __TOKGEN_DYNARRAY__ #Macro DefineDynamicArrayType(_TYPE_) #Ifndef __TOKGEN_DYNARRAY_##_TYPE_##__ #Define __TOKGEN_DYNARRAY_##_TYPE_##__ Type _TYPE_##ArrayIterator As Function(ByRef Index As UInteger, ByRef Value As _TYPE_) As Integer Type _TYPE_##Array Public: Declare Constructor Declare Destructor Declare Function Add(Value As _TYPE_) As _TYPE_ Pointer Declare Function Add As _TYPE_ Pointer Declare Sub Remove(Index As UInteger) Declare Sub ReDim(newSize As UInteger, preserveValues As Integer = 0) Declare Property Item(Index As UInteger) As _TYPE_ Declare Property Item(Index As UInteger, Value As _TYPE_) Declare Function PeekAt(Index As UInteger) As _TYPE_ Pointer Declare Property ItemCount As UInteger Declare Sub Iterate(iterator As _TYPE_##ArrayIterator, safe As Integer = Not 0) ExpandFactor As UInteger = 10 ' for how much items is array expanded when needed Private: Size As UInteger = 0 Count As UInteger = 0 mutex As Any Pointer pItem As _TYPE_ Pointer End Type '' implementation '' create mutex to use for thread safety Constructor _TYPE_##Array This.mutex = MutexCreate End Constructor '' free memory on end Destructor _TYPE_##Array DeAllocate This.pItem MutexDestroy This.mutex End Destructor '' adds value to the array Function _TYPE_##Array.Add(Value As _TYPE_) As _TYPE_ Pointer Dim ptrTemp As _TYPE_ Pointer MutexLock This.mutex If This.Size = This.Count Then ptrTemp = ReAllocate(This.pItem, (This.Size + This.ExpandFactor) * SizeOf(_TYPE_)) If ptrTemp = 0 Then MutexUnLock This.mutex Error 4 ' Out of memory Return 0 EndIf This.Size += This.ExpandFactor This.pItem = ptrTemp EndIf This.Count += 1 This.pItem[This.Count - 1] = Value Function = VarPtr(This.pItem[This.Count - 1]) MutexUnLock This.mutex End Function '' adds an "empty" value (default value for the array's type) to the array Function _TYPE_##Array.Add As _TYPE_ Pointer Dim ptrTemp As _TYPE_ Pointer MutexLock This.mutex If This.Size = This.Count Then ptrTemp = ReAllocate(This.pItem, (This.Size + This.ExpandFactor) * SizeOf(_TYPE_)) If ptrTemp = 0 Then MutexUnLock This.mutex Error 4 ' Out of memory Return 0 EndIf This.Size += This.ExpandFactor This.pItem = ptrTemp EndIf ' need to zero fill memory, cuz reallocate wont do that For i As Integer = 0 To SizeOf(_TYPE_) *(Cast(Byte Pointer, VarPtr(This.pItem[This.Count])) + i) = 0 Next This.Count += 1 Function = VarPtr(This.pItem[This.Count - 1]) MutexUnLock This.mutex End Function '' removes value from array Sub _TYPE_##Array.Remove(Index As UInteger) MutexLock This.mutex If Index >= 0 And Index < This.Count Then For i As UInteger = Index To This.Count - 2 This.pItem[i] = This.pItem[i + 1] Next This.Count -= 1 Else MutexUnLock This.mutex Error 6 ' Out of bounds array access Return EndIf MutexUnLock This.mutex End Sub '' redimensions array (with option to preserve values) Sub _TYPE_##Array.ReDim(newSize As UInteger, preserveValues As Integer = 0) Dim ptrTemp As _TYPE_ Pointer MutexLock This.mutex This.Size = newSize If preserveValues Then ptrTemp = ReAllocate(This.pItem, newSize * SizeOf(_TYPE_)) If ptrTemp = 0 Then MutexUnLock This.mutex Error 4 ' Out of memory Return EndIf If This.Size < This.Count Then This.Count = This.Size This.pItem = ptrTemp Else ptrTemp = Allocate(newSize * SizeOf(_TYPE_)) If ptrTemp = 0 Then MutexUnLock This.mutex Error 4 ' Out of memory Return EndIf This.Count = 0 DeAllocate This.pItem This.pItem = ptrTemp EndIf MutexUnLock This.mutex End Sub '' returns array item Property _TYPE_##Array.Item(Index As UInteger) As _TYPE_ MutexLock This.mutex If Index >= 0 And Index < This.Count Then Property = This.pItem[Index] MutexUnLock This.mutex Else MutexUnLock This.mutex Error 6 ' Out of bounds array access EndIf End Property '' sets array item Property _TYPE_##Array.Item(Index As UInteger, Value As _TYPE_) MutexLock This.mutex If Index >= 0 And Index < This.Count Then This.pItem[Index] = Value MutexUnLock This.mutex Else MutexUnLock This.mutex Error 6 ' Out of bounds array access EndIf End Property '' returns pointer to value in array Function _TYPE_##Array.PeekAt(Index As UInteger) As _TYPE_ Pointer MutexLock This.mutex If Index >= 0 And Index < This.Count Then Function = VarPtr(This.pItem[Index]) MutexUnLock This.mutex Else MutexUnLock This.mutex Error 6 ' Out of bounds array access EndIf End Function '' returns number of items in array Property _TYPE_##Array.ItemCount As UInteger MutexLock This.mutex ItemCount = This.Count MutexUnLock This.mutex End Property '' iterates trough an array using iterator function '' '' WARNNING: if safe is set to nonzero (default) then thread safety is guaranted but you '' CANNOT call any of array's methods/properties inside iterator function! '' if safe is set to zero then no thread safety is guaranted! (but then you '' can call any of array's methods/properties) '' '' NOTE: in iterator function which accepts index and value of current item, both '' arguments are pased by reference and they can be changed inside iterator, '' iterator function should return nonzero to stop iterating the array Sub _TYPE_##Array.Iterate(iterator As _TYPE_##ArrayIterator, safe As Integer = Not 0) If safe Then MutexLock This.mutex For i As UInteger = 0 To This.Count - 1 If iterator(i, This.pItem[i]) <> 0 Then Exit For Next If safe Then MutexUnLock This.mutex End Sub #EndIf #EndMacro #EndIf