diff --git a/DTLib.Tests/DTLib.Tests.csproj b/DTLib.Tests/DTLib.Tests.csproj
index 3b2c8ac..7ab9453 100644
--- a/DTLib.Tests/DTLib.Tests.csproj
+++ b/DTLib.Tests/DTLib.Tests.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/DTLib.Tests/Program.cs b/DTLib.Tests/Program.cs
index d058ea8..eff8654 100644
--- a/DTLib.Tests/Program.cs
+++ b/DTLib.Tests/Program.cs
@@ -30,6 +30,18 @@ public static class Program
try
{
+ string path = "file";
+ string path2 = path + "_temp";
+ // Ensure that the target does not exist.
+ File.Delete(path2);
+ // Copy the file.
+ File.Copy(path, path2);
+ System.Console.WriteLine("{0} was copied to {1}.", path, path2);
+ // Delete the newly created file.
+ File.Delete(path2);
+ System.Console.WriteLine("{0} was successfully deleted.", path2);
+ return;
+
new LaunchArgumentParser().WithNoExit().ParseAndHandle(args);
TestPInvoke.TestAll();
TestAutoarr.TestAll();
diff --git a/DTLib/Console/LaunchArgumentParser.cs b/DTLib/Console/LaunchArgumentParser.cs
index 09ef953..14b3bd8 100644
--- a/DTLib/Console/LaunchArgumentParser.cs
+++ b/DTLib/Console/LaunchArgumentParser.cs
@@ -108,7 +108,8 @@ public class LaunchArgumentParser
if (i+1 >= args.Length)
throw new Exception($"argument <{args[i]}> should have a parameter after it");
i++; // next arg
- arg.Handler = () => arg.HandlerWithArg(args[i]);
+ var i1 = i;
+ arg.Handler = () => arg.HandlerWithArg(args[i1]);
}
else if (arg.Handler is null) throw new NullReferenceException($"argument <{args[i]}> hasn't got any handlers");
diff --git a/DTLib/DTLib.csproj b/DTLib/DTLib.csproj
index 48b76c8..6519210 100644
--- a/DTLib/DTLib.csproj
+++ b/DTLib/DTLib.csproj
@@ -2,7 +2,7 @@
DTLib
- 1.0.4
+ 1.0.5
Timerix
Library for all my C# projects
GIT
diff --git a/DTLib/Experimental/Reactive/ReactiveStream.cs b/DTLib/Experimental/Reactive/ReactiveStream.cs
index 0c95923..0021cdc 100644
--- a/DTLib/Experimental/Reactive/ReactiveStream.cs
+++ b/DTLib/Experimental/Reactive/ReactiveStream.cs
@@ -1,9 +1,7 @@
namespace DTLib.Experimental.Reactive
{
- public class ReactiveStream : IEnumerable>, IList>
+ public class ReactiveStream : IList>
{
- public ReactiveStream() { }
-
List> _storage = new();
List> Storage
{
diff --git a/DTLib/Extensions/BaseConverter.cs b/DTLib/Extensions/BaseConverter.cs
index 297140f..418f86d 100644
--- a/DTLib/Extensions/BaseConverter.cs
+++ b/DTLib/Extensions/BaseConverter.cs
@@ -24,12 +24,12 @@ public static class BaseConverter
public static uint ToUInt(this T input) => Convert.ToUInt32(input);
public static long ToLong(this T input) => Convert.ToInt64(input);
public static ulong ToULong(this T input) => Convert.ToUInt64(input);
- public static float ToFloat(this string input) => float.Parse(input, NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture);
+ public static float ToFloat(this string input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture);
#if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
- public static float ToFloat(this ReadOnlySpan input) => float.Parse(input, NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture);
+ public static float ToFloat(this ReadOnlySpan input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture);
#endif
- public static double ToDouble(this T input) => Convert.ToDouble(input, System.Globalization.CultureInfo.InvariantCulture);
- public static decimal ToDecimal(this T input) => Convert.ToDecimal(input, System.Globalization.CultureInfo.InvariantCulture);
+ public static double ToDouble(this T input) => Convert.ToDouble(input, CultureInfo.InvariantCulture);
+ public static decimal ToDecimal(this T input) => Convert.ToDecimal(input, CultureInfo.InvariantCulture);
public static int ToInt(this byte[] bytes)
{
diff --git a/DTLib/Extensions/SpanHelper.cs b/DTLib/Extensions/SpanHelper.cs
index 6a3fbeb..72cb4de 100644
--- a/DTLib/Extensions/SpanHelper.cs
+++ b/DTLib/Extensions/SpanHelper.cs
@@ -1,6 +1,6 @@
+#if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
namespace DTLib.Extensions;
-#if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
public static class SpanHelper
{
public static ReadOnlySpan After(this ReadOnlySpan span, T c) where T : IEquatable
diff --git a/DTLib/Filesystem/Directory.cs b/DTLib/Filesystem/Directory.cs
index e446d4d..c2fc351 100644
--- a/DTLib/Filesystem/Directory.cs
+++ b/DTLib/Filesystem/Directory.cs
@@ -2,56 +2,85 @@
public static class Directory
{
- public static bool Exists(string dir) => System.IO.Directory.Exists(Path.FixSeparators(dir));
+ public static bool Exists(string dir, bool separatorsFixed)
+ {
+ if(!separatorsFixed)
+ dir = Path.FixSeparators(dir);
+ return System.IO.Directory.Exists(dir);
+ }
/// создает папку, если её не существует
- public static void Create(string dir)
+ public static void Create(string dir, bool separatorsFixed)
{
- dir = Path.FixSeparators(dir);
+ if(!separatorsFixed)
+ dir = Path.FixSeparators(dir);
if (!Exists(dir))
{
// проверяет существование папки, в которой нужно создать dir
- if (dir.Contains(Path.Sep) && !Exists(dir.Remove(dir.LastIndexOf(Path.Sep))))
- Create(dir.Remove(dir.LastIndexOf(Path.Sep)));
- System.IO.Directory.CreateDirectory(dir);
+ if (dir.Contains(Path.Sep))
+ {
+ string parentDir = dir.Remove(dir.LastIndexOf(Path.Sep));
+ if(!Exists(parentDir,true))
+ Create(parentDir,true);
+ }
+ else System.IO.Directory.CreateDirectory(dir);
}
}
/// копирует все файлы и папки
- public static void Copy(string source_dir, string new_dir, bool owerwrite = false)
+ public static void Copy(string source_dir, string new_dir, bool owerwrite)
{
- Create(new_dir);
- var subdirs = new List();
- List files = GetAllFiles(source_dir, ref subdirs);
- for (int i = 0; i < subdirs.Count; i++)
- Create(subdirs[i].Replace(source_dir, new_dir));
- for (int i = 0; i < files.Count; i++)
- File.Copy(files[i], files[i].Replace(source_dir, new_dir), owerwrite);
+ Copy_internal(source_dir, new_dir, owerwrite, null);
}
/// копирует все файлы и папки и выдаёт список конфликтующих файлов
- public static void Copy(string source_dir, string new_dir, out List conflicts, bool owerwrite = false)
+ public static void Copy(string source_dir, string new_dir, bool owerwrite, out List conflicts)
{
conflicts = new List();
- var subdirs = new List();
- List files = GetAllFiles(source_dir, ref subdirs);
+ Copy_internal(source_dir, new_dir, owerwrite, conflicts);
+ }
+
+ private static void Copy_internal(string source_dir, string new_dir, bool owerwrite, List conflicts)
+ {
+ bool countConflicts = conflicts is null;
+ List files = GetAllFiles(source_dir);
Create(new_dir);
- for (int i = 0; i < subdirs.Count; i++)
- Create(subdirs[i].Replace(source_dir, new_dir));
for (int i = 0; i < files.Count; i++)
{
- string newfile = files[i].Replace(source_dir, new_dir);
- if (File.Exists(newfile))
- conflicts.Add(newfile);
+ string newfile = Path.ReplaceBase(files[i], source_dir, new_dir);
+ if (countConflicts && File.Exists(newfile))
+ conflicts!.Add(newfile);
File.Copy(files[i], newfile, owerwrite);
}
}
/// удаляет папку со всеми подпапками и файлами
- public static void Delete(string dir) => System.IO.Directory.Delete(Path.FixSeparators(dir), true);
+ public static void Delete(string dir, bool separatorsFixed)
+ {
+ if(!separatorsFixed)
+ dir = Path.FixSeparators(dir);
+ System.IO.Directory.Delete(dir, true);
+ }
- public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(Path.FixSeparators(dir));
- public static string[] GetFiles(string dir, string searchPattern) => System.IO.Directory.GetFiles(Path.FixSeparators(dir), searchPattern);
- public static string[] GetDirectories(string dir) => System.IO.Directory.GetDirectories(Path.FixSeparators(dir));
+ public static string[] GetFiles(string dir, bool separatorsFixed)
+ {
+ if (!separatorsFixed)
+ dir = Path.FixSeparators(dir);
+ return System.IO.Directory.GetFiles(dir);
+ }
+
+ public static string[] GetFiles(string dir, string searchPattern, bool separatorsFixed)
+ {
+ if (!separatorsFixed)
+ dir = Path.FixSeparators(dir);
+ return System.IO.Directory.GetFiles(dir, searchPattern);
+ }
+
+ public static string[] GetDirectories(string dir, bool separatorsFixed)
+ {
+ if (!separatorsFixed)
+ dir = Path.FixSeparators(dir);
+ return System.IO.Directory.GetDirectories(dir);
+ }
/// выдает список всех файлов
public static List GetAllFiles(string dir)
@@ -84,13 +113,15 @@ public static class Directory
public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory();
- public static void CreateSymlink(string sourceName, string symlinkName)
+ public static void CreateSymlink(string sourcePath, string symlinkPath, bool separatorsFixed)
{
- sourceName = Path.FixSeparators(sourceName);
- symlinkName = Path.FixSeparators(symlinkName);
- if (symlinkName.Contains(Path.Sep))
- Create(symlinkName.Remove(symlinkName.LastIndexOf(Path.Sep)));
- if (!Symlink.CreateSymbolicLink(symlinkName, sourceName, Symlink.SymlinkTarget.Directory))
- throw new InvalidOperationException($"some error occured while creating symlink\nDirectory.CreateSymlink({symlinkName}, {sourceName})");
+ if (!separatorsFixed)
+ {
+ sourcePath = Path.FixSeparators(sourcePath);
+ symlinkPath = Path.FixSeparators(symlinkPath);
+ }
+ Create(Path.ParentDir(symlinkPath, true), true);
+ if (!Symlink.CreateSymbolicLink(symlinkPath, sourcePath, Symlink.SymlinkTarget.Directory))
+ throw new InvalidOperationException($"some error occured while creating symlink\nDirectory.CreateSymlink({symlinkPath}, {sourcePath})");
}
}
diff --git a/DTLib/Filesystem/File.cs b/DTLib/Filesystem/File.cs
index 4a107a7..ad1a26c 100644
--- a/DTLib/Filesystem/File.cs
+++ b/DTLib/Filesystem/File.cs
@@ -1,33 +1,55 @@
-
-namespace DTLib.Filesystem;
+namespace DTLib.Filesystem;
public static class File
{
/// возвращает размер файла в байтах
- public static long GetSize(string file) => new System.IO.FileInfo(Path.FixSeparators(file)).Length;
+ public static long GetSize(string file, bool separatorsFixed)
+ {
+ if (!separatorsFixed)
+ file = Path.FixSeparators(file);
+ return new System.IO.FileInfo(file).Length;
+ }
- public static bool Exists(string file) => System.IO.File.Exists(Path.FixSeparators(file));
+ public static bool Exists(string file, bool separatorsFixed)
+ {
+ if (!separatorsFixed)
+ file = Path.FixSeparators(file);
+ return System.IO.File.Exists(file);
+ }
/// если файл не существует, создаёт файл с папками из его пути и закрывает этот фвйл
- public static void Create(string file)
+ public static void Create(string file, bool separatorsFixed)
{
- file = Path.FixSeparators(file);
- if (!Exists(file))
+ if (!separatorsFixed)
+ file = Path.FixSeparators(file);
+ if (!Exists(file, true))
{
- if (file.Contains(Path.Sep))
- Directory.Create(file.Remove(file.LastIndexOf(Path.Sep)));
+ Directory.Create(Path.ParentDir(file, true), true);
using System.IO.FileStream stream = System.IO.File.Create(file);
stream.Close();
}
}
- public static void Copy(string srcPath, string newPath, bool overwrite = false)
+ public static void Copy(string srcPath, string newPath, bool overwrite = false, bool separatorsFixed)
{
- srcPath = Path.FixSeparators(srcPath);
- newPath = Path.FixSeparators(newPath);
- if (!overwrite && Exists(newPath))
- throw new Exception($"file <{newPath}> alredy exists");
- System.IO.File.Copy(srcPath, newPath, overwrite);
+ if (!separatorsFixed)
+ {
+ srcPath = Path.FixSeparators(srcPath);
+ newPath = Path.FixSeparators(newPath);
+ }
+
+ if (Exists(newPath))
+ {
+ if(overwrite) System.IO.File.Delete(newPath);
+ else throw new Exception($"file <{newPath}> alredy exists");
+ }
+ else Directory.Create(Path.ParentDir(newPath, true));
+ using var srcFile=System.IO.File.Open(srcPath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
+ using var newFile=System.IO.File.Open(newPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
+ srcFile.CopyTo(newFile);
+ srcFile.Close();
+ newFile.Flush();
+ newFile.Close();
}
public static void Delete(string file) => System.IO.File.Delete(Path.FixSeparators(file));
@@ -70,8 +92,7 @@ public static class File
{
file = Path.FixSeparators(file);
if (Exists(file))
- return System.IO.File.Open(file, System.IO.FileMode.Open, System.IO.FileAccess.Read,
- System.IO.FileShare.ReadWrite);
+ return System.IO.File.Open(file, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
throw new Exception($"file not found: <{file}>");
}
diff --git a/DTLib/Filesystem/Path.cs b/DTLib/Filesystem/Path.cs
index 864fd4e..9fa8620 100644
--- a/DTLib/Filesystem/Path.cs
+++ b/DTLib/Filesystem/Path.cs
@@ -8,11 +8,30 @@ public static class Path
public static readonly char Sep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '\\' : '/';
private static readonly char NotSep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '/' : '\\' ;
+ /// does not correct separators, use Resolve for correction
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static string Concat(string path, string addition) => $"{path}{Sep}{addition}";
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static string Concat(params string[] parts) => StringConverter.MergeToString(Sep, parts);
+ public static string Concat(string path, string addition)
+ {
+ if (!path.EndsWith(Sep) && !addition.StartsWith(Sep))
+ path += Sep;
+ return path + addition;
+ }
+
+ ///
+ public static string Concat(params string[] parts)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(parts[0]);
+ for (int i = 1; i < parts.Length; i++)
+ {
+ char lastC = builder[builder.Length - 1];
+ if(lastC!=Sep && lastC!=NotSep)
+ builder.Append(Sep);
+ builder.Append(parts[i]);
+ }
+ return builder.ToString();
+ }
public static string FixSeparators(string path)
{
@@ -21,7 +40,7 @@ public static class Path
for(int i=0; i doesnt starts with <{baseDir}");
+ return Concat(otherDir, path.Substring(baseDir.Length));
+ }
}
\ No newline at end of file
diff --git a/DTLib/Hasher.cs b/DTLib/Hasher.cs
index 204e28b..ac200da 100644
--- a/DTLib/Hasher.cs
+++ b/DTLib/Hasher.cs
@@ -10,8 +10,6 @@ public class Hasher
readonly HashAlgorithm sha256 = SHA256.Create();
readonly HashAlgorithm xxh32 = XXHash32.Create();
- public Hasher() { }
-
// хеш массива
public byte[] Hash(byte[] input) => sha256.ComputeHash(input);
diff --git a/DTLib/XXHash.cs b/DTLib/XXHash.cs
index c232ffd..9d081ec 100644
--- a/DTLib/XXHash.cs
+++ b/DTLib/XXHash.cs
@@ -27,7 +27,7 @@ sealed class XXHash32 : HashAlgorithm
{
if (BitConverter.IsLittleEndian)
{
- FuncGetLittleEndianUInt32 = new Func((x, i) =>
+ FuncGetLittleEndianUInt32 = (x, i) =>
{
unsafe
{
@@ -36,12 +36,12 @@ sealed class XXHash32 : HashAlgorithm
return *(uint*)(array + i);
}
}
- });
- FuncGetFinalHashUInt32 = new Func(i => (i & 0x000000FFU) << 24 | (i & 0x0000FF00U) << 8 | (i & 0x00FF0000U) >> 8 | (i & 0xFF000000U) >> 24);
+ };
+ FuncGetFinalHashUInt32 = i => (i & 0x000000FFU) << 24 | (i & 0x0000FF00U) << 8 | (i & 0x00FF0000U) >> 8 | (i & 0xFF000000U) >> 24;
}
else
{
- FuncGetLittleEndianUInt32 = new Func((x, i) =>
+ FuncGetLittleEndianUInt32 = (x, i) =>
{
unsafe
{
@@ -50,8 +50,8 @@ sealed class XXHash32 : HashAlgorithm
return (uint)(array[i++] | (array[i++] << 8) | (array[i++] << 16) | (array[i] << 24));
}
}
- });
- FuncGetFinalHashUInt32 = new Func(i => i);
+ };
+ FuncGetFinalHashUInt32 = i => i;
}
}
@@ -102,8 +102,7 @@ sealed class XXHash32 : HashAlgorithm
/// The number of bytes in the byte array to use as data.
protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
- if (State != 1)
- State = 1;
+ State = 1;
int size = cbSize - ibStart;
_RemainingLength = size & 15;
if (cbSize >= 16)