Re: Could this be faster?

new topic     » goto parent     » topic index » view thread      » older message » newer message

Here is the Win32Lib friendly version to Pete's walk_dir if anyone
is interested.

include win32lib.ew
without warning

sequence ListOfStructures
ListOfStructures ={}

integer CurrentStructure, LatestSize
atom LabelPointerStart, LabelBlockSize, LabelPointer, LabelPointerEnd

function new_struct()
	ListOfStructures &= 0
	CurrentStructure = length(ListOfStructures)
	LatestSize = 0
	return CurrentStructure
end function

function sizeof(integer id)
	return ListOfStructures[id]
end function

function struc(integer sType)
	integer disp, size
	disp = LatestSize
	if sType > #00FFFFFF then -- this type is defined in dll.e
		size = and_bits(sType, #00FFFFFF)
	else
		size = ListOfStructures[sType]
	end if
	LatestSize += size
	ListOfStructures[CurrentStructure] = LatestSize
	return disp
end function

function anySize(integer size) -- allow arbitrary sized elements
	return or_bits(#01000000, size)
end function

LabelBlockSize = 100000
LabelPointerStart = allocate(LabelBlockSize)
LabelPointer = LabelPointerStart
LabelPointerEnd = LabelPointerStart + LabelBlockSize - 2

function allocate_StringZ(sequence string)
-- allocate, poke & null-terminate a text string

	atom len, temp

	len = length(string)

        -- advance the pointer
	temp = LabelPointer
	LabelPointer += len + 1
	if LabelPointer > LabelPointerEnd then
		LabelPointer = LabelPointerStart + len + 1
		temp = LabelPointerStart
	end if

	-- poke the string into memory
	poke(temp, string)
	poke(temp + len, 0)

	-- exit
	return temp
end function

procedure FatalErr(sequence err_msg)
	integer void
	VOID = message_box("Fatal Error", "Error", {MB_OK, MB_ICONERROR})
	abort(1)
end procedure

procedure link_error(sequence name)
	FatalErr("Couldn't link function:\n\n " & name & "()")
end procedure

function link_c_func(atom dll, sequence name, sequence args, atom result)
	integer handle
	handle = define_c_func(dll, name, args, result)
	if handle = -1 then
                link_error(name)
	else
		return handle
	end if
end function

-- dynamically link a C routine as a Euphoria function
function link_c_proc(atom dll, sequence name, sequence args)
	integer handle
	handle = define_c_proc(dll, name, args)
	if handle = -1 then
                link_error(name)
	else
		return handle
	end if
end function

global function assign_dll(sequence dll_file)
	atom handle
	handle = open_dll(dll_file)
	if handle = NULL then
                link_error(dll_file)
	end if
	return handle
end function

constant
    Kernel32 = assign_dll("kernel32.dll"),
    FINDDATA                = new_struct(),
    FINDDATA_dwAttr         = struc(C_LONG),
    FINDDATA_Times3         = struc(anySize(24)),
    FINDDATA_nFileSizeHigh  = struc(C_LONG),
    FINDDATA_nFileSizeLow   = struc(C_LONG),
    FINDDATA_res2           = struc(anySize(8)),
    FINDDATA_cFileName      = struc(anySize(260)),
    FINDDATA_cAltFileName   = struc(anySize(14)),
    fd = allocate(sizeof(FINDDATA)),
xFindFirstFile  = link_c_func(Kernel32, "FindFirstFileA", {C_POINTER,
    C_POINTER},  C_LONG),
xFindNextFile   = link_c_func(Kernel32, "FindNextFileA",{C_POINTER,
    C_POINTER}, C_INT),
    xFindClose      = link_c_func(Kernel32, "FindClose", {C_POINTER},C_INT),

    INVALID_HANDLE_VALUE=-1

function get_file_ext(sequence filename)
integer c
    for i=length(filename) to 1 by -1 do
        c = filename[i]
        if c = '.' then
            return filename[i+1..length(filename)]
        elsif c>='A' and c<='Z' then
            filename[i] = c+32
        end if
    end for
    return ""
end function

procedure wd(sequence path)
-- walk_dir coded using winAPI direct.
-- results not in any particular order.
integer d
atom fH, attr
sequence longname
sequence ipath
sequence dirstack

    ipath = path
    dirstack={}

    if platform()!=2 then ?9/0 end if   --Win32 only supported

    while 1 do
        --
        -- Force consistent use of '\\' vs '/'.
        --
        d=find('/',path)
        if d=0 then exit end if
        path[d]='\\'
    end while

    fH=INVALID_HANDLE_VALUE
    if length(path) and path[length(path)]='\\' then
        path&="*.*"
    elsif length(path) and path[length(path)]=':' then
        ipath = path&'\\'
        path&="\\*.*"
    --NB I doubt this will work with wildcards!
    elsif not find('*',path) and not find('?',path) then
        --
        -- Check if the passed path is a directory;
        -- if it is, list it's contents, not just it.
        --
        fH = c_func(xFindFirstFile,{allocate_StringZ(path),fd})
        if fH!=INVALID_HANDLE_VALUE then
            attr = peek4u(fd + FINDDATA_dwAttr)
            if and_bits(attr,#10) then  -- directory bit
                ipath&='\\'
                path&="\\*.*"
                if c_func(xFindClose,{fH}) then end if
                fH=INVALID_HANDLE_VALUE
            end if
        end if
    end if
    if fH=INVALID_HANDLE_VALUE then
        fH = c_func(xFindFirstFile,{allocate_StringZ(path),fd})
    end if
    if fH!=INVALID_HANDLE_VALUE then
        while 1 do
            attr = peek4u(fd + FINDDATA_dwAttr)
            longname = peek_string(fd + FINDDATA_cFileName)
            if and_bits(attr,#10) then
                if not find(longname,{".",".."}) then
                    dirstack = append(dirstack,ipath&longname)
                end if
            else
                if find(get_file_ext(longname),{"aac","mp4", "mp3",
                "mp2", "mp1", "ogg", "wav"}) then
-- DEV: call external routine/append to result stack
                    puts(1,longname&'\n')
                end if
            end if
            if not c_func(xFindNextFile,{fH,fd}) then exit end if
        end while
        if c_func(xFindClose,{fH}) then end if
        for i=1 to length(dirstack) do
            wd(dirstack[i])
        end for
    end if
end procedure
wd("C:\\")




----If you continue to do what you have always done,
you will get what you have always gotten.----

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu