2525using myoddweb . directorywatcher . interfaces ;
2626using Nito . AspNetBackgroundTasks ;
2727using Nito . AsyncEx ;
28+ using NReco . Text ;
2829
2930namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
3031{
@@ -42,12 +43,17 @@ internal static class Global
4243 public static long MaxFileSizeMB = 2048 ;
4344
4445
45- public static List < string > WatchedCodeExtension = new List < string > ( ) { "cs" , "py" } ;
46- public static List < string > WatchedResXExtension = new List < string > ( ) { "resx" } ;
46+ public static HashSet < string > WatchedCodeExtension = new HashSet < string > ( ) { "cs" , "py" } ;
47+ public static HashSet < string > WatchedResXExtension = new HashSet < string > ( ) { "resx" } ;
4748
48- public static List < string > ExcludedExtensions = new List < string > ( ) { "*~" , "tmp" } ;
49- public static List < string > IgnorePathsStartingWith = new List < string > ( ) ;
50- public static List < string > IgnorePathsContaining = new List < string > ( ) ;
49+ public static HashSet < string > ExcludedExtensions = new HashSet < string > ( ) { "*~" , "tmp" } ;
50+
51+ public static List < string > IgnorePathsStartingWithList = new List < string > ( ) ;
52+ public static List < string > IgnorePathsContainingList = new List < string > ( ) ;
53+ public static List < string > IgnorePathsEndingWithList = new List < string > ( ) ;
54+
55+ public static bool IgnorePathsContainingACHasAny = false ;
56+ public static AhoCorasickDoubleArrayTrie < bool > IgnorePathsContainingAC = new AhoCorasickDoubleArrayTrie < bool > ( ) ;
5157
5258 public static string AsyncPath = "" ;
5359 public static string SyncPath = "" ;
@@ -97,6 +103,15 @@ public bool Is(EventAction action)
97103
98104 internal class Program
99105 {
106+ //let null char mark start and end of a filename
107+ //https://stackoverflow.com/questions/54205087/how-can-i-create-a-file-with-null-bytes-in-the-filename
108+ //https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
109+ //https://serverfault.com/questions/242110/which-common-characters-are-illegal-in-unix-and-windows-filesystems
110+ public static readonly string NullChar = new string ( new char [ ] { ( char ) 0 } ) ;
111+
112+ public static readonly string DirectorySeparatorChar = new string ( new char [ ] { Path . DirectorySeparatorChar } ) ;
113+
114+
100115 private static byte [ ] GetHash ( string inputString )
101116 {
102117#pragma warning disable SCS0006 //Warning SCS0006 Weak hashing function
@@ -151,14 +166,26 @@ private static void Main()
151166 Global . AsyncPathMinFreeSpace = fileConfig . GetLong ( "AsyncPathMinFreeSpace" ) ?? 0 ;
152167 Global . SyncPathMinFreeSpace = fileConfig . GetLong ( "SyncPathMinFreeSpace" ) ?? 0 ;
153168
154- Global . WatchedCodeExtension = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "WatchedCodeExtensions" , "WatchedCodeExtension" ) ;
155- Global . WatchedResXExtension = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "WatchedResXExtensions" , "WatchedResXExtension" ) ;
169+ Global . WatchedCodeExtension = new HashSet < string > ( fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "WatchedCodeExtensions" , "WatchedCodeExtension" ) ) ;
170+ Global . WatchedResXExtension = new HashSet < string > ( fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "WatchedResXExtensions" , "WatchedResXExtension" ) ) ;
156171
157172 //this would need Microsoft.Extensions.Configuration and Microsoft.Extensions.Configuration.Binder packages
158- Global . ExcludedExtensions = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "ExcludedExtensions" , "ExcludedExtension" ) ; //NB! UpperOnWindows
173+ Global . ExcludedExtensions = new HashSet < string > ( fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "ExcludedExtensions" , "ExcludedExtension" ) ) ; //NB! UpperOnWindows
159174
160- Global . IgnorePathsStartingWith = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "IgnorePathsStartingWith" , "IgnorePathStartingWith" ) ; //NB! UpperOnWindows
161- Global . IgnorePathsContaining = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "IgnorePathsContaining" , "IgnorePathContaining" ) ; //NB! UpperOnWindows
175+ Global . IgnorePathsStartingWithList = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "IgnorePathsStartingWith" , "IgnorePathStartingWith" ) ; //NB! UpperOnWindows
176+ Global . IgnorePathsContainingList = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "IgnorePathsContaining" , "IgnorePathContaining" ) ; //NB! UpperOnWindows
177+ Global . IgnorePathsEndingWithList = fileConfig . GetListUpperOnWindows ( Global . CaseSensitiveFilenames , "IgnorePathsEndingWith" , "IgnorePathEndingWith" ) ; //NB! UpperOnWindows
178+
179+ var ACInput = Global . IgnorePathsStartingWithList . Select ( x => new KeyValuePair < string , bool > ( NullChar + x , false ) )
180+ . Concat ( Global . IgnorePathsContainingList . Select ( x => new KeyValuePair < string , bool > ( x , false ) ) )
181+ . Concat ( Global . IgnorePathsEndingWithList . Select ( x => new KeyValuePair < string , bool > ( x + NullChar , false ) ) )
182+ . ToList ( ) ;
183+
184+ if ( ACInput . Any ( ) ) //needed to avoid exceptions
185+ {
186+ Global . IgnorePathsContainingACHasAny = true ;
187+ Global . IgnorePathsContainingAC . Build ( ACInput ) ;
188+ }
162189
163190
164191 var pathHashes = "" ;
@@ -377,10 +404,13 @@ private static IAsyncEnumerable<FileInfo> ProcessSubDirs(DirectoryInfo srcDirInf
377404 continue ;
378405
379406
380- var nonFullNameInvariant = ConsoleWatch . GetNonFullName ( dirInfo . FullName ) + Path . PathSeparator ;
407+ var nonFullNameInvariantWithLeadingSlash = DirectorySeparatorChar + Extensions . GetDirPathWithTrailingSlash ( ConsoleWatch . GetNonFullName ( dirInfo . FullName . ToUpperInvariantOnWindows ( Global . CaseSensitiveFilenames ) ) ) ;
381408 if (
382- Global . IgnorePathsStartingWith . Any ( x => nonFullNameInvariant . StartsWith ( x ) )
383- || Global . IgnorePathsContaining . Any ( x => nonFullNameInvariant . Contains ( x ) )
409+ //Global.IgnorePathsStartingWith.Any(x => nonFullNameInvariantWithLeadingSlash.StartsWith(x))
410+ //|| Global.IgnorePathsContaining.Any(x => nonFullNameInvariantWithLeadingSlash.Contains(x))
411+ //|| Global.IgnorePathsEndingWith.Any(x => nonFullNameInvariantWithLeadingSlash.EndsWith(x))
412+ Global . IgnorePathsContainingACHasAny //needed to avoid exceptions
413+ && Global . IgnorePathsContainingAC . ParseText ( NullChar + nonFullNameInvariantWithLeadingSlash /* + NullChar*/ ) . Any ( ) //NB! no NullChar appended to end since it is dir path not complete file path
384414 )
385415 {
386416 continue ;
@@ -1037,7 +1067,7 @@ private static bool IsWatchedFile(string fullName)
10371067 || Global . WatchedResXExtension . Contains ( "*" )
10381068 )
10391069 &&
1040- Global . ExcludedExtensions . All ( x =>
1070+ Global . ExcludedExtensions . All ( x => //TODO: optimise
10411071
10421072 ! fullNameInvariant . EndsWith ( "." + x )
10431073 &&
@@ -1049,11 +1079,14 @@ private static bool IsWatchedFile(string fullName)
10491079 )
10501080 )
10511081 {
1052- var nonFullNameInvariant = GetNonFullName ( fullNameInvariant ) ;
1082+ var nonFullNameInvariantWithLeadingSlash = Program . DirectorySeparatorChar + GetNonFullName ( fullNameInvariant ) ;
10531083
10541084 if (
1055- Global . IgnorePathsStartingWith . Any ( x => nonFullNameInvariant . StartsWith ( x ) )
1056- || Global . IgnorePathsContaining . Any ( x => nonFullNameInvariant . Contains ( x ) )
1085+ //Global.IgnorePathsStartingWith.Any(x => nonFullNameInvariantWithLeadingSlash.StartsWith(x))
1086+ //|| Global.IgnorePathsContaining.Any(x => nonFullNameInvariantWithLeadingSlash.Contains(x))
1087+ //|| Global.IgnorePathsEndingWith.Any(x => nonFullNameInvariantWithLeadingSlash.EndsWith(x))
1088+ Global . IgnorePathsContainingACHasAny //needed to avoid exceptions
1089+ && Global . IgnorePathsContainingAC . ParseText ( Program . NullChar + nonFullNameInvariantWithLeadingSlash + Program . NullChar ) . Any ( )
10571090 )
10581091 {
10591092 return false ;
0 commit comments