11using System ;
22using System . Collections . Generic ;
3- using System . IO ;
4- using System . Text ;
53using Hasher . Features ;
64using SabreTools . CommandLine ;
75using SabreTools . CommandLine . Features ;
8- using SabreTools . CommandLine . Inputs ;
9- using SabreTools . Hashing ;
106
117namespace Hasher
128{
139 public static class Program
1410 {
15- #region Constants
16-
17- private const string _debugName = "debug" ;
18- private const string _typeName = "type" ;
19-
20- #endregion
21-
2211 public static void Main ( string [ ] args )
2312 {
2413 // Create the command set
25- var commandSet = CreateCommands ( ) ;
14+ var mainFeature = new MainFeature ( ) ;
15+ var commandSet = CreateCommands ( mainFeature ) ;
2616
2717 // If we have no args, show the help and quit
2818 if ( args == null || args . Length == 0 )
@@ -38,39 +28,33 @@ public static void Main(string[] args)
3828 var topLevel = commandSet . GetTopLevel ( featureName ) ;
3929 switch ( topLevel )
4030 {
31+ // Standalone Options
4132 case Help help : help . ProcessArgs ( args , 0 , commandSet ) ; return ;
4233 case ListFeature lf : lf . Execute ( ) ; return ;
43- }
4434
45- // Loop through and process the options
46- int firstFileIndex = 0 ;
47- for ( ; firstFileIndex < args . Length ; firstFileIndex ++ )
48- {
49- string arg = args [ firstFileIndex ] ;
50-
51- var input = commandSet . GetTopLevel ( arg ) ;
52- if ( input == null )
35+ // Default Behavior
36+ default :
37+ if ( ! mainFeature . ProcessArgs ( args , 0 ) )
38+ {
39+ commandSet . OutputAllHelp ( ) ;
40+ return ;
41+ }
42+ else if ( ! mainFeature . VerifyInputs ( ) )
43+ {
44+ Console . Error . WriteLine ( "At least one input is required" ) ;
45+ commandSet . OutputAllHelp ( ) ;
46+ return ;
47+ }
48+
49+ mainFeature . Execute ( ) ;
5350 break ;
54-
55- input . ProcessInput ( args , ref firstFileIndex ) ;
56- }
57-
58- // Get the required variables
59- bool debug = commandSet . GetBoolean ( _debugName ) ;
60- List < HashType > hashTypes = GetHashTypes ( commandSet . GetStringList ( _typeName ) ) ;
61-
62- // Loop through all of the input files
63- for ( int i = firstFileIndex ; i < args . Length ; i ++ )
64- {
65- string arg = args [ i ] ;
66- PrintPathHashes ( arg , hashTypes , debug ) ;
6751 }
6852 }
6953
7054 /// <summary>
7155 /// Create the command set for the program
7256 /// </summary>
73- private static CommandSet CreateCommands ( )
57+ private static CommandSet CreateCommands ( MainFeature mainFeature )
7458 {
7559 List < string > header = [
7660 "File Hashing Program" ,
@@ -90,118 +74,14 @@ private static CommandSet CreateCommands()
9074 var commandSet = new CommandSet ( header , footer ) ;
9175
9276 // Standalone Options
93- commandSet . Add ( new Help ( ) ) ;
77+ commandSet . Add ( new Help ( [ "-?" , "-h" , "--help" ] ) ) ;
9478 commandSet . Add ( new ListFeature ( ) ) ;
9579
9680 // Hasher Options
97- commandSet . Add ( new FlagInput ( _debugName , [ "-d" , "--debug" ] , "Enable debug mode" ) ) ;
98- commandSet . Add ( new StringListInput ( _typeName , [ "-t" , "--type" ] , "Select included hashes" ) ) ;
81+ commandSet . Add ( mainFeature . DebugInput ) ;
82+ commandSet . Add ( mainFeature . TypeInput ) ;
9983
10084 return commandSet ;
10185 }
102-
103- /// <inheritdoc/>
104- private static List < HashType > GetHashTypes ( List < string > types )
105- {
106- List < HashType > hashTypes = [ ] ;
107- if ( types . Count == 0 )
108- {
109- hashTypes . Add ( HashType . CRC32 ) ;
110- hashTypes . Add ( HashType . MD5 ) ;
111- hashTypes . Add ( HashType . SHA1 ) ;
112- hashTypes . Add ( HashType . SHA256 ) ;
113- }
114- else if ( types . Contains ( "all" ) )
115- {
116- hashTypes = [ .. ( HashType [ ] ) Enum . GetValues ( typeof ( HashType ) ) ] ;
117- }
118- else
119- {
120- foreach ( string typeString in types )
121- {
122- HashType ? hashType = typeString . GetHashType ( ) ;
123- if ( hashType != null && ! hashTypes . Contains ( hashType . Value ) )
124- hashTypes . Add ( item : hashType . Value ) ;
125- }
126- }
127-
128- return hashTypes ;
129- }
130-
131- /// <summary>
132- /// Wrapper to print hashes for a single path
133- /// </summary>
134- /// <param name="path">File or directory path</param>
135- /// <param name="hashTypes">Set of hashes to retrieve</param>
136- /// <param name="debug">Enable debug output</param>
137- private static void PrintPathHashes ( string path , List < HashType > hashTypes , bool debug )
138- {
139- Console . WriteLine ( $ "Checking possible path: { path } ") ;
140-
141- // Check if the file or directory exists
142- if ( File . Exists ( path ) )
143- {
144- PrintFileHashes ( path , hashTypes , debug ) ;
145- }
146- else if ( Directory . Exists ( path ) )
147- {
148- foreach ( string file in Directory . GetFiles ( path , "*" , SearchOption . AllDirectories ) )
149- {
150- PrintFileHashes ( file , hashTypes , debug ) ;
151- }
152- }
153- else
154- {
155- Console . WriteLine ( $ "{ path } does not exist, skipping...") ;
156- }
157- }
158-
159- /// <summary>
160- /// Print information for a single file, if possible
161- /// </summary>
162- /// <param name="file">File path</param>
163- /// <param name="hashTypes">Set of hashes to retrieve</param>
164- /// <param name="debug">Enable debug output</param>
165- private static void PrintFileHashes ( string file , List < HashType > hashTypes , bool debug )
166- {
167- Console . WriteLine ( $ "Attempting to hash { file } , this may take a while...") ;
168- Console . WriteLine ( ) ;
169-
170- // If the file doesn't exist
171- if ( ! File . Exists ( file ) )
172- {
173- Console . WriteLine ( $ "{ file } does not exist, skipping...") ;
174- return ;
175- }
176-
177- try
178- {
179- // Get all file hashes for flexibility
180- var hashes = HashTool . GetFileHashes ( file ) ;
181- if ( hashes == null )
182- {
183- if ( debug ) Console . WriteLine ( $ "Hashes for { file } could not be retrieved") ;
184- return ;
185- }
186-
187- // Output subset of available hashes
188- var builder = new StringBuilder ( ) ;
189- foreach ( HashType hashType in hashTypes )
190- {
191- // TODO: Make helper to pretty-print hash type names
192- if ( hashes . TryGetValue ( hashType , out string ? hash ) && hash != null )
193- builder . AppendLine ( $ "{ hashType } : { hash } ") ;
194- }
195-
196- // Create and print the output data
197- string hashData = builder . ToString ( ) ;
198- Console . WriteLine ( hashData ) ;
199- }
200- catch ( Exception ex )
201- {
202- Console . WriteLine ( debug ? ex : "[Exception opening file, please try again]" ) ;
203- return ;
204- }
205- }
20686 }
20787}
0 commit comments