Page 1 of 1

Extended Search

Posted: Tue Jun 28, 2005 5:44 pm
by HeX0R
Code updated for 5.20+

This little tool comes in very handy, when dealing with loads of small files (like big php-projects), when you search for special files containing special phrases.
The Search-Routine is very fast, using CompareMemoryString()!

Have phun!

Code: Select all

;/---------------------/
;|                     |
;| Extended Searching  |
;|        V0.1         |
;|                     |
;|   (c)HeX0R 2005     |
;|                     |
;| Search for Phrases  |
;|      in Files       |
;| (Made cause WinXP   |
;| really sucks with   |
;| this...)            |
;|                     |
;/---------------------/

#My_Version = "0.1"
;- Window Constants
;
Enumeration
  #Window_0
  #Window_1
EndEnumeration

;- Gadget Constants
;
Enumeration
  #ExplorerTree_0
  #Listview_0
  #Text_0
  #Text_1
  #Text_2
  #Text_3
  #Text_4
  #Text_5
  #String_0
  #String_1
  #String_2
  #String_3
  #Button_0
  #check01
  #check1
  #check2
  #check3
  #gad1
  #gad2
  #gad3
  #gad4
EndEnumeration

Global NewList Results.s()
Global NewList Extensions.s()

Structure _GLOBALS_
  Searched_Bytes.l
  File_num.l
  File_null.f
  File_count.f
  Search_Pattern.s[3]
EndStructure

Global Globals._GLOBALS_

Procedure Load_Language(FileName$, Mode.b)
  ;/----------------------------/
  ;| Standard Language-Function |
  ;|                            |
  ;| With Mode = #True you can  |
  ;| create a Language File,    |
  ;| which the User can         |
  ;| translate for his/her      |
  ;| needs                      |
  ;/----------------------------/
  ;Mode isn't used in this tool!


  If Mode
    CreatePreferences("English.ini")
  EndIf

  ;If you wonder, why i do the following:
  ;Whenever i add Language-Strings, i had
  ;to ReDIM the Array!
  ;Therefore i do anything here automatically
  ;(Remember i am terrible lazy...)
  i = 0
  Restore Language
  Repeat
    Read.s a$
    If a$ = "<<[[END]]>>"
      Break
    EndIf
    If Mode
      WritePreferenceString(Str(i), a$)
    EndIf
    i + 1
  ForEver

  ;Now we know, how many Elements we have...
  Global Dim Language.s(i)

  If Mode
    ClosePreferences()
  EndIf

  OpenPreferences(FileName$)
  ;Doesn't matter, if FileName$ really exists or not.
  ;If not, the Program will always load the English-Language.
  ;This is the big advantage of PB's Preference-Commands!
  Restore Language
  For k = 0 To i
    Read.s b$
    If Pref_Open
      Language(k) = ReadPreferenceString(Str(k), b$)
    Else
      Language(k) = b$
    EndIf
  Next k
  ClosePreferences()

EndProcedure

Procedure Count_Files(Dir$)
  ;/----------------------------/
  ;|    Count-Files-Function    |
  ;|                            |
  ;| Function will count the    |
  ;| files, which match the     |
  ;| extensions.                |
  ;|(Needed for the Progressbar)|
  ;/----------------------------/

  Protected EntryName$, Extension$
  Protected Verz, Entry

  Verz = ExamineDirectory(#PB_Any, Dir$, "")
  If Verz
    While NextDirectoryEntry(Verz)
      Entry = DirectoryEntryType(Verz)
      
      If Entry = #PB_DirectoryEntry_Directory
        EntryName$ = DirectoryEntryName(Verz)
        If EntryName$ <> "." And EntryName$ <> ".."
          Count_Files(Dir$ + EntryName$ + "\")
        EndIf
      ElseIf Entry = #PB_DirectoryEntry_File

        EntryName$ = DirectoryEntryName(Verz)
        Extension$ = LCase(GetExtensionPart(Dir$ + EntryName$))

        ForEach Extensions()
          If Extensions() = Extension$ Or Extensions() = "*"
            Globals\File_num + 1
            Break
          EndIf
        Next

      EndIf
    Wend
    
    FinishDirectory(Verz)
  EndIf
EndProcedure

Procedure.b Search_Files(Dir$, Use_These_Pattern)
  ;/----------------------------/
  ;|    Main Search-Routine     |
  ;|                            |
  ;| Will return 1, when user   |
  ;| closed the progress-window |
  ;/----------------------------/

  Protected EntryName$, Extension$
  Protected Ok.b, Check_Byte.b, Found.b, State.b
  Protected Use_Pattern, Length, k, i, Event, Verz, Entry, Le, Le2, ORed
  Protected *Buffer
  Protected Factor.f

  Verz = ExamineDirectory(#PB_Any, Dir$, "")
  ORed = GetGadgetState(#check01)

  If Verz
    While NextDirectoryEntry(Verz)
      Entry = DirectoryEntryType(Verz)
      If Entry = #PB_DirectoryEntry_Directory
        EntryName$ = DirectoryEntryName(Verz)
        If EntryName$ <> "." And EntryName$ <> ".."
          If Search_Files(Dir$ + EntryName$ + "\", Use_These_Pattern)
            ProcedureReturn 1
          EndIf
        EndIf
      ElseIf Entry = #PB_DirectoryEntry_File

        EntryName$ = DirectoryEntryName(Verz)
        Extension$ = LCase(GetExtensionPart(Dir$ + EntryName$))
        Found = #False

        ForEach Extensions()
          If Extensions() = Extension$ Or Extensions() = "*"
            Found = #True
            Break
          EndIf
        Next

        If Found
          Globals\File_null + Globals\File_count
          SetGadgetState(#gad3, Globals\File_null)
          If Len(Dir$ + EntryName$) > 40
            SetGadgetText(#gad2, Left(Dir$ + EntryName$, 20) + "..." + Right(Dir$ + EntryName$, 20))
          Else
            SetGadgetText(#gad2, Dir$ + EntryName$)
          EndIf

          Ok          = #False
          Use_Pattern = Use_These_Pattern
          Factor      = 0

          If ReadFile(0, Dir$ + EntryName$)
            Length = Lof(0)
            If Length > 0
              *Buffer = ReAllocateMemory(*Buffer, Length)
              If *Buffer
                ReadData(0, *Buffer, Length)
                Factor     = 100 / Length
                Check_Byte = 1

                For k = 0 To 2
                  If Use_Pattern & Check_Byte = 0

                    State = GetGadgetState(k + #check1) ! 1
                    Le    = Len(Globals\Search_Pattern[k])
                    Le2   = Length - Le
                    For i = 0 To Le2
                      SetGadgetState(#gad4, i * Factor)
                      Globals\Searched_Bytes + 1
                      If CompareMemoryString(*Buffer + i, @Globals\Search_Pattern[k] , State, Le) = 0
                        Globals\Searched_Bytes + Le - 1
                        Use_Pattern | Check_Byte
                        If Use_Pattern = 7 Or ORed
                          Ok = #True
                          Break 2
                        EndIf
                        Break
                      EndIf
                    Next i

                    ;Clear Event-Queue!!
                    ;Otherwise Window will be very laggy!!
                    Repeat
                      Event = WindowEvent()
                      If Event = #WM_CLOSE
                        Select EventWindow()
                          Case #Window_0
                            CloseWindow(#Window_1)
                            CloseWindow(#Window_0)
                            End
                          Case #Window_1
                            If *Buffer
                              FreeMemory(*Buffer)
                            EndIf
                            ProcedureReturn 1
                         EndSelect
                      EndIf
                    Until Event = 0

                  EndIf
                  Check_Byte << 1
                Next k

              EndIf
            EndIf
            CloseFile(0)
          EndIf
          If Ok
            AddElement(Results())
            Results() = Dir$ + EntryName$
          EndIf
        EndIf
      EndIf
    Wend
    
    FinishDirectory(Verz)
  EndIf
  If *Buffer
    FreeMemory(*Buffer)
  EndIf
  ProcedureReturn 0
EndProcedure

Load_Language("", 0)

If OpenWindow(#Window_0, 243, 98, 570, 352, Language(4)+" V" + #My_Version, #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_MinimizeGadget) = 0 
  End
EndIf

TextGadget(#Text_4, 10, 4, 100, 14, Language(13))
TextGadget(#Text_5, 200, 4, 100, 14, Language(14))
ExplorerTreeGadget(#ExplorerTree_0, 10, 20, 180, 190, "", #PB_Explorer_AlwaysShowSelection | #PB_Explorer_NoFiles | #PB_Explorer_AutoSort)
ListViewGadget(#Listview_0, 200, 20, 360, 190)
TextGadget(#Text_0, 10, 220, 95, 20, Language(15))
TextGadget(#Text_1, 10, 250, 95, 20, Language(15))
TextGadget(#Text_2, 10, 280, 95, 20, Language(15))
StringGadget(#String_0, 110, 220, 350, 20, "")
StringGadget(#String_1, 110, 250, 350, 20, "")
StringGadget(#String_2, 110, 280, 350, 20, "")
CheckBoxGadget(#check1, 466, 220, 130, 20, Language(1))
CheckBoxGadget(#check2, 466, 250, 130, 20, Language(1))
CheckBoxGadget(#check3, 466, 280, 130, 20, Language(1))
TextGadget(#Text_3, 10, 305, 100, 40, Language(2))
StringGadget(#String_3, 110, 310, 350, 20, "php,txt,bat,ini,c")
ButtonGadget(#Button_0, 466, 310, 94, 20, Language(3))
CheckBoxGadget(#check01, 10, 335, 500, 15, Language(10))

DisableGadget(#Text_0, 1)
DisableGadget(#Text_1, 1)
DisableGadget(#Text_2, 1)
DisableGadget(#check1, 1)
DisableGadget(#check2, 1)
DisableGadget(#check3, 1)
DisableGadget(#Button_0, 1)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      GadgetID = EventGadget()

      If GadgetID = #Button_0
        ClearGadgetItems(#Listview_0)

        Globals\Searched_Bytes = 0
        Needed_Time          = ElapsedMilliseconds()
        For i = #ExplorerTree_0 To #check3
          DisableGadget(i, 1)
        Next i

        If GetGadgetText(#String_3) = ""
          SetGadgetText(#String_3, "*")
        EndIf
        ClearList(Extensions())
        i = 1
        While StringField(GetGadgetText(#String_3), i, ",") <> ""
          AddElement(Extensions())
          Extensions() = Trim(LCase(StringField(GetGadgetText(#String_3), i, ",")))
          i + 1
        Wend
        Globals\Search_Pattern[0] = GetGadgetText(#String_0)
        Globals\Search_Pattern[1] = GetGadgetText(#String_1)
        Globals\Search_Pattern[2] = GetGadgetText(#String_2)
        Active_File$              = GetGadgetText(#ExplorerTree_0)
        Globals\File_num          = 0
        Globals\File_null         = 0

        Count_Files(Active_File$)
        Globals\File_count = 100 / Globals\File_num
        OpenWindow(#Window_1, 354, 160, 302, 129, Language(5) + "...",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar, WindowID(#Window_0))
        TextGadget(#gad1, 10, 10, 280, 20, Language(6) , #PB_Text_Center)
        TextGadget(#gad2, 10, 40, 280, 20, "", #PB_Text_Center)
        ProgressBarGadget(#gad3, 10, 70, 280, 20, 0, 100, #PB_ProgressBar_Smooth)
        ProgressBarGadget(#gad4, 10, 95, 280, 20, 0, 100, #PB_ProgressBar_Smooth)
        SetGadgetState(#gad3, 0)
        Found = 0
        For i = 0 To 2
          If Globals\Search_Pattern[i] = ""
            Found + Int(Pow(2,i))
          EndIf
        Next i
        While WindowEvent() : Wend

        Cancel.b = Search_Files(Active_File$, Found)

        CloseWindow(#Window_1)

        For i = #ExplorerTree_0 To #check3
          DisableGadget(i, 0)
        Next i
        If GetGadgetText(#String_0) = ""
          DisableGadget(#Text_0, 1)
          DisableGadget(#check1, 1)
        EndIf
        If GetGadgetText(#String_1) = ""
          DisableGadget(#Text_1, 1)
          DisableGadget(#check2, 1)
        EndIf
        If GetGadgetText(#String_2) = ""
          DisableGadget(#Text_2, 1)
          DisableGadget(#check3, 1)
        EndIf

        If Cancel
          AddGadgetItem(#Listview_0, -1, Language(7))
        Else
          AddGadgetItem(#Listview_0, -1, ReplaceString(Language(12), "{files}", Str(ListSize(Results()))))
          AddGadgetItem(#Listview_0, -1, "----------------------------------------")
          AddGadgetItem(#Listview_0, -1, "")

          i = 0
          ForEach Results()
            i + 1
            AddGadgetItem(#Listview_0, -1, Str(i) + ". " + Results())
          Next
          AddGadgetItem(#Listview_0, -1, "")
          Needed_Time = (ElapsedMilliseconds() - Needed_Time) / 1000
          h         = Int(Needed_Time / 3600)
          m.b         = Int((Needed_Time - (h * 3600)) / 60)
          s.b         = Int(Needed_Time - (h * 3600) - (m * 60))
          ;---------------------------------------------------------
          Meg       = Int(Globals\Searched_Bytes / 1048576)
          kB        = Int((Globals\Searched_Bytes - (1048576 * Meg)) / 1024)
          Bytes     = Int(Globals\Searched_Bytes - (1048576 * Meg) - (kB * 1024))

          AddGadgetItem(#Listview_0, -1, ReplaceString(ReplaceString(ReplaceString(Language(8), "{h}", Str(h)), "{m}", Str(m)), "{s}", Str(s)))
          AddGadgetItem(#Listview_0, -1, ReplaceString(ReplaceString(ReplaceString(Language(9), "{mb}", Str(Meg)), "{kb}", Str(kB)), "{b}", Str(Bytes)))

          If Needed_Time > 0
            AddGadgetItem(#Listview_0, -1, "kB/sec: " + StrF((Globals\Searched_Bytes / 1024) / Needed_Time, 2))
          Else
            AddGadgetItem(#Listview_0, -1, "kB/sec: " + StrF((Globals\Searched_Bytes / 1024) / 0.1, 2))
          EndIf
          SetGadgetState(#Listview_0, CountGadgetItems(#Listview_0) - 1)
          SetGadgetState(#Listview_0, -1)
          ClearList(Results())
        EndIf

      ElseIf GadgetID = #check01
        If GetGadgetState(#check01)
          SetGadgetText(#check01, Language(11))
        Else
          SetGadgetText(#check01, Language(10))
        EndIf

      ElseIf GadgetID = #String_0 Or GadgetID = #String_1 Or GadgetID = #String_2
        If EventType() = #PB_EventType_Change
          Add = GadgetID - #String_0
          If GetGadgetText(GadgetID) = "" And GetGadgetText(#Text_0 + Add) = Language(0) + " " + Str(Add + 1) + ":"
            SetGadgetText(#Text_0 + Add, Language(15))
            DisableGadget(#Text_0 + Add, 1)
            DisableGadget(#check1 + Add, 1)
            If GetGadgetText(#String_0) = "" And GetGadgetText(#String_1) = "" And GetGadgetText(#String_2) = ""
              DisableGadget(#Button_0, 1)
            EndIf
          ElseIf GetGadgetText(GadgetID) And GetGadgetText(#Text_0 + Add) = Language(15)
            SetGadgetText(#Text_0 + Add, Language(0) + " " + Str(Add + 1) + ":")
            DisableGadget(#Text_0 + Add, 0)
            DisableGadget(#check1 + Add, 0)
            If GetGadgetText(#ExplorerTree_0)
              DisableGadget(#Button_0, 0)
            EndIf
          EndIf
        EndIf
      ElseIf GadgetID = #ExplorerTree_0
        If GetGadgetText(#ExplorerTree_0)
          DisableGadget(#Button_0, 0)
        Else
          DisableGadget(#Button_0, 1)
        EndIf
      EndIf

    Case #WM_CLOSE
      Break

  EndSelect

ForEver

End

DataSection
  Language:
  Data$ "Searchphrase"                                        ;0
  Data$ "Case sensitiv"                                       ;1
  Data$ "Search only the following types"                     ;2
  Data$ "Start Search"                                        ;3
  Data$ "Extended Search"                                     ;4
  Data$ "Search"                                              ;5
  Data$ "Please wait"                                         ;6
  Data$ "User cancelled Search..."                            ;7
  Data$ "Needed time: {h} Hours, {m} Minutes and {s} Seconds" ;8
  Data$ "Searched Bytes: {mb}MB {kb}kB {b}Bytes"              ;9
  Data$ "Find ALL of these Searchphrases"                     ;10
  Data$ "Find one of these Searchphrases"                     ;11
  Data$ "Found {files} Files:"                                ;12
  Data$ "Select Search-Path:"                                 ;13
  Data$ "Search Results:"                                     ;14
  Data$ "No Searchphrase"                                     ;15
  Data$ "<<[[END]]>>"

EndDataSection