public List <VCodeHunt.SearchFile.KeywordMatch> Search(SearchParams searchParams, string file) { List <VCodeHunt.SearchFile.KeywordMatch> matches = new List <VCodeHunt.SearchFile.KeywordMatch>(); VCodeHunt.SearchFile.KeywordMatch match = new VCodeHunt.SearchFile.KeywordMatch(); System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding(); byte[] keywords = ascii.GetBytes(searchParams.Keywords); byte[] keywordsLowerCase = ascii.GetBytes(searchParams.Keywords.ToLower()); byte[] keywordsUpperCase = ascii.GetBytes(searchParams.Keywords.ToUpper()); int overlap = keywords.Count() - 1; const int bufflen = 64 * 1024; byte[] buff = new byte[bufflen + overlap]; using (BinaryReader br = new BinaryReader(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { long maxlen = br.BaseStream.Length; long idx = 0; long bytesRead = 0; while (idx < maxlen || m_terminate.WaitOne(0)) { // search data must overlap bytesRead = br.Read(buff, 0, bufflen + overlap); if (0 == bytesRead || bytesRead <= overlap) { break; } // search byte[] matchkeywords = keywords; long bytesMax = bytesRead - (searchParams.Keywords.Length - 1); bool found = false; for (int bidx = 0; bidx < bytesMax; bidx++) { found = false; matchkeywords = keywords; if (searchParams.UseCaseSensitiveMatch) { if (buff[bidx] == keywords[0]) { found = true; for (int kidx = 1, sidx = bidx; kidx < keywords.Length && sidx < bytesMax; kidx++, sidx++) { if (buff[sidx] != keywords[kidx]) { break; } } } } else { int kidx = 0; int sidx = bidx; for (; kidx < keywords.Length && sidx < bytesMax; kidx++, sidx++) { if (buff[sidx] == keywordsLowerCase[kidx]) { matchkeywords[kidx] = keywordsLowerCase[kidx]; } else if (buff[sidx] == keywordsUpperCase[kidx]) { matchkeywords[kidx] = keywordsUpperCase[kidx]; } else { found = false; break; } } found = kidx == keywords.Length; } // check for match if (found) { match.SetMatch(idx + bidx, matchkeywords, matchkeywords, FileContentType.Binary); matches.Add(match); match = new VCodeHunt.SearchFile.KeywordMatch(); } else if (searchParams.ShowContextLines && searchParams.ContextLinesCount > 0) { if (matches.Count > 0 && matches.Last().ContextPost.Count < searchParams.ContextLinesCount) { matches.Last().ContextPost.Enqueue(String.Format("{0:X2}", buff[bidx])); } else { if (match.ContextPre.Count != 0 && match.ContextPre.Count >= searchParams.ContextLinesCount) { match.ContextPre.Dequeue(); } match.ContextPre.Enqueue(String.Format("{0:X2}", buff[bidx])); } } } idx += (bytesRead - overlap); if (m_terminate.WaitOne(0)) { break; } } } return(matches.Count() == 0 ? null : matches); }
public List <VCodeHunt.SearchFile.KeywordMatch> Search(SearchParams searchParams, string file) { // test regex is actually valid Regex regex = null; if (searchParams.UseRegexMatch) { try { regex = new Regex(searchParams.Keywords, searchParams.UseCaseSensitiveMatch ? RegexOptions.None : RegexOptions.IgnoreCase); } catch (ArgumentException) { // no point dropping out return(null); } } List <VCodeHunt.SearchFile.KeywordMatch> matches = new List <VCodeHunt.SearchFile.KeywordMatch>(); VCodeHunt.SearchFile.KeywordMatch match = new VCodeHunt.SearchFile.KeywordMatch(); using (StreamReader sr = new StreamReader(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { string line = string.Empty; Int64 lineCount = 1; while (!sr.EndOfStream || m_terminate.WaitOne(0)) { string keywordsMatched = string.Empty; line = sr.ReadLine(); if (null == line) { break; } bool found = false; if (searchParams.UseRegexMatch) { Match regexmatch = regex.Match(line); if (regexmatch.Success) { keywordsMatched = regexmatch.Value; found = true; } } else { int matchIndex = line.IndexOf(searchParams.Keywords, searchParams.UseCaseSensitiveMatch ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase); if (-1 != matchIndex) { found = true; keywordsMatched = line.Substring(matchIndex, searchParams.Keywords.Length); if (searchParams.UseWholeWordMatch) { // test start if (matchIndex != 0 && char.IsLetterOrDigit(line[matchIndex - 1])) { found = false; } // test end if (matchIndex != line.Length - searchParams.Keywords.Length && char.IsLetterOrDigit(line[matchIndex + searchParams.Keywords.Length])) { found = false; } } } } // store match if (!searchParams.UseNegateSearch == found) { match.SetMatch(lineCount, line, keywordsMatched, FileContentType.Text); matches.Add(match); match = new VCodeHunt.SearchFile.KeywordMatch(); } else if (searchParams.ShowContextLines && searchParams.ContextLinesCount > 0) { if (matches.Count > 0 && matches.Last().ContextPost.Count < searchParams.ContextLinesCount) { matches.Last().ContextPost.Enqueue(line); } else { if (match.ContextPre.Count != 0 && match.ContextPre.Count >= searchParams.ContextLinesCount) { match.ContextPre.Dequeue(); } match.ContextPre.Enqueue(line); } } lineCount++; if (m_terminate.WaitOne(0)) { break; } } } return(matches.Count() == 0 ? null : matches); }