diff --git a/DTLib.Logging/Loggers/FileLogger.cs b/DTLib.Logging/Loggers/FileLogger.cs index 08eaae8..7114e21 100644 --- a/DTLib.Logging/Loggers/FileLogger.cs +++ b/DTLib.Logging/Loggers/FileLogger.cs @@ -41,8 +41,7 @@ public class FileLogger : ILogger var msg = format.CreateMessage(context, severity, message); lock (LogfileStream) { - LogfileStream.Write(msg.ToBytes(StringConverter.UTF8)); - LogfileStream.Flush(); + LogfileStream.FluentWrite(msg.ToBytes(StringConverter.UTF8)).Flush(); } } diff --git a/DTLib.Network/FSP.cs b/DTLib.Network/FSP.cs index b424b00..de3ba9d 100644 --- a/DTLib.Network/FSP.cs +++ b/DTLib.Network/FSP.cs @@ -69,7 +69,7 @@ public class FSP MainSocket.SendPackage("ready".ToBytes(StringConverter.UTF8)); int packagesCount = 0; byte[] buffer = new byte[5120]; - int fullPackagesCount = (Filesize / buffer.Length).Truncate(); + int fullPackagesCount = (int)(Filesize / buffer.Length); // получение полных пакетов файла for (byte n = 0; packagesCount < fullPackagesCount; packagesCount++) { @@ -113,7 +113,7 @@ public class FSP MainSocket.GetAnswer("ready"); byte[] buffer = new byte[5120]; int packagesCount = 0; - int fullPackagesCount = (Filesize / buffer.Length).Truncate(); + int fullPackagesCount = (int)(Filesize / buffer.Length); // отправка полных пакетов файла for (; packagesCount < fullPackagesCount; packagesCount++) { diff --git a/DTLib/Extensions/BaseConverter.cs b/DTLib/Extensions/BaseConverter.cs index 418f86d..b9f7ee1 100644 --- a/DTLib/Extensions/BaseConverter.cs +++ b/DTLib/Extensions/BaseConverter.cs @@ -8,29 +8,46 @@ global using DTLib.Extensions; global using DTLib.Filesystem; global using static DTLib.Logging.PublicLog; using System.Globalization; +using System.Runtime.CompilerServices; namespace DTLib.Extensions; public static class BaseConverter { // сокращение конвертации + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ToBool(this T input) => Convert.ToBoolean(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char ToChar(this T input) => Convert.ToChar(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte ToByte(this T input) => Convert.ToByte(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte ToSByte(this T input) => Convert.ToSByte(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short ToShort(this T input) => Convert.ToInt16(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort ToUShort(this T input) => Convert.ToUInt16(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ToInt(this T input) => Convert.ToInt32(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint ToUInt(this T input) => Convert.ToUInt32(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long ToLong(this T input) => Convert.ToInt64(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong ToULong(this T input) => Convert.ToUInt64(input); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ToFloat(this string input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture); #if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0 + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ToFloat(this ReadOnlySpan input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture); #endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double ToDouble(this T input) => Convert.ToDouble(input, CultureInfo.InvariantCulture); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ToDecimal(this T input) => Convert.ToDecimal(input, CultureInfo.InvariantCulture); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ToInt(this byte[] bytes) { int output = 0; @@ -39,19 +56,25 @@ public static class BaseConverter return output; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] IntToBytes(this int num) { List output = new(); while (num != 0) { - output.Add(ToByte(num % 256)); - num = (num / 256).Truncate(); + output.Add((byte)(num % 256)); + num = (int)(num / 256.0); } output.Reverse(); return output.ToArray(); } - // Math.Truncate принимает как decimal, так и doublе, - // из-за чего вызов метода так: Math.Truncate(10/3) выдаст ошибку "неоднозначный вызов" - public static int Truncate(this T number) => Math.Truncate(number.ToDouble()).ToInt(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TruncateToInt(this double number) => Math.Truncate(number).ToInt(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TruncateToInt(this decimal number) => Math.Truncate(number).ToInt(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long TruncateToLong(this double number) => Math.Truncate(number).ToLong(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long TruncateToLong(this decimal number) => Math.Truncate(number).ToLong(); } diff --git a/DTLib/Extensions/FluentStreamExtensions.cs b/DTLib/Extensions/FluentStreamExtensions.cs new file mode 100644 index 0000000..e2af78f --- /dev/null +++ b/DTLib/Extensions/FluentStreamExtensions.cs @@ -0,0 +1,165 @@ +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace DTLib.Extensions; + +public static class FluentStreamExtensions +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Write(this Stream s, byte[] buff) + => s.Write(buff, 0, buff.Length); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentWriteByte(this Stream s, byte b) + { + s.WriteByte(b); + return s; + } + +#region FluentWrite +/************************************* + FluentWrite +*************************************/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentWrite(this Stream s, byte[] buff) + { + s.Write(buff); + return s; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentWriteAsync(this Stream st, byte[] buff) + => FluentWriteAsync(st, buff, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentWriteAsync(this Stream s, byte[] buff, CancellationToken ct) + { + await s.WriteAsync(buff, 0, buff.Length, ct); + return s; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentWriteAsync(this Task st, byte[] buff) + => FluentWriteAsync(st, buff, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentWriteAsync(this Task st, byte[] buff, CancellationToken ct) + { + Stream s = await st; + await s.WriteAsync(buff, 0, buff.Length, ct); + return s; + } + +#endregion + +#region FluentCopy +/************************************* + FluentCopy +*************************************/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentCopyTo(this Stream src, Stream dest) + { + src.CopyTo(dest); + return src; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentCopyToAsync(this Stream src, Stream dest) + => FluentCopyToAsync(src, dest, 81920, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentCopyToAsync(this Stream src, Stream dest, int bufferSize) + => FluentCopyToAsync(src, dest, bufferSize, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentCopyToAsync(this Stream src, Stream dest, int bufferSize, CancellationToken ct) + { + await src.CopyToAsync(dest, bufferSize, ct); + return src; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentCopyToAsync(this Task src, Stream dest) + => FluentCopyToAsync(src, dest, 81920, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentCopyToAsync(this Task src, Stream dest, int bufferSize) + => FluentCopyToAsync(src, dest, bufferSize, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentCopyToAsync(this Task srcTask, Stream dest, int bufferSize, CancellationToken ct) + { + Stream src = await srcTask; + await src.CopyToAsync(dest, bufferSize, ct); + return src; + } + +#endregion + +#region FluentFlush +/************************************* + FluentFlush +*************************************/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentFlush(this Stream s) + { + s.Flush(); + return s; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentFlushAsync(this Stream s) + => FluentFlushAsync(s, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentFlushAsync(this Stream s, CancellationToken ct) + { + await s.FlushAsync(ct); + return s; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Task FluentFlushAsync(this Task st) + => FluentFlushAsync(st, CancellationToken.None); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async Task FluentFlushAsync(this Task st, CancellationToken ct) + { + Stream s = await st; + await s.FlushAsync(ct); + return s; + } + +#endregion + +#region WriteString + +/************************************* + WriteString +*************************************/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteString(this Stream stream, string s) => + stream.Write(s.ToBytes()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteString(this Stream stream, string s, Encoding enc) => + stream.Write(s.ToBytes(enc)); + +#endregion + +#region FluentWriteString + +/************************************* + FluentWriteString +*************************************/ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentWriteString(this Stream stream, string s) => + stream.FluentWrite(s.ToBytes()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Stream FluentWriteString(this Stream stream, string s, Encoding enc) => + stream.FluentWrite(s.ToBytes(enc)); + +#endregion +} \ No newline at end of file diff --git a/DTLib/Extensions/StreamExtensions.cs b/DTLib/Extensions/StreamExtensions.cs deleted file mode 100644 index 06130fc..0000000 --- a/DTLib/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.IO; - -namespace DTLib.Extensions; - -public static class StreamExtensions -{ - public static void Write(this Stream stream, byte[] buff) - => stream.Write(buff, 0, buff.Length); -} \ No newline at end of file diff --git a/DTLib/Extensions/StringConverter.cs b/DTLib/Extensions/StringConverter.cs index 40f5db0..898d437 100644 --- a/DTLib/Extensions/StringConverter.cs +++ b/DTLib/Extensions/StringConverter.cs @@ -4,7 +4,9 @@ public static class StringConverter { public static Encoding UTF8 = new UTF8Encoding(false); public static Encoding UTF8BOM = new UTF8Encoding(true); + public static byte[] ToBytes(this string str) => UTF8.GetBytes(str); public static byte[] ToBytes(this string str, Encoding encoding) => encoding.GetBytes(str); + public static string BytesToString(this byte[] bytes) => UTF8.GetString(bytes); public static string BytesToString(this byte[] bytes, Encoding encoding) => encoding.GetString(bytes); // хеш в виде массива байт в строку (хеш изначально не в кодировке UTF8, так что метод выше не работает с ним) @@ -160,7 +162,7 @@ public static class StringConverter public static List SplitToList(this string s, int length) { List parts = new(); - int max = (s.Length / length).Truncate(); + int max = (int)(s.Length / length); for (int i = 0; i < max; i++) parts.Add(s.Substring(i * length, length)); if (max * length != s.Length) parts.Add(s.Substring(max * length, s.Length - max * length)); diff --git a/DTLib/Extensions/StrugBuilderExtensions.cs b/DTLib/Extensions/StrugBuilderExtensions.cs index a8ea145..d39f53a 100644 --- a/DTLib/Extensions/StrugBuilderExtensions.cs +++ b/DTLib/Extensions/StrugBuilderExtensions.cs @@ -8,7 +8,7 @@ public static class StrugBuilderExtensions b.Append(array[i]); return b; } - public static StringBuilder AppendArray(this StringBuilder b, TVal[] array, char separator) + public static StringBuilder AppendArray(this StringBuilder b, TVal[] array, char separator) { if (array.Length == 0) return b; b.Append(array[0]); @@ -16,7 +16,7 @@ public static class StrugBuilderExtensions b.Append(separator).Append(array[i]); return b; } - public static StringBuilder AppendArray(this StringBuilder b, TVal[] array, string separator) + public static StringBuilder AppendArray(this StringBuilder b, TVal[] array, string separator) { if (array.Length == 0) return b; b.Append(array[0]); @@ -31,7 +31,7 @@ public static class StrugBuilderExtensions b.Append(el); return b; } - public static StringBuilder AppendColletion(this StringBuilder b, IEnumerable enumerable, char separator) + public static StringBuilder AppendColletion(this StringBuilder b, IEnumerable enumerable, char separator) { using IEnumerator enumerator = enumerable.GetEnumerator(); if (!enumerator.MoveNext()) return b; @@ -40,7 +40,7 @@ public static class StrugBuilderExtensions b.Append(separator).Append(enumerator.Current); return b; } - public static StringBuilder AppendColletion(this StringBuilder b, IEnumerable enumerable, string separator) + public static StringBuilder AppendColletion(this StringBuilder b, IEnumerable enumerable, string separator) { using IEnumerator enumerator = enumerable.GetEnumerator(); if (!enumerator.MoveNext()) return b; diff --git a/DTLib/Logging/FileLogger.cs b/DTLib/Logging/FileLogger.cs index b0c5ade..844a810 100644 --- a/DTLib/Logging/FileLogger.cs +++ b/DTLib/Logging/FileLogger.cs @@ -21,20 +21,19 @@ public class FileLogger : IDisposable lock (LogfileStream) { LastLogMessageTime = DateTime.Now.ToString(MyTimeFormat.ForText); - LogfileStream.WriteByte('['.ToByte()); - LogfileStream.Write(LastLogMessageTime.ToBytes(StringConverter.UTF8)); - LogfileStream.Write("]: ".ToBytes(StringConverter.UTF8)); + LogfileStream.FluentWriteString("[") + .FluentWriteString(LastLogMessageTime) + .FluentWriteString("]: "); if (msg.Length == 1) - LogfileStream.Write(msg[0].ToBytes(StringConverter.UTF8)); + LogfileStream.FluentWriteString(msg[0]); else { var strb = new StringBuilder(); for (ushort i = 1; i < msg.Length; i += 2) strb.Append(msg[i]); - LogfileStream.Write(strb.ToString().ToBytes(StringConverter.UTF8)); + LogfileStream.FluentWriteString(strb.ToString()); } - LogfileStream.WriteByte('\n'.ToByte()); - LogfileStream.Flush(); + LogfileStream.FluentWriteString("\n").Flush(); } }