1- using Newtonsoft . Json ;
1+ using System ;
2+ using Newtonsoft . Json ;
23using System . IO ;
34using System . Threading . Tasks ;
45using Windows . Storage ;
78using ClipboardCanvas . Exceptions ;
89using ClipboardCanvas . Helpers . Filesystem ;
910using ClipboardCanvas . Helpers . SafetyHelpers ;
10- using System ;
11+ using ClipboardCanvas . UnsafeNative ;
1112
1213namespace ClipboardCanvas . ReferenceItems
1314{
@@ -30,12 +31,57 @@ private ReferenceFile(StorageFile innerFile, IStorageItem referencedItem)
3031 this . ReferencedItem = referencedItem ;
3132 }
3233
33- public async Task < SafeWrapperResult > UpdateReference ( string newPath )
34+ /// <summary>
35+ /// Updates the underlying file and fileData
36+ /// </summary>
37+ /// <param name="newPath"></param>
38+ /// <returns></returns>
39+ private async Task < SafeWrapperResult > UpdateReference ( string newPath , bool regenerateReferenceItem )
3440 {
35- _referenceFileData = new ReferenceFileData ( newPath ) ;
41+ if ( ! StorageHelpers . Existsh ( newPath ) )
42+ {
43+ return new SafeWrapperResult ( OperationErrorCode . NotFound , new FileNotFoundException ( ) , "File does not exist." ) ;
44+ }
45+
46+ long fileId = UnsafeNativeHelpers . GetFileId ( newPath ) ;
47+ bool isRepairable = fileId != - 1 ;
48+
49+ _referenceFileData = new ReferenceFileData ( newPath , fileId , isRepairable ) ;
3650 string serialized = JsonConvert . SerializeObject ( _referenceFileData , Formatting . Indented ) ;
3751
38- return await FilesystemOperations . WriteFileText ( _innerReferenceFile , serialized ) ;
52+ SafeWrapperResult writeFileTextResult = await FilesystemOperations . WriteFileText ( _innerReferenceFile , serialized ) ;
53+ if ( ! writeFileTextResult )
54+ {
55+ return writeFileTextResult ;
56+ }
57+
58+ if ( regenerateReferenceItem )
59+ {
60+ SafeWrapper < IStorageItem > referencedItem = await StorageHelpers . ToStorageItemWithError < IStorageItem > ( newPath ) ;
61+ this . ReferencedItem = referencedItem . Result ;
62+
63+ return referencedItem ;
64+ }
65+
66+ return SafeWrapperResult . SUCCESS ;
67+ }
68+
69+ public static async Task < ReferenceFile > CreateReferenceFileFromFile ( StorageFile emptyReferenceFile , IStorageItem referencedItem )
70+ {
71+ if ( ! FileHelpers . IsPathEqualExtension ( emptyReferenceFile . Path , Constants . FileSystem . REFERENCE_FILE_EXTENSION ) )
72+ {
73+ return new ReferenceFile ( emptyReferenceFile , null )
74+ {
75+ LastError = new SafeWrapperResult ( OperationErrorCode . InvalidArgument , new ArgumentException ( ) , "Empty file uses invalid Reference File extension." )
76+ } ;
77+ }
78+
79+ ReferenceFile referenceFile = new ReferenceFile ( emptyReferenceFile , referencedItem ) ;
80+
81+ SafeWrapperResult result = await referenceFile . UpdateReference ( referencedItem . Path , false ) ;
82+ referenceFile . LastError = result ;
83+
84+ return referenceFile ;
3985 }
4086
4187 private static async Task < SafeWrapper < ReferenceFileData > > ReadData ( StorageFile referenceFile )
@@ -50,26 +96,48 @@ private static async Task<SafeWrapper<ReferenceFileData>> ReadData(StorageFile r
5096 return ( referenceFileData , SafeWrapperResult . SUCCESS ) ;
5197 }
5298
53- public static async Task < ReferenceFile > GetReferenceFile ( StorageFile referenceFile )
99+ public static async Task < ReferenceFile > GetReferenceFile ( StorageFile file )
54100 {
55101 // The file is not a Reference File
56- if ( ! IsReferenceFile ( referenceFile ) )
102+ if ( ! IsReferenceFile ( file ) )
57103 {
58104 return null ;
59105 }
60106
61- // The file does not exist
62- if ( ! StorageHelpers . Existsh ( referenceFile . Path ) )
107+ // The referenceFile does not exist
108+ if ( ! StorageHelpers . Existsh ( file . Path ) )
63109 {
64- return new ReferenceFile ( referenceFile , null )
110+ return new ReferenceFile ( file , null )
65111 {
66112 LastError = new SafeWrapperResult ( OperationErrorCode . NotFound , new FileNotFoundException ( ) , "Couldn't resolve item associated with path." )
67113 } ;
68114 }
69115
70- SafeWrapper < ReferenceFileData > referenceFileData = await ReadData ( referenceFile ) ;
116+ SafeWrapper < ReferenceFileData > referenceFileData = await ReadData ( file ) ;
117+
118+ ReferenceFile referenceFile = await GetFile ( file , referenceFileData ) ;
119+ if ( referenceFile . LastError )
120+ {
121+ if ( ! referenceFileData . Result . isRepairable ) // Bad FileId but the path is correct
122+ {
123+ // Repair the FileId
124+ await referenceFile . UpdateReference ( referenceFileData . Result . path , false ) ;
125+ }
126+ }
127+ else
128+ {
129+ if ( referenceFile . LastError == OperationErrorCode . InvalidArgument || referenceFile . LastError == OperationErrorCode . NotFound )
130+ {
131+ if ( referenceFileData . Result ? . isRepairable ?? false )
132+ {
133+ // Repair it
134+ SafeWrapperResult result = await RepairReferenceFile ( referenceFile , referenceFileData ) ;
135+ referenceFile . LastError = result ;
136+ }
137+ }
138+ }
71139
72- return await GetFile ( referenceFile , referenceFileData ) ;
140+ return referenceFile ;
73141 }
74142
75143 private static async Task < ReferenceFile > GetFile ( StorageFile referenceFile , SafeWrapper < ReferenceFileData > referenceFileData )
@@ -116,6 +184,21 @@ private static async Task<ReferenceFile> GetFile(StorageFile referenceFile, Safe
116184 } ;
117185 }
118186
187+ private static async Task < SafeWrapperResult > RepairReferenceFile ( ReferenceFile referenceFile , ReferenceFileData referenceFileData )
188+ {
189+ if ( referenceFileData . fileId == - 1 )
190+ {
191+ return referenceFile . LastError ;
192+ }
193+
194+ // Get path from FileId...
195+
196+ // TODO: Implement that when it becomes possible
197+
198+ // for now, return the error
199+ return referenceFile . LastError ;
200+ }
201+
119202 public static bool IsReferenceFile ( StorageFile file )
120203 {
121204 return FileHelpers . IsPathEqualExtension ( file ? . Path , Constants . FileSystem . REFERENCE_FILE_EXTENSION ) ;
0 commit comments