@@ -29,6 +29,11 @@ internal sealed class MainFeature : Feature
2929 private const string _fileOnlyName = "file-only" ;
3030 internal readonly FlagInput FileOnlyInput = new ( _fileOnlyName , [ "-f" , "--file" ] , "Print to file only" ) ;
3131
32+ #if NETCOREAPP
33+ private const string _jsonName = "json" ;
34+ internal readonly FlagInput JsonInput = new ( _jsonName , [ "-j" , "--json" ] , "Output to json file" ) ;
35+ #endif
36+
3237 private const string _noArchivesName = "no-archives" ;
3338 internal readonly FlagInput NoArchivesInput = new ( _noArchivesName , [ "-na" , "--no-archives" ] , "Disable scanning archives" ) ;
3439
@@ -47,6 +52,11 @@ internal sealed class MainFeature : Feature
4752 /// Output information to file only, skip printing to console
4853 /// </summary>
4954 public bool FileOnly { get ; private set ; }
55+
56+ /// <summary>
57+ /// Output information to json
58+ /// </summary>
59+ public bool JsonFlag { get ; private set ; }
5060
5161 public MainFeature ( )
5262 : base ( DisplayName , _flags , _description )
@@ -55,6 +65,9 @@ public MainFeature()
5565
5666 Add ( DebugInput ) ;
5767 Add ( FileOnlyInput ) ;
68+ #if NETCOREAPP
69+ Add ( JsonInput ) ;
70+ #endif
5871 Add ( NoContentsInput ) ;
5972 Add ( NoArchivesInput ) ;
6073 Add ( NoPathsInput ) ;
@@ -70,6 +83,9 @@ public override bool Execute()
7083
7184 // Get the options from the arguments
7285 FileOnly = GetBoolean ( _fileOnlyName ) ;
86+ #if NETCOREAPP
87+ JsonFlag = GetBoolean ( _jsonName ) ;
88+ #endif
7389
7490 // Create scanner for all paths
7591 var scanner = new Scanner (
@@ -127,7 +143,12 @@ private void GetAndWriteProtections(Scanner scanner, string path)
127143 try
128144 {
129145 var protections = scanner . GetProtections ( path ) ;
146+
130147 WriteProtectionResultFile ( path , protections ) ;
148+
149+ #if NETCOREAPP
150+ WriteProtectionResultJson ( path , protections ) ;
151+ #endif
131152 }
132153 catch ( Exception ex )
133154 {
@@ -199,5 +220,45 @@ private void WriteProtectionResultFile(string path, Dictionary<string, List<stri
199220 // Dispose of the writer
200221 sw ? . Dispose ( ) ;
201222 }
223+
224+ #if NETCOREAPP
225+ /// <summary>
226+ /// Write the protection results from a single path to a json file, if possible
227+ /// </summary>
228+ /// <param name="path">File or directory path</param>
229+ /// <param name="protections">Dictionary of protections found, if any</param>
230+ private static void WriteProtectionResultJson ( string path , Dictionary < string , List < string > > protections )
231+ {
232+ if ( protections == null )
233+ {
234+ Console . WriteLine ( $ "No protections found for { path } ") ;
235+ return ;
236+ }
237+
238+ // Attempt to open a protection file for writing
239+ StreamWriter ? jsw = null ;
240+ try
241+ {
242+ jsw = new StreamWriter ( File . OpenWrite ( $ "protection-{ DateTime . Now : yyyy-MM-dd_HHmmss.ffff} .json") ) ;
243+ // Create the output data
244+ string serializedData = System . Text . Json . JsonSerializer . Serialize ( protections , JsonSerializerOptions ) ;
245+
246+ // Write the output data
247+ // TODO: this prints plus symbols wrong, probably some other things too
248+ jsw ? . WriteLine ( serializedData ) ;
249+ jsw ? . Flush ( ) ;
250+
251+ // Dispose of the writer
252+ jsw ? . Dispose ( ) ;
253+ }
254+ catch { }
255+ }
256+
257+ /// <summary>
258+ /// JSON serializer options for output printing
259+ /// </summary>
260+ private static System . Text . Json . JsonSerializerOptions JsonSerializerOptions
261+ => new System . Text . Json . JsonSerializerOptions { WriteIndented = true } ;
262+ #endif
202263 }
203264}
0 commit comments