#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.6.1
 Author:         aldoniel

 Script Function:
	Template AutoIt script.

The ListDir function returns a table listing every file or directory from a root dir, including or not subdirectories.
It uses the FileFindFirstFile function, so you have to provide a file name pattern using windows syntax (ie. you can use * and ? wildcards)
(Also demo of the Arraycreate/ArrayAddOptim/ArrayGetNextItem functions, kind of minimalistic table memory manager)

Syntax :
ListDir(byref $variable_to_list_files, byref $variable_to_list_directories, "root dir","search pattern", explore subdirectories true|false)
returns : nothing
if BitAND(@error,4)==4 means no array match
if BitAND(@error,4)==2 means no file match

#ce ----------------------------------------------------------------------------

Func ListDir(byref $tblFileList, byref $tblDir, $rootdir, $filefilter, $explore_subdir=true, $absolute_path=true) ;do not explore subdirs if set to false
	; !! check error return code (demo)
	local $sFile, $temp
	Arraycreate($tblDir,400,1500) ; arbitrary size : 400 directories, 1500 increment, etc.
	Arraycreate($tblFileList,4000,15000)
	If StringRight($rootdir, 1) <> '\' Then $rootdir &= '\'
	While 1 ;$rootdir <>0 ; on pourrait mettre while 1
		$hSearch = FileFindFirstFile ($rootdir &$filefilter)
		while $hSearch <> -1 ; erreur ou répertoire vide
			$sFile = FileFindNextFile ($hSearch)
			if @error then ExitLoop ; no more file match
			if @extended <> 1 Then ; if is not directory
				if $absolute_path then
					ArrayAddOptim($tblFileList,$rootdir&$sFile)
				Else
					ArrayAddOptim($tblFileList,$sFile)
				EndIf
			Else
				if $absolute_path then
					ArrayAddOptim($tblDir,$rootdir&$sFile&"\")
				Else
					ArrayAddOptim($tblDir,$sFile&"\")
				EndIf
			EndIf
		WEnd
		FileClose($hSearch)
		if $explore_subdir==False then ExitLoop
		$temp=ArrayGetNextItem($tblDir)
		If not @error then
			$rootdir=$temp
		Else
			ExitLoop
		EndIf
	WEnd
	local $errorcode=0
	ArrayClean($tblFileList)
	if @error then $errorcode=2
	ArrayClean($tblDir)
	if @error then $errorcode+=4
	SetError($errorcode)
EndFunc

func ArrayClean(ByRef $array) ; convert AddArrayOptim special table into a normal one
	; @error = -1 means no file/dir found
	local $new_size=$array[1]-4
	if $new_size <=0 Then
		$array=0
		SetError(-1)
		Return
	EndIf
		local $buffer[$new_size]
	local $i
	local $max = $array[1] -1
	for $i=4 to $max
		$buffer[$i-4] = $array[$i]
	Next
	$array=$buffer
EndFunc


func ArrayCreate(byref $array, $array_size, $increment)
dim $array[$array_size+4]
$array[0]=$array_size+4 ;real size returned by ubound
$array[1]=4 ; first adress not reserved (write)
$array[2]=4
$array[3]=$increment
EndFunc

func ArrayGetNextItem(byref $array)
	if $array[2]<$array[1] Then		; security : you cannot read what hasn't been written.
		$array[2]+=1
		return $array[$array[2]-1]
	Else
		SetError(true)
		return ""
	EndIf
EndFunc

func ArrayAddOptim(ByRef $avArray, $vValue)
; usage : create an array with ArrayCreate. Arguments / return : cf _ArrayAdd
; add a value to the end of an special array like _ArrayAdd
; !! $avArray[0 to 2] are reserved, no user data. Do not read, do not change.
; !! $avArray[0] is the array size returned by ubound
; !! $avArray[1] is the array write pointer
; !! $avArray[2] is the array read pointer
; !! $avArray[3] is the array size increment
; Like _ArrayAdd, but to reduce CPU load, it use less the Redim function
; in exchange of more memory usage adds the size increment to the end of the table
; and only redim if the table is full.
; Kind of oriented object without objects...
; max 16 million elements
; test : ArrayAddOptim time consumption is almost linear, whereas ArrayAdd has a very small exponential factor, wich is negligeable for a few thousand files (+200%  time), but not for a whole drive (lunch break, more than 1 hour, wasn't enought ; optim dit it in 100")
If Not IsArray($avArray) Then Return SetError(1, 0, -1)
If UBound($avArray, 0) <> 1 Then Return SetError(2, 0, -1)

if $avArray[1]>=$avArray[0] Then ;redim too small table
	redim $avArray[$avArray[0] + $avArray[3]]
	$avArray[0]+=$avArray[3]
EndIf
$avArray[$avArray[1]]=$vValue
$avArray[1]+=1
Return $avArray[1]
EndFunc