+++ /dev/null
-import "ExplorerTree"
-import "Finder"
-
-class NumberLink : struct
-{
- NumberLink prev, next;
- int num;
-};
-
-struct SearchStackFrame
-{
- int tag;
- char path[MAX_LOCATION];
- FileListing listing;
-
- bool branched;
- //DataRow result;
- //DataRow browse;
- ExplorerFileBranch result;
- ExplorerFileBranch browse;
-};
-
-class SearchThread : Thread
-{
- bool active, terminate, hasNameSearch, hasSizeSearch, hasContentSearch, listLines;
- int count, matchCount;
- char location[MAX_LOCATION], nameSearch[1024], contentSearch[1024];
- bool optionTree, optionBrowser, optionSubdirs;
- bool optionNameMatchCase, optionNameMatchWord;
- bool optionContentMatchCase, optionContentMatchWord;
- OldList lines;
- //DataField resultsNameField;
- //DataField browserNameField;
-
- ExplorerSearch searchPanel;
-
- SearchThread()
- {
- active = false;
- terminate = false;
- }
-
- bool SearchFileContent(String path)
- {
- bool match = false;
- File file = FileOpen(path, read);
- if(file)
- {
- //
- // char line[65536];
- // char * find = null;
- // for( ; !find && file.GetLine(line, 65536) ; )
- // find = SearchString(line, 0, contentSearch, optionContentMatchCase, optionContentMatchWord);
- // // find = strstr(line, contentSearch);
- //
-
- uint readCount = 16383;
- char * find = null;
- char buffer[16384];
- int seekBack = 0 - strlen(contentSearch) - 2;
- if(listLines)
- {
- uint line = 1;
- while(readCount == 16383)
- {
- uint start = 0, len = 0;
- readCount = file.Read(buffer, 1, 16383);
- buffer[readCount] = '\0';
- for( ; start < readCount; start += len ? len : 1)
- {
- if( (len = strlen(&buffer[start])) )
- {
- char * newLine = buffer;
- uint bstart;
- find = SearchString(buffer, start, contentSearch, optionContentMatchCase, optionContentMatchWord);
-
- // todo add a maximum line length possibility as param
- for(bstart = start;
- bstart < readCount && newLine && (!find || newLine < find);
- bstart += (newLine - &buffer[bstart]) / sizeof(char))
- {
- newLine = strstr(&buffer[bstart], "\n");
- newLine++;
- if(bstart + (newLine - &buffer[bstart]) / sizeof(char) < readCount && newLine && (!find || newLine < find))
- line++;
- }
-
- if(find)
- {
- len = (find - &buffer[start]) / sizeof(char) + strlen(contentSearch);
- match = true;
- if(!lines.first || ((NumberLink)lines.last).num != line)
- lines.Add(NumberLink { num = line });
- }
-
- }
- }
- file.Seek(seekBack, current);
- }
- }
- else
- {
- for( ; !find && readCount == 16383; )
- {
- uint start = 0, len = 0;
- readCount = file.Read(buffer, 1, 16383);
- buffer[readCount] = '\0';
- for( ; !find && start < readCount; start += len + 1)
- if( (len = strlen(&buffer[start])) )
- find = SearchString(buffer, start, contentSearch, optionContentMatchCase, optionContentMatchWord);
- file.Seek(seekBack, current);
- }
- match = (bool)find;
- }
- delete file;
- }
- return match;
- }
-
- // I wonder if this is optimized at the c level to be compiled inline
- // and to use in-place in-stack memory for both the return value and the parameters
- // if not, c should be more optimized...
- // would the const have any impact on optimization?
- unsigned int Main()
- {
- bool match;
- int frame, stackTop = 0, treeTop = 0;
- double lastTime = GetTime();
- SearchStackFrame stack[1024];
- //to be used for content replace... EditBox edit { multiLine = true, textHorzScroll = true, textVertScroll = true, maxLineSize = 65536 };
-
- ExplorerFileBranch fileTreeBranch;
- // This won't give drive attribs for c: or c:\ and other drives as well
- // \\Nateus\data\ is not remote, etc...
- // How to?
- FileStats stats;
-
- terminate = false;
- count = 0;
- matchCount = 0;
-
- hasNameSearch = (strlen(nameSearch) != 0);
- hasSizeSearch = false; // this is temporary
- hasContentSearch = (strlen(contentSearch) != 0);
-
- listLines = true;
- lines = OldList { };
-
- //SearchDir(location);
-
- FileGetStats(location, stats);
-
- strcpy(stack[0].path, location);
- stack[0].listing = FileListing { stack[0].path }; // there should be a sorted = true/false
- // Binary Search sorting...
- if(optionTree)
- stack[0].branched = false;
- if(optionBrowser)
- {
- app.Lock();
- {
- //stack[0].browse = searchPanel.AddBrowserRow();
- //fileTreeBranch = MakeFileBranch(attribs, stack[0].path);
- //stack[0].browse.SetData(browserNameField, fileTreeBranch);
- //stack[0].browse.SetData(typeField, null);
- //stack[0].browse.SetData(sizeField, null);
-
- stack[0].browse = MakeFileBranch(stats, stack[0].path);
- searchPanel.AddBrowse(stack[0].browse, null);
- }
- app.Unlock();
- }
-
- for(frame = 0; frame >= 0 && !terminate; )
- {
- if(stack[frame].listing.Find())
- {
- count++;
-
- //match = (strcmp(stack[frame].listing.name, nameSearch) == 0);
- //match = (stack[frame].listing.name[0] == nameSearch[0]);
- //match = (bool)strstr(stack[frame].listing.name, nameSearch);
-
- if(hasNameSearch)
- match = (bool)SearchString(stack[frame].listing.name, 0, nameSearch, optionNameMatchCase, optionNameMatchWord);
- else
- match = true;
-
- if(match && hasContentSearch && !stack[frame].listing.stats.attribs.isDirectory)
- if(!SearchFileContent(stack[frame].listing.path))
- match = false;
-
- if(match)
- {
- matchCount++;
- if(optionTree)
- {
- for(frame = treeTop; frame <= stackTop; frame++)
- {
- if(!stack[frame].branched)
- {
- app.Lock();
- if(frame)
- {
- stack[frame].result = MakeFileBranch(stack[frame - 1].listing.stats, stack[frame - 1].listing.name);
- searchPanel.AddResult(stack[frame].result, stack[frame - 1].result);
- stack[frame].result.row.collapsed = false;
- }
- else
- {
- stack[0].result = MakeFileBranch(stats, stack[0].path);
- searchPanel.AddResult(stack[0].result, null);
- stack[0].result.row.collapsed = false;
- }
- stack[frame].branched = true;
- app.Unlock();
- }
- }
- treeTop = stackTop;
- frame--;
- }
- }
- if(optionSubdirs && stack[frame].listing.stats.attribs.isDirectory)
- {
- app.Lock();
- {
- double thisTime = GetTime();
- if(thisTime - lastTime > 0.25)
- {
- searchPanel.SearchUpdateLabel(stack[stackTop].listing.path);
- lastTime = thisTime;
- }
- }
- //searchPanel.SearchUpdateLabel(stack[stackTop].listing.path);
- frame++;
- if(optionBrowser)
- {
- stack[frame].browse = MakeFileBranch(stack[stackTop].listing.stats, stack[stackTop].listing.name);
- searchPanel.AddBrowse(stack[frame].browse, stack[stackTop].browse);
-
- if(frame)
- stack[frame].browse.row.collapsed = true;
- //if(frame == 1)
- //searchPanel.SortBrowser(); // this can be very bad for performance in some situations
- // there should be a way to sort the nodes as they are added
- // BinarySearch sorting implementation in listBox's Sort?
- }
- app.Unlock();
- strcpy(stack[frame].path, stack[stackTop].listing.path);
- stack[frame].listing = FileListing { stack[frame].path };
- if(optionTree)
- stack[frame].branched = false;
- if(match)
- {
- app.Lock();
- if(optionTree)
- {
- stack[frame].result = MakeFileBranch(stack[stackTop].listing.stats, stack[stackTop].listing.name);
- searchPanel.AddResult(stack[frame].result, stack[stackTop].result);
- stack[frame].result.row.collapsed = false;
- //searchPanel.SortResults(); // this can be very bad for performance in some situations
- // there should be a way to sort the nodes as they are added
- // BinarySearch sorting implementation in listBox's Sort?
- stack[frame].branched = true;
- }
- else
- {
- //searchPanel.SearchAddResultsItem(stack[stackTop].listing.name, stack[stackTop].listing.path);
- }
- app.Unlock();
- }
- stackTop++;
- }
- else
- {
- app.Lock();
- if(optionBrowser)
- {
- ExplorerFileBranch item;
- item = MakeFileBranch(stack[frame].listing.stats, stack[frame].listing.name);
- searchPanel.AddBrowse(item, stack[frame].browse);
- //if(frame == 1)
- //searchPanel.SortBrowser(); // this can be very bad for performance in some situations
- // there should be a way to sort the nodes as they are added
- // BinarySearch sorting implementation in listBox's Sort?
- }
- if(match)
- {
- if(optionTree)
- {
- ExplorerFileBranch item;
- item = MakeFileBranch(stack[frame].listing.stats, stack[frame].listing.name);
- searchPanel.AddResult(item, stack[frame].result);
- item.row.collapsed = false;
- //searchPanel.SortResults(); // this can be very bad for performance in some situations
- // there should be a way to sort the nodes as they are added
- // BinarySearch sorting implementation in listBox's Sort?
-
- if(listLines && lines.first)
- {
- NumberLink lin = lines.first;
- char temp[MAX_F_STRING];
- sprintf(temp, "lines %d", lin.num);
- for(lin = lin.next; lin && strlen(temp) < MAX_F_STRING; lin = lin.next)
- strcatf(temp, ", %d", lin.num);
- fileTreeBranch = ExplorerFileBranch { name = CopyString(temp), type = lineNumbers };
- searchPanel.AddResult(fileTreeBranch, item);
- //row.AddRow().SetData(resultsNameField, fileTreeBranch);
- lines.Free(null);
- }
- }
- else
- ;//searchPanel.SearchAddResultsItem(stack[frame].listing.name, stack[frame].listing.path);
- }
- app.Unlock();
- }
- }
- else
- {
- if(optionTree && stack[frame].branched && frame == treeTop)
- {
- stack[frame].branched = false;
- treeTop--;
- }
- frame--;
- stackTop--;
- }
- }
- if(terminate)
- for( ; frame >= 0 ; frame--)
- stack[frame].listing.Stop();
-
- app.Lock();
- if(optionTree)
- searchPanel.SortResults();
- if(optionBrowser)
- searchPanel.SortBrowser();
- app.Unlock();
-
- active = false;
-
- searchPanel.SearchTerminate();
- return 0;
- }
-}
-
-