@@ -238,4 +238,76 @@ public static bool IsValidName(string name)
238238
239239 #endregion Class Fields
240240 }
241+
242+ /// <summary>
243+ /// An implementation of INameTransform that transforms entry paths as per the Zip file naming convention.
244+ /// Strips path roots and puts directory separators in the correct format ('/')
245+ /// </summary>
246+ public class PathTransformer : INameTransform
247+ {
248+ /// <summary>
249+ /// Initialize a new instance of <see cref="PathTransformer"></see>
250+ /// </summary>
251+ public PathTransformer ( )
252+ {
253+ }
254+
255+ /// <summary>
256+ /// Transform a windows directory name according to the Zip file naming conventions.
257+ /// </summary>
258+ /// <param name="name">The directory name to transform.</param>
259+ /// <returns>The transformed name.</returns>
260+ public string TransformDirectory ( string name )
261+ {
262+ name = TransformFile ( name ) ;
263+
264+ if ( name . Length > 0 )
265+ {
266+ if ( ! name . EndsWith ( "/" , StringComparison . Ordinal ) )
267+ {
268+ name += "/" ;
269+ }
270+ }
271+ else
272+ {
273+ throw new ZipException ( "Cannot have an empty directory name" ) ;
274+ }
275+
276+ return name ;
277+ }
278+
279+ /// <summary>
280+ /// Transform a windows file name according to the Zip file naming conventions.
281+ /// </summary>
282+ /// <param name="name">The file name to transform.</param>
283+ /// <returns>The transformed name.</returns>
284+ public string TransformFile ( string name )
285+ {
286+ if ( name != null )
287+ {
288+ // Put separators in the expected format.
289+ name = name . Replace ( @"\" , "/" ) ;
290+
291+ // Remove the path root.
292+ name = WindowsPathUtils . DropPathRoot ( name ) ;
293+
294+ // Drop any leading and trailing slashes.
295+ name = name . Trim ( '/' ) ;
296+
297+ // Convert consecutive // characters to /
298+ int index = name . IndexOf ( "//" , StringComparison . Ordinal ) ;
299+ while ( index >= 0 )
300+ {
301+ name = name . Remove ( index , 1 ) ;
302+ index = name . IndexOf ( "//" , StringComparison . Ordinal ) ;
303+ }
304+ }
305+ else
306+ {
307+ name = string . Empty ;
308+ }
309+
310+ return name ;
311+ }
312+ }
241313}
0 commit comments