33using System . Runtime . InteropServices ;
44using System . Text ;
55
6- namespace WebDavContainerExtension . Helpers
6+ namespace WebDavCommon . Helpers
77{
8+ /// <summary>
9+ /// Provides extension methods to read and write extended attributes on file and folders.
10+ /// </summary>
11+ /// <remarks>This class uses file system to store extended attributes in case of alternative data streams not supported.</remarks>
812 public class NSFileManagerHelper
913 {
10- private const string LibsystemKernelDylib = "/usr/lib/system/libsystem_kernel.dylib" ;
14+ /// <summary>The path to system lib.</summary>
15+ private const string LibSystemKernelDylib = "/usr/lib/system/libsystem_kernel.dylib" ;
1116
1217 /// <summary>
1318 /// Errno for not existing attribute.
@@ -19,12 +24,6 @@ public class NSFileManagerHelper
1924 /// </summary>
2025 private const int ErrorMessageBufferMaxSize = 255 ;
2126
22-
23- static NSFileManagerHelper ( )
24- {
25- }
26-
27-
2827 /// <summary>
2928 /// Determines whether extended attributes are supported.
3029 /// </summary>
@@ -33,12 +32,9 @@ static NSFileManagerHelper()
3332 /// <exception cref="ArgumentNullException">Throw when path is null or empty.</exception>
3433 public static bool IsExtendedAttributesSupported ( string path )
3534 {
36- if ( string . IsNullOrEmpty ( path ) )
37- {
38- throw new ArgumentNullException ( nameof ( path ) ) ;
39- }
35+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
4036
41- long attributeCount = ListXAattr ( path , null , 0 , 0 ) ;
37+ long attributeCount = ListXAttr ( path , null , 0 , 0 ) ;
4238 return attributeCount >= 0 ;
4339 }
4440
@@ -52,26 +48,15 @@ public static bool IsExtendedAttributesSupported(string path)
5248 /// <exception cref="IOException">Throw when file or attribute is no available.</exception>
5349 public static string GetExtendedAttribute ( string path , string attrName )
5450 {
55- if ( string . IsNullOrEmpty ( path ) )
56- {
57- throw new ArgumentNullException ( nameof ( path ) ) ;
58- }
59-
60- if ( string . IsNullOrEmpty ( attrName ) )
61- {
62- throw new ArgumentNullException ( nameof ( attrName ) ) ;
63- }
51+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
52+ if ( string . IsNullOrEmpty ( attrName ) ) throw new ArgumentNullException ( nameof ( attrName ) ) ;
6453
6554 byte [ ] buffer = GetExtendedAttributeBytes ( path , attrName ) ;
66- if ( buffer != null )
67- {
68- return Encoding . UTF8 . GetString ( buffer ) ;
69- }
55+ if ( buffer != null ) return Encoding . UTF8 . GetString ( buffer ) ;
7056
7157 return null ;
7258 }
7359
74-
7560 /// <summary>
7661 /// Reads extended attribute as <see cref="T:byte[]" />.
7762 /// </summary>
@@ -82,34 +67,21 @@ public static string GetExtendedAttribute(string path, string attrName)
8267 /// <exception cref="IOException">Throw when file or attribute is no available.</exception>
8368 public static byte [ ] GetExtendedAttributeBytes ( string path , string attrName )
8469 {
85- if ( string . IsNullOrEmpty ( path ) )
86- {
87- throw new ArgumentNullException ( nameof ( path ) ) ;
88- }
89-
90- if ( string . IsNullOrEmpty ( attrName ) )
91- {
92- throw new ArgumentNullException ( nameof ( attrName ) ) ;
93- }
70+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
71+ if ( string . IsNullOrEmpty ( attrName ) ) throw new ArgumentNullException ( nameof ( attrName ) ) ;
9472
9573 long attributeSize = GetXAttr ( path , attrName , null , 0 , 0 , 0 ) ;
9674 if ( attributeSize == - 1 )
9775 {
98- if ( Marshal . GetLastWin32Error ( ) == AttributeNotFoundErrno )
99- {
100- return null ;
101- }
76+ if ( Marshal . GetLastWin32Error ( ) == AttributeNotFoundErrno ) return null ;
10277
10378 ThrowLastException ( path , attrName ) ;
10479 }
10580
106- byte [ ] buffer = new byte [ attributeSize ] ;
81+ var buffer = new byte [ attributeSize ] ;
10782 long readLength = GetXAttr ( path , attrName , buffer , attributeSize , 0 , 0 ) ;
10883
109- if ( readLength == - 1 )
110- {
111- ThrowLastException ( path , attrName ) ;
112- }
84+ if ( readLength == - 1 ) ThrowLastException ( path , attrName ) ;
11385
11486 return buffer ;
11587 }
@@ -124,21 +96,13 @@ public static byte[] GetExtendedAttributeBytes(string path, string attrName)
12496 /// <exception cref="IOException">Throw when file or attribute is no available.</exception>
12597 public static void SetExtendedAttribute ( string path , string attrName , string attrValue )
12698 {
127- if ( string . IsNullOrEmpty ( path ) )
128- {
129- throw new ArgumentNullException ( nameof ( path ) ) ;
130- }
131-
132- if ( string . IsNullOrEmpty ( attrName ) )
133- {
134- throw new ArgumentNullException ( nameof ( attrName ) ) ;
135- }
99+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
100+ if ( string . IsNullOrEmpty ( attrName ) ) throw new ArgumentNullException ( nameof ( attrName ) ) ;
136101
137102 byte [ ] buffer = Encoding . UTF8 . GetBytes ( attrValue ) ;
138103 SetExtendedAttributeBytes ( path , attrName , buffer ) ;
139104 }
140105
141-
142106 /// <summary>
143107 /// Writes extended attribute as <see cref="T:byte[]" />.
144108 /// </summary>
@@ -149,21 +113,11 @@ public static void SetExtendedAttribute(string path, string attrName, string att
149113 /// <exception cref="IOException">Throw when file or attribute is no available.</exception>
150114 public static void SetExtendedAttributeBytes ( string path , string attrName , byte [ ] buffer )
151115 {
152- if ( string . IsNullOrEmpty ( path ) )
153- {
154- throw new ArgumentNullException ( nameof ( path ) ) ;
155- }
156-
157- if ( string . IsNullOrEmpty ( attrName ) )
158- {
159- throw new ArgumentNullException ( nameof ( attrName ) ) ;
160- }
116+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
117+ if ( string . IsNullOrEmpty ( attrName ) ) throw new ArgumentNullException ( nameof ( attrName ) ) ;
161118
162119 long result = SetXAttr ( path , attrName , buffer , buffer . Length , 0 , 0 ) ;
163- if ( result == - 1 )
164- {
165- ThrowLastException ( path , attrName ) ;
166- }
120+ if ( result == - 1 ) ThrowLastException ( path , attrName ) ;
167121 }
168122
169123 /// <summary>
@@ -173,29 +127,19 @@ public static void SetExtendedAttributeBytes(string path, string attrName, byte[
173127 /// <param name="attrName">Attribute name.</param>
174128 public static void DeleteExtendedAttribute ( string path , string attrName )
175129 {
176- if ( string . IsNullOrEmpty ( path ) )
177- {
178- throw new ArgumentNullException ( nameof ( path ) ) ;
179- }
180-
181- if ( string . IsNullOrEmpty ( attrName ) )
182- {
183- throw new ArgumentNullException ( nameof ( attrName ) ) ;
184- }
130+ if ( string . IsNullOrEmpty ( path ) ) throw new ArgumentNullException ( nameof ( path ) ) ;
131+ if ( string . IsNullOrEmpty ( attrName ) ) throw new ArgumentNullException ( nameof ( attrName ) ) ;
185132
186133 long result = RemoveXAttr ( path , attrName , 0 ) ;
187- if ( result == - 1 )
188- {
189- ThrowLastException ( path , attrName ) ;
190- }
134+ if ( result == - 1 ) ThrowLastException ( path , attrName ) ;
191135 }
192136
193137 /// <summary>
194138 /// Throws corresponding exception for last platform api call.
195139 /// </summary>
196140 /// <param name="fileName">File name.</param>
197141 /// <param name="attrName">Attribute name.</param>
198- /// <exception cref="System.IO.IOException"></exception>
142+ /// <exception cref="System.IO.IOException"> if IO error occured. </exception>
199143 private static void ThrowLastException ( string fileName , string attrName )
200144 {
201145 int errno = Marshal . GetLastWin32Error ( ) ; // It returns glibc errno
@@ -225,8 +169,14 @@ private static string GetMessageForErrno(int errno)
225169 /// <param name="position">Position value.</param>
226170 /// <param name="options">Options value.</param>
227171 /// <returns>Attribute value size in bytes, when returning value -1 than some error occurred./// </returns>
228- [ DllImport ( LibsystemKernelDylib , EntryPoint = "getxattr" , SetLastError = true ) ]
229- private static extern long GetXAttr ( string filePath , string attrName , byte [ ] buffer , long bufferSize , long position , int options ) ;
172+ [ DllImport ( LibSystemKernelDylib , EntryPoint = "getxattr" , SetLastError = true ) ]
173+ private static extern long GetXAttr (
174+ string filePath ,
175+ string attrName ,
176+ byte [ ] buffer ,
177+ long bufferSize ,
178+ long position ,
179+ int options ) ;
230180
231181 /// <summary>
232182 /// External func setxattr from libc, sets attribute value for file by name.
@@ -238,8 +188,14 @@ private static string GetMessageForErrno(int errno)
238188 /// <param name="position">Position value.</param>
239189 /// <param name="options">Options value.</param>
240190 /// <returns>Status, when returning value -1 than some error occurred.</returns>
241- [ DllImport ( LibsystemKernelDylib , EntryPoint = "setxattr" , SetLastError = true ) ]
242- private static extern long SetXAttr ( string filePath , string attrName , byte [ ] attrValue , long size , long position , int options ) ;
191+ [ DllImport ( LibSystemKernelDylib , EntryPoint = "setxattr" , SetLastError = true ) ]
192+ private static extern long SetXAttr (
193+ string filePath ,
194+ string attrName ,
195+ byte [ ] attrValue ,
196+ long size ,
197+ long position ,
198+ int options ) ;
243199
244200 /// <summary>
245201 /// Removes the extended attribute.
@@ -248,7 +204,7 @@ private static string GetMessageForErrno(int errno)
248204 /// <param name="attrName">Attribute name.</param>
249205 /// <param name="options">Options value.</param>
250206 /// <returns>On success, zero is returned. On failure, -1 is returned.</returns>
251- [ DllImport ( LibsystemKernelDylib , EntryPoint = "removexattr" , SetLastError = true ) ]
207+ [ DllImport ( LibSystemKernelDylib , EntryPoint = "removexattr" , SetLastError = true ) ]
252208 private static extern long RemoveXAttr ( string path , string attrName , int options ) ;
253209
254210 /// <summary>
@@ -259,16 +215,15 @@ private static string GetMessageForErrno(int errno)
259215 /// <param name="size">Buffer size</param>
260216 /// <param name="options">Options value.</param>
261217 /// <returns>Attributes bytes array size, when returning value -1 than some error occurred</returns>
262- [ DllImport ( LibsystemKernelDylib , EntryPoint = "listxattr" , SetLastError = true ) ]
263- private static extern long ListXAattr ( string filePath , StringBuilder nameBuffer , long size , int options ) ;
218+ [ DllImport ( LibSystemKernelDylib , EntryPoint = "listxattr" , SetLastError = true ) ]
219+ private static extern long ListXAttr ( string filePath , StringBuilder nameBuffer , long size , int options ) ;
264220
265- /// <summary>
266- /// External func strerror_r from libc, what returns string that describes the error code passed in the argument.
267- /// </summary>
221+ /// <summary>External func strerror_r from libc, what returns string that describes the error code passed in the argument.</summary>
268222 /// <param name="code">Error number.</param>
269223 /// <param name="buffer">Destination buffer.</param>
270224 /// <param name="bufferSize">Buffer size.</param>
271- [ DllImport ( LibsystemKernelDylib , EntryPoint = "strerror_r" , SetLastError = true ) ]
225+ /// <returns>The <see cref="IntPtr"/>.</returns>
226+ [ DllImport ( LibSystemKernelDylib , EntryPoint = "strerror_r" , SetLastError = true ) ]
272227 private static extern IntPtr StrErrorR ( int code , StringBuilder buffer , int bufferSize ) ;
273228 }
274- }
229+ }
0 commit comments