Skip to content

Commit a6d103a

Browse files
committed
Implement icsharpcode#539
1 parent a1cf337 commit a6d103a

File tree

4 files changed

+40
-101
lines changed

4 files changed

+40
-101
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1+
using System.IO;
2+
13
namespace ICSharpCode.SharpZipLib.Core
24
{
35
/// <summary>
4-
/// WindowsPathUtils provides simple utilities for handling windows paths.
6+
/// PathUtils provides simple utilities for handling paths.
57
/// </summary>
6-
public abstract class WindowsPathUtils
8+
public static class PathUtils
79
{
8-
/// <summary>
9-
/// Initializes a new instance of the <see cref="WindowsPathUtils"/> class.
10-
/// </summary>
11-
internal WindowsPathUtils()
12-
{
13-
}
14-
1510
/// <summary>
1611
/// Remove any path root present in the path
1712
/// </summary>
1813
/// <param name="path">A <see cref="string"/> containing path information.</param>
1914
/// <returns>The path with the root removed if it was present; path otherwise.</returns>
20-
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isnt otherwise checked for validity.</remarks>
15+
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isn't otherwise checked for validity.</remarks>
2116
public static string DropPathRoot(string path)
2217
{
2318
string result = path;
@@ -33,35 +28,48 @@ public static string DropPathRoot(string path)
3328
int elements = 2;
3429

3530
// Scan for two separate elements \\machine\share\restofpath
36-
while ((index <= path.Length) &&
37-
(((path[index] != '\\') && (path[index] != '/')) || (--elements > 0)))
31+
while ((index <= path.Length) && (((path[index] != '\\') && (path[index] != '/')) || (--elements > 0)))
3832
{
3933
index++;
4034
}
4135

4236
index++;
4337

4438
if (index < path.Length)
45-
{
4639
result = path[index..];
47-
}
4840
else
49-
{
5041
result = "";
51-
}
5242
}
5343
}
5444
else if ((path.Length > 1) && (path[1] == ':'))
5545
{
5646
int dropCount = 2;
5747
if ((path.Length > 2) && ((path[2] == '\\') || (path[2] == '/')))
58-
{
5948
dropCount = 3;
60-
}
49+
6150
result = result.Remove(0, dropCount);
6251
}
6352
}
53+
6454
return result;
6555
}
56+
57+
/// <summary>
58+
/// Returns a random file name in the users temporary directory, or in directory of <paramref name="orig"/> if specified
59+
/// </summary>
60+
/// <param name="orig">If specified, used as the base file name for the temporary file</param>
61+
/// <returns>Returns a temporary file name</returns>
62+
public static string GetTempFileName(string orig)
63+
{
64+
string fileName;
65+
var tempPath = Path.GetTempPath();
66+
67+
do
68+
{
69+
fileName = orig == null ? Path.Combine(tempPath, Path.GetRandomFileName()) : $"{orig}.{Path.GetRandomFileName()}";
70+
} while (File.Exists(fileName));
71+
72+
return fileName;
73+
}
6674
}
6775
}

src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public static string MakeValidName(string name, char replacement)
176176
throw new ArgumentNullException(nameof(name));
177177
}
178178

179-
name = WindowsPathUtils.DropPathRoot(name.Replace("/", Path.DirectorySeparatorChar.ToString()));
179+
name = PathUtils.DropPathRoot(name.Replace("/", Path.DirectorySeparatorChar.ToString()));
180180

181181
// Drop any leading slashes.
182182
while ((name.Length > 0) && (name[0] == Path.DirectorySeparatorChar))

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

+11-80
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
10661066
bool testData = (tests & HeaderTest.Extract) != 0;
10671067

10681068
var entryAbsOffset = offsetOfFirstEntry + entry.Offset;
1069-
1069+
10701070
baseStream_.Seek(entryAbsOffset, SeekOrigin.Begin);
10711071
var signature = (int)ReadLEUint();
10721072

@@ -3826,7 +3826,7 @@ private void MakeBytesAvailable()
38263826
/// </summary>
38273827
/// <param name="zipString">The <see cref="ZipString"/> to convert to a string.</param>
38283828
/// <returns>The textual equivalent for the input value.</returns>
3829-
static public implicit operator string(ZipString zipString)
3829+
public static implicit operator string(ZipString zipString)
38303830
{
38313831
zipString.MakeTextAvailable();
38323832
return zipString.comment_;
@@ -4463,7 +4463,7 @@ public interface IArchiveStorage
44634463
/// <summary>
44644464
/// An abstract <see cref="IArchiveStorage"/> suitable for extension by inheritance.
44654465
/// </summary>
4466-
abstract public class BaseArchiveStorage : IArchiveStorage
4466+
public abstract class BaseArchiveStorage : IArchiveStorage
44674467
{
44684468
#region Constructors
44694469

@@ -4577,18 +4577,8 @@ public DiskArchiveStorage(ZipFile file)
45774577
/// <returns>Returns the temporary output stream.</returns>
45784578
public override Stream GetTemporaryOutput()
45794579
{
4580-
if (temporaryName_ != null)
4581-
{
4582-
temporaryName_ = GetTempFileName(temporaryName_, true);
4583-
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
4584-
}
4585-
else
4586-
{
4587-
// Determine where to place files based on internal strategy.
4588-
// Currently this is always done in system temp directory.
4589-
temporaryName_ = Path.GetTempFileName();
4590-
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
4591-
}
4580+
temporaryName_ = PathUtils.GetTempFileName(temporaryName_);
4581+
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write);
45924582

45934583
return temporaryStream_;
45944584
}
@@ -4601,20 +4591,19 @@ public override Stream GetTemporaryOutput()
46014591
public override Stream ConvertTemporaryToFinal()
46024592
{
46034593
if (temporaryStream_ == null)
4604-
{
46054594
throw new ZipException("No temporary stream has been created");
4606-
}
46074595

4608-
string moveTempName = GetTempFileName(fileName_, false);
4596+
string moveTempName = PathUtils.GetTempFileName(fileName_);
46094597
bool newFileCreated = false;
46104598

4611-
46124599
Stream result;
46134600
try
46144601
{
46154602
temporaryStream_.Dispose();
4603+
46164604
File.Move(fileName_, moveTempName);
46174605
File.Move(temporaryName_, fileName_);
4606+
46184607
newFileCreated = true;
46194608
File.Delete(moveTempName);
46204609

@@ -4645,12 +4634,10 @@ public override Stream MakeTemporaryCopy(Stream stream)
46454634
{
46464635
stream.Dispose();
46474636

4648-
temporaryName_ = GetTempFileName(fileName_, true);
4637+
temporaryName_ = PathUtils.GetTempFileName(fileName_);
46494638
File.Copy(fileName_, temporaryName_, true);
46504639

4651-
temporaryStream_ = new FileStream(temporaryName_,
4652-
FileMode.Open,
4653-
FileAccess.ReadWrite);
4640+
temporaryStream_ = new FileStream(temporaryName_, FileMode.Open, FileAccess.ReadWrite);
46544641
return temporaryStream_;
46554642
}
46564643

@@ -4666,18 +4653,12 @@ public override Stream OpenForDirectUpdate(Stream stream)
46664653
if ((stream == null) || !stream.CanWrite)
46674654
{
46684655
if (stream != null)
4669-
{
46704656
stream.Dispose();
4671-
}
46724657

4673-
result = new FileStream(fileName_,
4674-
FileMode.Open,
4675-
FileAccess.ReadWrite);
4658+
result = new FileStream(fileName_, FileMode.Open, FileAccess.ReadWrite);
46764659
}
46774660
else
4678-
{
46794661
result = stream;
4680-
}
46814662

46824663
return result;
46834664
}
@@ -4688,61 +4669,11 @@ public override Stream OpenForDirectUpdate(Stream stream)
46884669
public override void Dispose()
46894670
{
46904671
if (temporaryStream_ != null)
4691-
{
46924672
temporaryStream_.Dispose();
4693-
}
46944673
}
46954674

46964675
#endregion IArchiveStorage Members
46974676

4698-
#region Internal routines
4699-
4700-
private static string GetTempFileName(string original, bool makeTempFile)
4701-
{
4702-
string result = null;
4703-
4704-
if (original == null)
4705-
{
4706-
result = Path.GetTempFileName();
4707-
}
4708-
else
4709-
{
4710-
int counter = 0;
4711-
int suffixSeed = DateTime.Now.Second;
4712-
4713-
while (result == null)
4714-
{
4715-
counter += 1;
4716-
string newName = string.Format("{0}.{1}{2}.tmp", original, suffixSeed, counter);
4717-
if (!File.Exists(newName))
4718-
{
4719-
if (makeTempFile)
4720-
{
4721-
try
4722-
{
4723-
// Try and create the file.
4724-
using (FileStream stream = File.Create(newName))
4725-
{
4726-
}
4727-
result = newName;
4728-
}
4729-
catch
4730-
{
4731-
suffixSeed = DateTime.Now.Second;
4732-
}
4733-
}
4734-
else
4735-
{
4736-
result = newName;
4737-
}
4738-
}
4739-
}
4740-
}
4741-
return result;
4742-
}
4743-
4744-
#endregion Internal routines
4745-
47464677
#region Instance Fields
47474678

47484679
private Stream temporaryStream_;

src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public string TransformFile(string name)
9393
}
9494

9595
name = name.Replace(@"\", "/");
96-
name = WindowsPathUtils.DropPathRoot(name);
96+
name = PathUtils.DropPathRoot(name);
9797

9898
// Drop any leading and trailing slashes.
9999
name = name.Trim('/');
@@ -289,7 +289,7 @@ public string TransformFile(string name)
289289
name = name.Replace(@"\", "/");
290290

291291
// Remove the path root.
292-
name = WindowsPathUtils.DropPathRoot(name);
292+
name = PathUtils.DropPathRoot(name);
293293

294294
// Drop any leading and trailing slashes.
295295
name = name.Trim('/');

0 commit comments

Comments
 (0)