stream fluent functions and other extension methods changes

This commit is contained in:
Timerix22 2023-02-22 00:00:26 +06:00
parent 021e9d1b65
commit 2d4dd84e14
8 changed files with 209 additions and 30 deletions

View File

@ -41,8 +41,7 @@ public class FileLogger : ILogger
var msg = format.CreateMessage(context, severity, message); var msg = format.CreateMessage(context, severity, message);
lock (LogfileStream) lock (LogfileStream)
{ {
LogfileStream.Write(msg.ToBytes(StringConverter.UTF8)); LogfileStream.FluentWrite(msg.ToBytes(StringConverter.UTF8)).Flush();
LogfileStream.Flush();
} }
} }

View File

@ -69,7 +69,7 @@ public class FSP
MainSocket.SendPackage("ready".ToBytes(StringConverter.UTF8)); MainSocket.SendPackage("ready".ToBytes(StringConverter.UTF8));
int packagesCount = 0; int packagesCount = 0;
byte[] buffer = new byte[5120]; byte[] buffer = new byte[5120];
int fullPackagesCount = (Filesize / buffer.Length).Truncate(); int fullPackagesCount = (int)(Filesize / buffer.Length);
// получение полных пакетов файла // получение полных пакетов файла
for (byte n = 0; packagesCount < fullPackagesCount; packagesCount++) for (byte n = 0; packagesCount < fullPackagesCount; packagesCount++)
{ {
@ -113,7 +113,7 @@ public class FSP
MainSocket.GetAnswer("ready"); MainSocket.GetAnswer("ready");
byte[] buffer = new byte[5120]; byte[] buffer = new byte[5120];
int packagesCount = 0; int packagesCount = 0;
int fullPackagesCount = (Filesize / buffer.Length).Truncate(); int fullPackagesCount = (int)(Filesize / buffer.Length);
// отправка полных пакетов файла // отправка полных пакетов файла
for (; packagesCount < fullPackagesCount; packagesCount++) for (; packagesCount < fullPackagesCount; packagesCount++)
{ {

View File

@ -8,29 +8,46 @@ global using DTLib.Extensions;
global using DTLib.Filesystem; global using DTLib.Filesystem;
global using static DTLib.Logging.PublicLog; global using static DTLib.Logging.PublicLog;
using System.Globalization; using System.Globalization;
using System.Runtime.CompilerServices;
namespace DTLib.Extensions; namespace DTLib.Extensions;
public static class BaseConverter public static class BaseConverter
{ {
// сокращение конвертации // сокращение конвертации
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ToBool<T>(this T input) => Convert.ToBoolean(input); public static bool ToBool<T>(this T input) => Convert.ToBoolean(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static char ToChar<T>(this T input) => Convert.ToChar(input); public static char ToChar<T>(this T input) => Convert.ToChar(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte ToByte<T>(this T input) => Convert.ToByte(input); public static byte ToByte<T>(this T input) => Convert.ToByte(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static sbyte ToSByte<T>(this T input) => Convert.ToSByte(input); public static sbyte ToSByte<T>(this T input) => Convert.ToSByte(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short ToShort<T>(this T input) => Convert.ToInt16(input); public static short ToShort<T>(this T input) => Convert.ToInt16(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort ToUShort<T>(this T input) => Convert.ToUInt16(input); public static ushort ToUShort<T>(this T input) => Convert.ToUInt16(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ToInt<T>(this T input) => Convert.ToInt32(input); public static int ToInt<T>(this T input) => Convert.ToInt32(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ToUInt<T>(this T input) => Convert.ToUInt32(input); public static uint ToUInt<T>(this T input) => Convert.ToUInt32(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ToLong<T>(this T input) => Convert.ToInt64(input); public static long ToLong<T>(this T input) => Convert.ToInt64(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong ToULong<T>(this T input) => Convert.ToUInt64(input); public static ulong ToULong<T>(this T input) => Convert.ToUInt64(input);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ToFloat(this string input) => float.Parse(input, NumberStyles.Any, 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 #if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ToFloat(this ReadOnlySpan<char> input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture); public static float ToFloat(this ReadOnlySpan<char> input) => float.Parse(input, NumberStyles.Any, CultureInfo.InvariantCulture);
#endif #endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double ToDouble<T>(this T input) => Convert.ToDouble(input, CultureInfo.InvariantCulture); public static double ToDouble<T>(this T input) => Convert.ToDouble(input, CultureInfo.InvariantCulture);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static decimal ToDecimal<T>(this T input) => Convert.ToDecimal(input, CultureInfo.InvariantCulture); public static decimal ToDecimal<T>(this T input) => Convert.ToDecimal(input, CultureInfo.InvariantCulture);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ToInt(this byte[] bytes) public static int ToInt(this byte[] bytes)
{ {
int output = 0; int output = 0;
@ -39,19 +56,25 @@ public static class BaseConverter
return output; return output;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte[] IntToBytes(this int num) public static byte[] IntToBytes(this int num)
{ {
List<byte> output = new(); List<byte> output = new();
while (num != 0) while (num != 0)
{ {
output.Add(ToByte(num % 256)); output.Add((byte)(num % 256));
num = (num / 256).Truncate(); num = (int)(num / 256.0);
} }
output.Reverse(); output.Reverse();
return output.ToArray(); return output.ToArray();
} }
// Math.Truncate принимает как decimal, так и doublе, [MethodImpl(MethodImplOptions.AggressiveInlining)]
// из-за чего вызов метода так: Math.Truncate(10/3) выдаст ошибку "неоднозначный вызов" public static int TruncateToInt(this double number) => Math.Truncate(number).ToInt();
public static int Truncate<T>(this T number) => Math.Truncate(number.ToDouble()).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();
} }

View File

@ -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<Stream> FluentWriteAsync(this Stream st, byte[] buff)
=> FluentWriteAsync(st, buff, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentWriteAsync(this Stream s, byte[] buff, CancellationToken ct)
{
await s.WriteAsync(buff, 0, buff.Length, ct);
return s;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Stream> FluentWriteAsync(this Task<Stream> st, byte[] buff)
=> FluentWriteAsync(st, buff, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentWriteAsync(this Task<Stream> 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<Stream> FluentCopyToAsync(this Stream src, Stream dest)
=> FluentCopyToAsync(src, dest, 81920, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Stream> FluentCopyToAsync(this Stream src, Stream dest, int bufferSize)
=> FluentCopyToAsync(src, dest, bufferSize, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentCopyToAsync(this Stream src, Stream dest, int bufferSize, CancellationToken ct)
{
await src.CopyToAsync(dest, bufferSize, ct);
return src;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Stream> FluentCopyToAsync(this Task<Stream> src, Stream dest)
=> FluentCopyToAsync(src, dest, 81920, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Stream> FluentCopyToAsync(this Task<Stream> src, Stream dest, int bufferSize)
=> FluentCopyToAsync(src, dest, bufferSize, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentCopyToAsync(this Task<Stream> 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<Stream> FluentFlushAsync(this Stream s)
=> FluentFlushAsync(s, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentFlushAsync(this Stream s, CancellationToken ct)
{
await s.FlushAsync(ct);
return s;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Stream> FluentFlushAsync(this Task<Stream> st)
=> FluentFlushAsync(st, CancellationToken.None);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Stream> FluentFlushAsync(this Task<Stream> 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
}

View File

@ -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);
}

View File

@ -4,7 +4,9 @@ public static class StringConverter
{ {
public static Encoding UTF8 = new UTF8Encoding(false); public static Encoding UTF8 = new UTF8Encoding(false);
public static Encoding UTF8BOM = new UTF8Encoding(true); 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 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); public static string BytesToString(this byte[] bytes, Encoding encoding) => encoding.GetString(bytes);
// хеш в виде массива байт в строку (хеш изначально не в кодировке UTF8, так что метод выше не работает с ним) // хеш в виде массива байт в строку (хеш изначально не в кодировке UTF8, так что метод выше не работает с ним)
@ -160,7 +162,7 @@ public static class StringConverter
public static List<string> SplitToList(this string s, int length) public static List<string> SplitToList(this string s, int length)
{ {
List<string> parts = new(); List<string> parts = new();
int max = (s.Length / length).Truncate(); int max = (int)(s.Length / length);
for (int i = 0; i < max; i++) for (int i = 0; i < max; i++)
parts.Add(s.Substring(i * length, length)); parts.Add(s.Substring(i * length, length));
if (max * length != s.Length) parts.Add(s.Substring(max * length, s.Length - max * length)); if (max * length != s.Length) parts.Add(s.Substring(max * length, s.Length - max * length));

View File

@ -8,7 +8,7 @@ public static class StrugBuilderExtensions
b.Append(array[i]); b.Append(array[i]);
return b; return b;
} }
public static StringBuilder AppendArray<TVal,TSep>(this StringBuilder b, TVal[] array, char separator) public static StringBuilder AppendArray<TVal>(this StringBuilder b, TVal[] array, char separator)
{ {
if (array.Length == 0) return b; if (array.Length == 0) return b;
b.Append(array[0]); b.Append(array[0]);
@ -16,7 +16,7 @@ public static class StrugBuilderExtensions
b.Append(separator).Append(array[i]); b.Append(separator).Append(array[i]);
return b; return b;
} }
public static StringBuilder AppendArray<TVal,TSep>(this StringBuilder b, TVal[] array, string separator) public static StringBuilder AppendArray<TVal>(this StringBuilder b, TVal[] array, string separator)
{ {
if (array.Length == 0) return b; if (array.Length == 0) return b;
b.Append(array[0]); b.Append(array[0]);
@ -31,7 +31,7 @@ public static class StrugBuilderExtensions
b.Append(el); b.Append(el);
return b; return b;
} }
public static StringBuilder AppendColletion<TVal, TSep>(this StringBuilder b, IEnumerable<TVal> enumerable, char separator) public static StringBuilder AppendColletion<TVal>(this StringBuilder b, IEnumerable<TVal> enumerable, char separator)
{ {
using IEnumerator<TVal> enumerator = enumerable.GetEnumerator(); using IEnumerator<TVal> enumerator = enumerable.GetEnumerator();
if (!enumerator.MoveNext()) return b; if (!enumerator.MoveNext()) return b;
@ -40,7 +40,7 @@ public static class StrugBuilderExtensions
b.Append(separator).Append(enumerator.Current); b.Append(separator).Append(enumerator.Current);
return b; return b;
} }
public static StringBuilder AppendColletion<TVal, TSep>(this StringBuilder b, IEnumerable<TVal> enumerable, string separator) public static StringBuilder AppendColletion<TVal>(this StringBuilder b, IEnumerable<TVal> enumerable, string separator)
{ {
using IEnumerator<TVal> enumerator = enumerable.GetEnumerator(); using IEnumerator<TVal> enumerator = enumerable.GetEnumerator();
if (!enumerator.MoveNext()) return b; if (!enumerator.MoveNext()) return b;

View File

@ -21,20 +21,19 @@ public class FileLogger : IDisposable
lock (LogfileStream) lock (LogfileStream)
{ {
LastLogMessageTime = DateTime.Now.ToString(MyTimeFormat.ForText); LastLogMessageTime = DateTime.Now.ToString(MyTimeFormat.ForText);
LogfileStream.WriteByte('['.ToByte()); LogfileStream.FluentWriteString("[")
LogfileStream.Write(LastLogMessageTime.ToBytes(StringConverter.UTF8)); .FluentWriteString(LastLogMessageTime)
LogfileStream.Write("]: ".ToBytes(StringConverter.UTF8)); .FluentWriteString("]: ");
if (msg.Length == 1) if (msg.Length == 1)
LogfileStream.Write(msg[0].ToBytes(StringConverter.UTF8)); LogfileStream.FluentWriteString(msg[0]);
else else
{ {
var strb = new StringBuilder(); var strb = new StringBuilder();
for (ushort i = 1; i < msg.Length; i += 2) for (ushort i = 1; i < msg.Length; i += 2)
strb.Append(msg[i]); strb.Append(msg[i]);
LogfileStream.Write(strb.ToString().ToBytes(StringConverter.UTF8)); LogfileStream.FluentWriteString(strb.ToString());
} }
LogfileStream.WriteByte('\n'.ToByte()); LogfileStream.FluentWriteString("\n").Flush();
LogfileStream.Flush();
} }
} }