merged projects DTLib.Dtsod, DTLib.Network and DTLib.Logging into DTLib project

This commit is contained in:
Timerix22 2024-09-20 01:45:33 +05:00
parent c31370f37a
commit 249627dc78
91 changed files with 55 additions and 34664 deletions

@ -1 +1 @@
Subproject commit cfd755cd8cde6a087ce9a4e4de8302edf771f76a
Subproject commit 59de4eada9235dd50c1cb0021d0cb8bdcabdc611

View File

@ -1,39 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--package info-->
<PackageId>DTLib.Dtsod</PackageId>
<Version>1.3.4</Version>
<Authors>Timerix</Authors>
<Description>Definitely not json</Description>
<RepositoryType>GIT</RepositoryType>
<RepositoryUrl>https://github.com/Timerix22/DTLib</RepositoryUrl>
<PackageProjectUrl>https://github.com/Timerix22/DTLib</PackageProjectUrl>
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<!--language features-->
<LangVersion>11</LangVersion>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
<!--external dependencies-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup>
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib\DTLib.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.3.4" />
</ItemGroup>
<!--project files-->
<ItemGroup>
<Compile Remove="Experimental/**/*" />
</ItemGroup>
</Project>

View File

@ -1,328 +0,0 @@
namespace DTLib.Dtsod;
// v21
// парсер теперь не может игнорировать комменты, потом починю
// теперь числовые значения конвертируются в правильный тип, а не в int64/uint64 (новый вариант switch из c#9.0 делал какую-то дичь)
// исправлены некоторые другие баги
public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
{
public DtsodVersion Version { get; } = DtsodVersion.V21;
public IDictionary<string, dynamic> ToDictionary() => this;
readonly string Text;
//public Dictionary<string, dynamic> Values { get; set; }
public DtsodV21(string text)
{
Text = text;
foreach (KeyValuePair<string, dynamic> pair in Parse(text))
Add(pair.Key, pair.Value);
}
public DtsodV21(IDictionary<string, dynamic> rawDict)
{
Text = "";
foreach (KeyValuePair<string, dynamic> pair in rawDict)
Add(pair.Key, pair.Value);
}
// выдаёт Exception
public new dynamic this[string key]
{
get => TryGetValue(key, out dynamic value) ? value : throw new Exception($"Dtsod[{key}] key not found");
set
{
if (!TrySetValue(key, value)) throw new Exception($"Dtsod[{key}] key not found");
}
}
// не выдаёт KeyNotFoundException
public new bool TryGetValue(string key, out dynamic value)
{
try
{
value = base[key];
return true;
}
catch (KeyNotFoundException)
{
value = null;
return false;
}
}
public bool TrySetValue(string key, dynamic value)
{
try
{
base[key] = value;
return true;
}
catch (KeyNotFoundException)
{
return false;
}
}
public override string ToString() => Text;
enum ValueType
{
List,
Complex,
String,
Default
}
Dictionary<string, dynamic> Parse(string text)
{
Dictionary<string, dynamic> parsed = new();
int i = 0;
for (; i < text.Length; i++)
ReadName();
return parsed;
// СЛОМАНО
/*void ReadCommentLine()
{
for (; i < text.Length && text[i] != '\n'; i++) DebugNoTime("h", text[i].ToString());
}*/
void ReadName()
{
bool isListElem = false;
dynamic value;
StringBuilder defaultNameBuilder = new();
for (; i < text.Length; i++)
{
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case ':':
i++;
string name = defaultNameBuilder.ToString();
value = ReadValue();
// если value это null, эта строка выдавала ошибку
//DebugNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })");
if (isListElem)
{
if (!parsed.ContainsKey(name))
parsed.Add(name, new List<dynamic>());
parsed[name].Add(value);
}
else
parsed.Add(name, value);
return;
// строка, начинающаяся с # будет считаться комментом
case '#':
//ReadCommentLine();
break;
case '}':
throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char");
// если $ перед названием параметра поставить, значение value добавится в лист с названием name
case '$':
if (defaultNameBuilder.ToString().Length != 0)
throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char");
isListElem = true;
break;
case ';':
throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char");
default:
defaultNameBuilder.Append(text[i]);
break;
}
}
}
dynamic ReadValue()
{
ValueType type = ValueType.Default;
dynamic value = null;
string ReadString()
{
i++;
StringBuilder valueBuilder = new();
valueBuilder.Append('"');
for (; text[i] != '"' || text[i - 1] == '\\'; i++)
{
valueBuilder.Append(text[i]);
}
valueBuilder.Append('"');
type = ValueType.String;
return valueBuilder.ToString();
}
List<dynamic> ReadList()
{
i++;
List<dynamic> output = new();
StringBuilder valueBuilder = new();
for (; text[i] != ']'; i++)
{
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case ',':
ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
valueBuilder.Clear();
break;
default:
valueBuilder.Append(text[i]);
break;
}
}
if (valueBuilder.Length > 0)
{
ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
}
type = ValueType.List;
return output;
}
Dictionary<string, dynamic> ReadComplex()
{
StringBuilder valueBuilder = new();
int balance = 1;
i++;
for (; balance != 0; i++)
{
switch (text[i])
{
case '"':
valueBuilder.Append(ReadString());
break;
case '}':
balance--;
if (balance != 0)
valueBuilder.Append(text[i]);
break;
case '{':
balance++;
valueBuilder.Append(text[i]);
break;
default:
valueBuilder.Append(text[i]);
break;
}
}
i--; // i++ в for выполняется даже когда balance == 0, то есть text[i] получается == ;, что ломает всё
type = ValueType.Complex;
return Parse(valueBuilder.ToString());
}
void ParseValueToRightType(string stringValue)
{
switch (stringValue)
{
// bool
case "true":
case "false":
value = stringValue.ToBool();
break;
// null
case "null":
value = null;
break;
default:
if (stringValue.Contains('"'))
value = stringValue.Remove(stringValue.Length - 1).Remove(0, 1);
// double
else if (stringValue.Contains('.'))
value = stringValue.ToDouble();
// ushort; ulong; uint
else if (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u')
{
switch (stringValue[stringValue.Length - 1])
{
case 's':
value = stringValue.Remove(stringValue.Length - 2).ToUShort();
break;
case 'i':
value = stringValue.Remove(stringValue.Length - 2).ToUInt();
break;
case 'l':
value = stringValue.Remove(stringValue.Length - 2).ToULong();
break;
default:
throw new Exception($"Dtsod.Parse.ReadValue() error: value= wrong type <u{stringValue[stringValue.Length - 1]}>");
}
}
// short; long; int
else
switch (stringValue[stringValue.Length - 1])
{
case 's':
value = stringValue.Remove(stringValue.Length - 1).ToShort();
break;
case 'l':
value = stringValue.Remove(stringValue.Length - 1).ToLong();
break;
default:
value = stringValue.ToInt();
break;
}
break;
}
}
StringBuilder defaultValueBuilder = new();
for (; i < text.Length; i++)
{
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '"':
value = ReadString();
break;
case ';':
switch (type)
{
case ValueType.String:
ParseValueToRightType(value);
break;
case ValueType.Default:
ParseValueToRightType(defaultValueBuilder.ToString());
break;
}
return value;
case '[':
value = ReadList();
break;
case '{':
value = ReadComplex();
break;
// строка, начинающаяся с # будет считаться комментом
case '#':
//ReadCommentLine();
break;
default:
defaultValueBuilder.Append(text[i]);
break;
}
}
throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function");
}
}
}

View File

@ -1,39 +0,0 @@
namespace DTLib.Dtsod.ClassSerializer;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
public class DtsodSerializableAttribute : Attribute
{
public DtsodVersion Version;
public DtsodSerializableAttribute(DtsodVersion ver) => Version = ver;
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SerializeAsAttribute: Attribute
{
public string Key;
/// <summary>
/// use it only for base types
/// </summary>
/// <param name="key">name the field will be serialized as</param>
public SerializeAsAttribute(string key) => Key = key;
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SerializationMethodAttribute<TSource,TSerialized> : Attribute
{
public Func<TSource, TSerialized> Method;
/// <summary>
/// </summary>
/// <param name="method">how to serialize field</param>
public SerializationMethodAttribute(Func<TSource, TSerialized> method) => Method = method;
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DeserializationMethodAttribute<TSource,TSerialized> : Attribute
{
public Func<TSerialized, TSource> Method;
/// <summary>
/// </summary>
/// <param name="method">how to deserialize field</param>
public DeserializationMethodAttribute( Func<TSerialized, TSource> method) => Method = method;
}

View File

@ -1,298 +0,0 @@
using System.Globalization;
using DTLib.Dtsod.ClassSerializer;
namespace DTLib.Dtsod;
public class DtsodV30 : DtsodDict<string, dynamic>, IDtsod
{
public DtsodVersion Version { get; } = DtsodVersion.V30;
public IDictionary<string, dynamic> ToDictionary() => this;
public DtsodV30() : base() => UpdateLazy();
public DtsodV30(IDictionary<string, dynamic> dict) : base(dict) => UpdateLazy();
public DtsodV30(string serialized) : this() => Append(Deserialize(serialized));
static IDictionary<string, dynamic> Deserialize(string text)
{
char c;
int i = -1; // ++i в ReadType
StringBuilder b = new();
Type ReadType()
{
while (i < text.Length - 1)
{
c = text[++i];
switch (c)
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '#':
SkipComment();
break;
case ':':
string _type = b.ToString();
b.Clear();
return TypeHelper.Instance.TypeFromString(_type);
case '=':
case '"':
case '\'':
case ';':
case '[':
case ']':
case '{':
case '}':
throw new Exception($"DtsodV30.Deserialize() error: unexpected {c}");
default:
b.Append(c);
break;
}
}
throw new Exception("DtsodV30.Deserialize.ReadType() error: end of text\ntext:\n" + text);
}
string ReadName()
{
while (i < text.Length - 1)
{
c = text[++i];
switch (c)
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '#':
SkipComment();
break;
case '=':
string _name = b.ToString();
b.Clear();
return _name;
case ':':
case '"':
case '\'':
case ';':
case '[':
case ']':
case '{':
case '}':
throw new Exception($"DtsodV30.Deserialize() error: unexpected {c}");
default:
b.Append(c);
break;
}
}
throw new Exception("DtsodV30.Deserialize.ReadName() error: end of text\ntext:\n" + text);
}
object ReadValue(ref bool endoflist)
{
void ReadString()
{
c = text[++i]; //пропускает начальный символ '"'
while ((c != '"' && c != '\'') || (text[i - 1] == '\\' && text[i - 2] != '\\'))
{
b.Append(c);
if (++i >= text.Length) throw new Exception("DtsodV30.Deserialize() error: end of text\ntext:\n" + text);
c = text[i];
}
}
List<object> ReadList()
{
List<object> list = new();
bool _endoflist = false;
while (!_endoflist)
list.Add(CreateInstance(ReadType(), ReadValue(ref _endoflist)));
b.Clear();
return list;
}
IDictionary<string, dynamic> ReadDictionary()
{
short bracketBalance = 1;
c = text[++i]; //пропускает начальный символ '{'
while (bracketBalance != 0)
{
switch (c)
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '#':
SkipComment();
break;
case '{':
bracketBalance++;
b.Append(c);
break;
case '}':
bracketBalance--;
if (bracketBalance != 0)
b.Append(c);
break;
case '"':
case '\'':
b.Append('"');
ReadString();
b.Append('"');
break;
default:
b.Append(c);
break;
}
if (++i >= text.Length) throw new Exception("DtsodV30.Deserialize() error: end of text\ntext:\n" + text);
c = text[i];
}
b.Clear();
return Deserialize(b.ToString());
}
while (i < text.Length-1)
{
c = text[++i];
switch (c)
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '#':
SkipComment();
break;
case '"':
case '\'':
ReadString();
break;
case ';': // один параметр
case ',': // для листов
string str = b.ToString();
b.Clear();
return str == "null" ? null : str;
case '[':
return ReadList();
case ']':
endoflist = true;
goto case ',';
case '{':
return ReadDictionary();
case '=':
case ':':
case '}':
throw new Exception($"DtsodV30.Deserialize() error: unexpected {c}");
default:
b.Append(c);
break;
}
}
throw new Exception("DtsodV30.Deserialize.ReadValue() error: end of text\ntext:\n" + text);
}
void SkipComment()
{
while (text[i] != '\n')
if (++i >= text.Length) throw new Exception("DtsodV30.Deserialize() error: end of text\ntext:\n" + text);
}
object CreateInstance(Type type, object ctor_arg)
{
if (TypeHelper.Instance.BaseTypeConstructors.TryGetValue(type, out Func<string, dynamic> ctor))
return (object)ctor.Invoke((string)ctor_arg);
else if (type.CustomAttributes.Any(a => a.AttributeType == typeof(DtsodSerializableAttribute)))
return Activator.CreateInstance(type, ((IDictionary<string, object>)ctor_arg).Values.ToArray());
else if (typeof(ICollection).IsAssignableFrom(type))
{
var method_As = typeof(TypeHelper).GetMethod("As",
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic)
.MakeGenericMethod(type.GetGenericArguments()[0]);
object collection = type.GetConstructor(Type.EmptyTypes).Invoke(null);
var method_Add = type.GetMethod("Add");
Log(method_Add.Name);
foreach (object el in (IEnumerable)ctor_arg)
{
var pel = method_As.Invoke(null, new object[] { el });
method_Add.Invoke(collection, new object[] { pel });
}
return collection;
}
else throw new Exception($"can't create instance of {type.FullName}");
}
Dictionary<string, dynamic> output = new();
Type type;
string name;
object value;
for (; i < text.Length; i++)
{
type = ReadType();
name = ReadName();
bool _ = false;
value = ReadValue(ref _);
output.Add(name, CreateInstance(type, value));
}
return output;
}
// public override void Append(ICollection<KeyValuePair<string, dynamic>> anotherDtsod) => base.Append(anotherDtsod);//UpdateLazy();
public override void Add(string key, dynamic value) => base.Add(key, (object)value);//UpdateLazy();
protected static string Serialize(IDictionary<string, dynamic> dtsod, ushort tabsCount = 0)
{
StringBuilder b = new();
foreach (KeyValuePair<string, dynamic> pair in dtsod)
{
SerializeObject(pair.Key, pair.Value);
}
void SerializeObject(string name, dynamic inst)
{
Type type = inst.GetType();
b.Append(TypeHelper.Instance.TypeToString(type)).Append(':')
.Append(name).Append('=');
if (TypeHelper.Instance.BaseTypeNames.ContainsKey(type))
{
if (type == typeof(decimal) || type == typeof(double) || type == typeof(float))
b.Append(inst.ToString(CultureInfo.InvariantCulture));
else b.Append(inst.ToString());
}
else if (typeof(IDictionary<string, dynamic>).IsAssignableFrom(type))
b.Append("\n{\n").Append(Serialize(inst, tabsCount++)).Append("};\n");
else if (type.CustomAttributes.Any(a => a.AttributeType == typeof(DtsodSerializableAttribute)))
{
var props = type.GetProperties().Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(DtsodSerializableAttribute)));
foreach (var prop in props)
{
var propval = prop.GetValue(inst);
}
}
else throw new Exception($"can't serialize type {type.FullName}");
}
return b.ToString();
}
protected Lazy<string> serialized;
protected void UpdateLazy() => serialized = new(() => Serialize(this));
public override string ToString() => serialized.Value;
}

View File

@ -1,114 +0,0 @@
namespace DTLib.Dtsod;
public class TypeHelper
{
static Lazy<TypeHelper> _inst = new();
public static TypeHelper Instance => _inst.Value;
internal readonly Dictionary<Type, Func<string, dynamic>> BaseTypeConstructors = new()
{
{ typeof(bool), (inp) => inp.ToBool() },
{ typeof(char), (inp) => inp.ToChar() },
{ typeof(string), (inp) => inp.ToString() },
{ typeof(byte), (inp) => inp.ToByte() },
{ typeof(sbyte), (inp) => inp.ToSByte() },
{ typeof(short), (inp) => inp.ToShort() },
{ typeof(ushort), (inp) => inp.ToUShort() },
{ typeof(int), (inp) => inp.ToInt() },
{ typeof(uint), (inp) => inp.ToUInt() },
{ typeof(long), (inp) => inp.ToLong() },
{ typeof(ulong), (inp) => inp.ToULong() },
{ typeof(float), (inp) => inp.ToFloat() },
{ typeof(double), (inp) => inp.ToDouble() },
{ typeof(decimal), (inp) => inp.ToDecimal() }
};
internal Dictionary<Type, string> BaseTypeNames = new()
{
{ typeof(bool), "bool" },
{ typeof(char), "char" },
{ typeof(string), "string" },
{ typeof(byte), "byte" },
{ typeof(sbyte), "sbyte" },
{ typeof(short), "short" },
{ typeof(ushort), "ushort" },
{ typeof(int), "int" },
{ typeof(uint), "uint" },
{ typeof(long), "long" },
{ typeof(ulong), "ulong" },
{ typeof(float), "float" },
{ typeof(double), "double" },
{ typeof(decimal), "decimal" }
};
private Dictionary<string, Type> ST_extensions = new()
{
{ "List<bool>", typeof(List<bool>) },
{ "List<char>", typeof(List<char>) },
{ "List<string>", typeof(List<string>) },
{ "List<byte>", typeof(List<byte>) },
{ "List<sbyte>", typeof(List<sbyte>) },
{ "List<short>", typeof(List<short>) },
{ "List<ushort>", typeof(List<ushort>) },
{ "List<int>", typeof(List<int>) },
{ "List<uint>", typeof(List<uint>) },
{ "List<long>", typeof(List<long>) },
{ "List<ulong>", typeof(List<ulong>) },
{ "List<float>", typeof(List<float>) },
{ "List<double>", typeof(List<double>) },
{ "List<decimal>", typeof(List<decimal>) },
};
private Dictionary<Type, string> TS_extensions = new()
{
{ typeof(List<bool>), "List<bool>" },
{ typeof(List<char>), "List<char>" },
{ typeof(List<string>), "List<string>" },
{ typeof(List<byte>), "List<byte>" },
{ typeof(List<sbyte>), "List<sbyte>" },
{ typeof(List<short>), "List<short>" },
{ typeof(List<ushort>), "List<ushort>" },
{ typeof(List<int>), "List<int>" },
{ typeof(List<uint>), "List<uint>" },
{ typeof(List<long>), "List<long>" },
{ typeof(List<ulong>), "List<ulong>" },
{ typeof(List<float>), "List<float>" },
{ typeof(List<double>), "List<double>" },
{ typeof(List<decimal>), "List<decimal>" },
};
public TypeHelper Extend(string name, Type type)
{
ST_extensions.Add(name, type);
TS_extensions.Add(type, name);
return this;
}
public string TypeToString(Type t) =>
BaseTypeNames.TryGetValue(t, out string name)
? name
: TS_extensions.TryGetValue(t, out name)
? name
: t.FullName;
public Type TypeFromString(string str) => str switch
{
"bool" => typeof(bool),
"char" => typeof(char),
"string" => typeof(string),
"byte" => typeof(byte),
"sbyte" => typeof(sbyte),
"short" => typeof(short),
"ushort" => typeof(ushort),
"int" => typeof(int),
"uint" => typeof(uint),
"long" => typeof(long),
"ulong" => typeof(ulong),
"float" => typeof(float),
"double" => typeof(double),
"decimal" => typeof(decimal),
_ => ST_extensions.TryGetValue(str, out var t)
? t
: Type.GetType(str, false)
?? throw new Exception($"DtsodV30.Deserialize.ParseType() error: type {str} doesn't exists")
};
internal static T As<T>(object inst) where T : class => inst as T;
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<!--package info-->
<PackageId>DTLib.Logging.Microsoft</PackageId>
<Version>1.0.1</Version>
<Version>1.1.0</Version>
<Authors>Timerix</Authors>
<Description>DTLib logger wrapper with dependency injection</Description>
<RepositoryType>GIT</RepositoryType>
@ -11,8 +11,7 @@
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<!--language features-->
<LangVersion>12</LangVersion>
<Nullable>disable</Nullable>
@ -26,9 +25,9 @@
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib.Logging\DTLib.Logging.csproj" />
<ProjectReference Include="..\DTLib\DTLib.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib.Logging" Version="1.3.5" />
<PackageReference Include="DTLib" Version="1.4.*" />
</ItemGroup>
</Project>

View File

@ -1,31 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--package info-->
<PackageId>DTLib.Logging</PackageId>
<Version>1.3.5</Version>
<Authors>Timerix</Authors>
<Description>Loggers with dependency injection</Description>
<RepositoryType>GIT</RepositoryType>
<RepositoryUrl>https://github.com/Timerix22/DTLib</RepositoryUrl>
<PackageProjectUrl>https://github.com/Timerix22/DTLib</PackageProjectUrl>
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<!--language features-->
<LangVersion>12</LangVersion>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib\DTLib.csproj" />
<ProjectReference Include="..\DTLib.Ben.Demystifier\DTLib.Ben.Demystifier.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.3.4" />
<PackageReference Include="DTLib.Ben.Demystifier" Version="1.0.6" />
</ItemGroup>
</Project>

View File

@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--package info-->
<PackageId>DTLib.Network</PackageId>
<Version>1.4.2</Version>
<Authors>Timerix</Authors>
<Description>Some sick network protocols</Description>
<RepositoryType>GIT</RepositoryType>
<RepositoryUrl>https://github.com/Timerix22/DTLib</RepositoryUrl>
<PackageProjectUrl>https://github.com/Timerix22/DTLib</PackageProjectUrl>
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<!--language features-->
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib.Dtsod\DTLib.Dtsod.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib.Dtsod" Version="1.3.4" />
</ItemGroup>
</Project>

View File

@ -1,9 +0,0 @@
using System.ComponentModel;
// включает init и record из c# 9.0
#if !NET6_0 && !NET7_0 && !NET8_0
namespace System.Runtime.CompilerServices;
[EditorBrowsable(EditorBrowsableState.Never)]
public class IsExternalInit { }
#endif

View File

@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--compilation properties-->
<OutputType>Exe</OutputType>
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<!--language features-->
<LangVersion>12</LangVersion>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib.Logging\DTLib.Logging.csproj" />
<ProjectReference Include="..\DTLib.Network\DTLib.Network.csproj" />
<ProjectReference Include="..\DTLib.Dtsod\DTLib.Dtsod.csproj" />
<ProjectReference Include="..\DTLib\DTLib.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.3.4" />
<PackageReference Include="DTLib.Dtsod" Version="1.3.4" />
<PackageReference Include="DTLib.Network" Version="1.4.0" />
<PackageReference Include="DTLib.Logging" Version="1.3.5" />
</ItemGroup>
<!--project files-->
<ItemGroup>
<None Update="Dtsod\TestResources\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>

View File

@ -1,40 +0,0 @@
/*
using KerepWrapper.Autoarr;
using KerepWrapper.KerepTypes;
namespace DTLib.Tests;
public static class TestAutoarr
{
public static void TestAll()
{
var ar = new Autoarr<KVPair>(4, 4, false);
Fill(ar);
Print(ar);
Free(ar);
}
public static void Fill(Autoarr<KVPair> ar)
{
Logger.Log("c", "----------[TestAutoarr/Fill]----------");
for(uint i=0;i<ar.MaxLength;i++)
ar.Add(new KVPair($"key_{i}",new Unitype(i)));
Logger.Log("g", "test completed");
}
public static void Print(Autoarr<KVPair> ar)
{
Logger.Log("c", "----------[TestAutoarr/Print]---------");
foreach (KVPair pair in ar)
Logger.Log("h", pair.ToString());
Logger.Log("g", "test completed");
}
public static void Free(Autoarr<KVPair> ar)
{
Logger.Log("c", "----------[TestAutoarr/Free]----------");
ar.Dispose();
Logger.Log("g", "test completed");
}
}
*/

View File

@ -1,88 +0,0 @@
using System.Linq;
namespace DTLib.Tests;
public static class TestDtsodV23
{
public static void TestAll()
{
TestBaseTypes();
TestLists();
TestComplexes();
TestReSerialization();
TestSpeed();
TestMemoryConsumption();
}
public static void TestBaseTypes()
{
ColoredConsole.WriteLine("c", "-----[TestDtsodV23/TestBaseTypes]-----");
DtsodV23 dtsod = new(File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "base_types.dtsod")));
foreach (var pair in dtsod)
ColoredConsole.WriteLine("b", pair.Value.GetType().Name + ' ', "w", pair.Key + ' ', "c", pair.Value.ToString());
ColoredConsole.WriteLine("g", "test completed");
}
public static void TestLists()
{
ColoredConsole.WriteLine("c", "-------[TestDtsodV23/TestLists]-------");
DtsodV23 dtsod = new(File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "lists.dtsod")));
foreach (var pair in dtsod)
{
ColoredConsole.WriteLine("b", pair.Value.GetType().Name + ' ', "w", pair.Key, "c",
$" count: {pair.Value.Count}");
foreach (var el in pair.Value)
ColoredConsole.WriteLine("b", '\t'+el.GetType().Name + ' ', "c", el.ToString());
}
ColoredConsole.WriteLine("g", "test completed");
}
public static void TestComplexes()
{
ColoredConsole.WriteLine("c", "-----[TestDtsodV23/TestComplexes]-----");
DtsodV23 dtsod = new(File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "complexes.dtsod")));
foreach (var complex in dtsod)
{
ColoredConsole.WriteLine("b", complex.Value.GetType().Name + ' ', "w", complex.Key,
"b", " size: ", "c", complex.Value.Keys.Count.ToString());
foreach (var pair in (DtsodV23) complex.Value)
ColoredConsole.WriteLine("b", '\t' + pair.Value.GetType().Name + ' ', "w", pair.Key + ' ',
"c", pair.Value.ToString());
}
ColoredConsole.WriteLine("g", "test completed");
}
public static void TestReSerialization()
{
ColoredConsole.WriteLine("c", "--[TestDtsodV23/TestReSerialization]--");
var dtsod = new DtsodV23(new DtsodV23(new DtsodV23(
new DtsodV23(File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "complexes.dtsod")))).ToString()).ToString());
ColoredConsole.WriteLine("y", dtsod.ToString());
ColoredConsole.WriteLine("g", "test completed");
}
public static void TestSpeed()
{
ColoredConsole.WriteLine("c", "-------[TestDtsodV23/TestSpeed]-------");
IDtsod dtsod=null;
string text = File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "messages.dtsod"));
LogOperationTime("V21 deserialization",64,()=>dtsod=new DtsodV21(text));
LogOperationTime("V21 serialization", 64, () => _=dtsod.ToString());
LogOperationTime("V23 deserialization", 64, () => dtsod = new DtsodV23(text));
LogOperationTime("V23 serialization", 64, () => _ = dtsod.ToString());
ColoredConsole.WriteLine("g", "test completed");
}
public static void TestMemoryConsumption()
{
ColoredConsole.WriteLine("c", "----[TestDtsodV23/TestMemConsumpt]----");
string text = File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "messages.dtsod"));
var a = GC.GetTotalMemory(true);
var dtsods = new DtsodV23[64];
for (int i = 0; i < dtsods.Length; i++)
dtsods[i] = new(text);
var b = GC.GetTotalMemory(true);
ColoredConsole.WriteLine("b", "at the start: ","c",$"{a/1024} kb\n",
"b", "at the end: ", "c", $"{b / 1024} kb\n{dtsods.Count()}","b"," dtsods initialized");
ColoredConsole.WriteLine("g", "test completed");
}
}

View File

@ -1,84 +0,0 @@
/*
using KerepWrapper.Dtsod;
using KerepWrapper.Autoarr;
using KerepWrapper.KerepTypes;
namespace DTLib.Tests;
public static class TestDtsodV24
{
public static void TestAll()
{
TestBaseTypes();
TestComplexes();
TestLists();
TestReSerialization();
TestSpeed();
}
public static void TestBaseTypes()
{
Logger.Log("c", "-----[TestDtsodV24/TestBaseTypes]-----");
DtsodV24 dtsod = new(File.ReadAllText($"Path.Concat("Dtsod","TestResources","DtsodV24", "base_types.dtsod")));
foreach (var pair in dtsod)
Logger.Log("b", pair.ToString());
Logger.Log("g", "test completed");
}
public static void TestComplexes()
{
Logger.Log("c", "-----[TestDtsodV24/TestComplexes]-----");
DtsodV24 dtsod = new(File.ReadAllText($"Path.Concat("Dtsod","TestResources","DtsodV24", "complexes.dtsod")));
Logger.Log("h", dtsod.ToString());
Logger.Log("g", "test completed");
}
public static void TestLists()
{
Logger.Log("c", "-------[TestDtsodV24/TestLists]-------");
DtsodV24 dtsod = new(File.ReadAllText($"Path.Concat("Dtsod","TestResources","DtsodV24", "lists.dtsod")));
foreach (KVPair pair in dtsod)
{
var list = new Autoarr<Unitype>(pair.value.VoidPtr, false);
Logger.Log("b", pair.key.HGlobalUTF8ToString(), "w", $" length: {list.Length}");
foreach (var el in list)
{
Logger.Log("h", '\t' + el.ToString());
if (el.TypeCode == KerepTypeCode.AutoarrUnitypePtr)
{
var ar = new Autoarr<Unitype>(el.VoidPtr, false);
foreach (var k in ar)
{
Logger.Log($"\t\t{k.ToString()}");
}
}
}
}
Logger.Log("g", "test completed");
}
public static void TestReSerialization()
{
Logger.Log("c", "--[TestDtsodV24/TestReSerialization]--");
var dtsod = new DtsodV24(new DtsodV24(new DtsodV24(
new DtsodV24(File.ReadAllText($"Path.Concat("Dtsod","TestResources","DtsodV24", "complexes.dtsod"))).ToString()).ToString()).ToString()));
Logger.Log("h", dtsod.ToString());
Logger.Log("g", "test completed");
}
public static void TestSpeed()
{
Logger.Log("c", "-------[TestDtsodV24/TestSpeed]-------");
IDtsod dtsod=null;
string _text = File.ReadAllText(Path.Concat("Dtsod","TestResources","DtsodV23", "messages.dtsod"));
string text = "";
LogOperationTime( "V23 to V24 conversion", 32, ()=>
text = DtsodConverter.ConvertVersion(new DtsodV23(_text), DtsodVersion.V24).ToString()
);
File.WriteAllText($"Path.Concat("Dtsod","TestResources","DtsodV24", "messages.dtsod",text));
LogOperationTime("V24 deserialization", 64, () => dtsod = new DtsodV24(text));
LogOperationTime("V24 serialization", 64, () => text = dtsod.ToString());
Logger.Log("g", "test completed");
}
}
*/

View File

@ -1,54 +0,0 @@
/*
using System.Runtime.InteropServices;
using KerepWrapper.Dtsod;
using KerepWrapper.KerepTypes;
namespace DTLib.Tests;
public static class TestPInvoke
{
public static void TestAll()
{
DependencyResolver.CopyLibs();
TestUTF8();
TestPrintf();
TestMarshalling();
}
public static void TestUTF8()
{
Logger.Log("c", "--------[TestPInvoke/TestUTF8]--------", "b", "");
IntPtr ptr;
string str="_$\"\\\\'''\ta ыыы000;2;=:%d;```";
for(int i=0; i<1000; i++)
{
ptr = Unmanaged.StringToHGlobalUTF8(str);
str = Unmanaged.HGlobalUTF8ToString(ptr);
}
Logger.Log("y", str);
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void pinvoke_print([MarshalAs(UnmanagedType.LPStr)] string msg);
public static void TestPrintf()
{
Logger.Log("c", "---------[TestPInvoke/Printf]---------", "b", "");
pinvoke_print("ъъ~ 中文");
Logger.Log("g", "test completed");
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe void test_marshalling([MarshalAs(UnmanagedType.LPStr)] string text, out IntPtr kptr);
public static unsafe void TestMarshalling()
{
Logger.Log("c", "---------[TestAutoarr/TestMarshalling]----------");
string msg = "ъъ~ 中文";
test_marshalling(msg, out var kptr);
KVPair k = *(KVPair*)kptr;
Logger.Log("b", k.ToString());
Logger.Log("g", "test completed");
}
}
*/

View File

@ -1,14 +0,0 @@
bool: false;
char: 'v';
byte: 255b;
sbyte: -125sb;
short: 14003s;
ushort: 32025us;
int: -2515;
uint: 0u;
long: -29863854396l;
ulong: 87659057946ul;
float: 39.944f;
double: 965.557;
decimal: -84.20de;
string: "_$\"\\\\'''\n\ta ыыы000;2;=:%d;```";

View File

@ -1,9 +0,0 @@
message:
{
type: "sent";
time: "15.12.2021 20:51:24 +03:00";
author_id: 293798876950036480ul;
channel_id: 913088838761603212ul;
message_id: 920734809096077353ul;
text: "_$\"\\\\'''\n\ta ыыы000;2;=:%d;```";
};

View File

@ -1,5 +0,0 @@
chars: ['a','b','c'];
uints: [10,20,30,0,0];
floats: [8.2,5.225,-0.9993];
strings:["aaa","bbb","ccc"];
things:["aaa",'b',-122];

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
bool: false ;
int: -2515;
uint: 0u;
float: 39.944f;
double: 965.557f;
string: "_$\"\\\\'''\n\ta ыыы000;2;=:%d;```";

View File

@ -1,10 +0,0 @@
message:
{
type: "sent";
time: "15.12.2021 20:51:24 +03:00";
author_id: -293798876950036480;
channel_id: 913088838761603212;
message_id: 920734809096077353u;
text: "_$\"\\\\'''\n\ta ыыы000;2;=:%d;```";
den: -0.99f;
};

View File

@ -1,24 +0,0 @@
uints: [10,20,30,0,0 ];
floats: [8.2f,5.225f,-0.9993f];
strings: ["aaa","bbb","ccc"];
things: ["aaa",true,-122];
$complex: {
a:141;
b:00f;
c:false;
};
$complex: {
d:-1u;
e:005;
f:-1f;
};
list_of_lists: [ [ "sss" ] ];
blank_list: [];
qqq: [
{
},
{
q: 0.0f;
}
];

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
bool:b=false;
char:c='v';
string:s="hello";
byte:by=255;
sbyte:sb=-125;
short:sh=14003;
ushort:us=32025;
int:i=-2515;
uint:ui=0;
long:l=-29863854396;
ulong:ul=87659057946;
float:f=39.944;
double:do=965.557;
decimal:de=-84.20;

View File

@ -1 +0,0 @@
List<string>:list=[string:"a",string:"b"];

View File

@ -1,48 +0,0 @@
global using System;
global using System.Collections;
global using System.Collections.Generic;
global using System.Text;
global using System.Threading;
global using System.Threading.Tasks;
global using DTLib;
global using DTLib.Extensions;
global using DTLib.Filesystem;
global using DTLib.Dtsod;
global using static DTLib.Tests.TesterLog;
global using static DTLib.Tests.Program;
global using DTLib.Console;
global using DTLib.Logging;
namespace DTLib.Tests;
public static class Program
{
public static ILogger Logger = new CompositeLogger(new ConsoleLogger(),
new FileLogger("logs", "DTLib.Tests"))
{
DebugLogEnabled = true
};
public static void Main(string[] args)
{
System.Console.OutputEncoding = Encoding.UTF8;
System.Console.InputEncoding = Encoding.UTF8;
var mainContext = new ContextLogger("Main", Logger);
try
{
new LaunchArgumentParser().WithNoExit().ParseAndHandle(args);
TestDtsodV23.TestAll();
// TestPInvoke.TestAll();
// TestAutoarr.TestAll();
// TestDtsodV24.TestAll();
}
catch(LaunchArgumentParser.ExitAfterHelpException)
{ }
catch (Exception ex)
{ mainContext.LogError(ex); }
System.Console.ResetColor();
}
}

View File

@ -1,17 +0,0 @@
using System.Diagnostics;
namespace DTLib.Tests;
public static class TesterLog
{
public static void LogOperationTime(string op_name, int repeats, Action operation)
{
Stopwatch clock = new();
clock.Start();
for (int i = 0; i < repeats; i++)
operation();
clock.Stop();
double time=(double)(clock.ElapsedTicks)/Stopwatch.Frequency/repeats;
Logger.LogInfo(nameof(TesterLog), $"operation {op_name} lasted {time.ToString(MyTimeFormat.ForText)} seconds");
}
}

@ -1 +1 @@
Subproject commit 676d59bf80e99aa4fc1bc653aab7e6c88ecf916d
Subproject commit bcaa7a941104ce3f2bfa810b758d59728b77d4dd

View File

@ -5,14 +5,6 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTLib", "DTLib\DTLib.csproj", "{B620E5E9-800F-4B2D-B4A5-062E05DB704F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTLib.Tests", "DTLib.Tests\DTLib.Tests.csproj", "{72BA37EF-07EC-4D34-966A-20D5E83ADB32}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Dtsod", "DTLib.Dtsod\DTLib.Dtsod.csproj", "{ADE425F5-8645-47F0-9AA8-33FA748D36BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Network", "DTLib.Network\DTLib.Network.csproj", "{24B7D0A2-0462-424D-B3F5-29A6655FE472}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Logging", "DTLib.Logging\DTLib.Logging.csproj", "{00B76172-32BB-4B72-9891-47FAEF63386C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Ben.Demystifier", "DTLib.Ben.Demystifier\DTLib.Ben.Demystifier.csproj", "{AC7CB524-4D59-42E0-9F96-1C201A92494B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6308F24E-A4FF-46B3-B72F-30E05DDCB1D5}"
@ -26,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
push_packages.sh = push_packages.sh
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KerepWrapper", "KerepWrapper\KerepWrapper.csproj", "{9ADC4AA1-1DE4-4BB6-AF38-E84C1A142032}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.Logging.Microsoft", "DTLib.Logging.Microsoft\DTLib.Logging.Microsoft.csproj", "{9CCBAFA1-F191-4CEC-A4FA-CFF9F6CA081F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib.XXHash", "DTLib.XXHash\DTLib.XXHash\DTLib.XXHash.csproj", "{C7029741-816D-41B2-A2C4-E20565B1739D}"
@ -42,30 +32,10 @@ Global
{B620E5E9-800F-4B2D-B4A5-062E05DB704F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B620E5E9-800F-4B2D-B4A5-062E05DB704F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B620E5E9-800F-4B2D-B4A5-062E05DB704F}.Release|Any CPU.Build.0 = Release|Any CPU
{72BA37EF-07EC-4D34-966A-20D5E83ADB32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72BA37EF-07EC-4D34-966A-20D5E83ADB32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72BA37EF-07EC-4D34-966A-20D5E83ADB32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72BA37EF-07EC-4D34-966A-20D5E83ADB32}.Release|Any CPU.Build.0 = Release|Any CPU
{ADE425F5-8645-47F0-9AA8-33FA748D36BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADE425F5-8645-47F0-9AA8-33FA748D36BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADE425F5-8645-47F0-9AA8-33FA748D36BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADE425F5-8645-47F0-9AA8-33FA748D36BE}.Release|Any CPU.Build.0 = Release|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24B7D0A2-0462-424D-B3F5-29A6655FE472}.Release|Any CPU.Build.0 = Release|Any CPU
{00B76172-32BB-4B72-9891-47FAEF63386C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00B76172-32BB-4B72-9891-47FAEF63386C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00B76172-32BB-4B72-9891-47FAEF63386C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00B76172-32BB-4B72-9891-47FAEF63386C}.Release|Any CPU.Build.0 = Release|Any CPU
{AC7CB524-4D59-42E0-9F96-1C201A92494B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC7CB524-4D59-42E0-9F96-1C201A92494B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC7CB524-4D59-42E0-9F96-1C201A92494B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC7CB524-4D59-42E0-9F96-1C201A92494B}.Release|Any CPU.Build.0 = Release|Any CPU
{9ADC4AA1-1DE4-4BB6-AF38-E84C1A142032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9ADC4AA1-1DE4-4BB6-AF38-E84C1A142032}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9ADC4AA1-1DE4-4BB6-AF38-E84C1A142032}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9ADC4AA1-1DE4-4BB6-AF38-E84C1A142032}.Release|Any CPU.Build.0 = Release|Any CPU
{9CCBAFA1-F191-4CEC-A4FA-CFF9F6CA081F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CCBAFA1-F191-4CEC-A4FA-CFF9F6CA081F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CCBAFA1-F191-4CEC-A4FA-CFF9F6CA081F}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@ -74,7 +74,7 @@ public static class ColoredConsole
}
// ввод цветного текста
public static string Read(ConsoleColor color)
public static string? Read(ConsoleColor color)
{
System.Console.ForegroundColor = color;
var r = System.Console.ReadLine();
@ -82,5 +82,5 @@ public static class ColoredConsole
return r;
}
public static string Read(string color) => Read(ParseColor(color));
public static string? Read(string color) => Read(ParseColor(color));
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<!--package info-->
<PackageId>DTLib</PackageId>
<Version>1.3.4</Version>
<Version>1.4.0</Version>
<Authors>Timerix</Authors>
<Description>Library for all my C# projects</Description>
<RepositoryType>GIT</RepositoryType>
@ -11,21 +11,26 @@
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<!--language features-->
<LangVersion>12</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>disable</Nullable>
<Nullable>enable</Nullable>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!--project files-->
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<Compile Remove="Experimental\**" />
<!--external dependencies-->
<ItemGroup >
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Experimental\ConsoleGUI\**" />
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib.Ben.Demystifier\DTLib.Ben.Demystifier.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib.Ben.Demystifier" Version="1.0.7" />
</ItemGroup>
</Project>

View File

@ -5,7 +5,6 @@ public static class DtsodConverter
public static IDtsod ConvertVersion(IDtsod src, DtsodVersion targetVersion)
=> targetVersion switch
{
DtsodVersion.V21 => new DtsodV21(src.ToDictionary()),
DtsodVersion.V22 => throw new Exception("DtsodV22 is deprecated"),
DtsodVersion.V23 => new DtsodV23(src.ToDictionary()),
// DtsodVersion.V24 => new DtsodV24(src.ToDictionary()),

View File

@ -1,6 +1,6 @@
namespace DTLib.Dtsod;
public abstract class DtsodDict<TKey, TVal> : IDictionary<TKey, TVal>, IDictionary
public abstract class DtsodDict<TKey, TVal> : IDictionary<TKey, TVal>, IDictionary where TKey : notnull
{
// да, вместо собственной реализации интерфейса это ссылки на Dictionary
readonly Dictionary<TKey, TVal> baseDict;
@ -18,7 +18,7 @@ public abstract class DtsodDict<TKey, TVal> : IDictionary<TKey, TVal>, IDictiona
}
}
public virtual bool TryGetValue(TKey key, out TVal value) => baseDict.TryGetValue(key, out value);
public virtual bool TryGetValue(TKey key, out TVal value) => baseDict.TryGetValue(key, out value!);
public bool TrySetValue(TKey key, TVal value)
{
@ -34,7 +34,7 @@ public abstract class DtsodDict<TKey, TVal> : IDictionary<TKey, TVal>, IDictiona
public virtual void Add(KeyValuePair<TKey, TVal> pair)
=> ((ICollection<KeyValuePair<TKey, TVal>>)baseDict).Add(pair);
public void Add(object key, object value)
public void Add(object key, object? value)
{
((IDictionary) baseDict).Add(key, value);
}
@ -62,7 +62,7 @@ public abstract class DtsodDict<TKey, TVal> : IDictionary<TKey, TVal>, IDictiona
public ICollection<TVal> Values => baseDict.Values;
public bool IsReadOnly { get; } = false;
public object this[object key]
public object? this[object key]
{
get => ((IDictionary) baseDict)[key];
set => ((IDictionary) baseDict)[key] = value;

View File

@ -29,7 +29,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
{
string name = ReadName();
if (name.IsNullOrEmpty()) goto end;
dynamic value = ReadValue(out bool _);
var value = ReadValue(out bool _);
if (partOfDollarList)
{
if (!output.TryGetValue(name, out var dollarList))
@ -85,7 +85,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
: throw new Exception("DtsodV23.Deserialize.ReadName() error: end of text\ntext:\n" + _text);
}
dynamic ReadValue(out bool endOfList)
dynamic? ReadValue(out bool endOfList)
{
endOfList = false;
@ -160,7 +160,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
return list;
}
dynamic ParseValue(string value_str)
dynamic? ParseValue(string value_str)
{
switch (value_str)
{
@ -168,7 +168,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
case "false":
return value_str.ToBool();
case "null":
return null;
return null!;
default:
if (value_str.Contains('"'))
return value_str.Substring(1, value_str.Length - 2).Replace("\\\\","\\").Replace("\\\"","\"");
@ -220,7 +220,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
}
}
object value = null;
object? value = null;
while (++i < text.Length)
{
c = text[i];
@ -299,7 +299,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
{ typeof(decimal), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)).Append("de") }
};
protected StringBuilder Serialize(DtsodV23 dtsod, ref int tabscount, StringBuilder b = null)
protected StringBuilder Serialize(DtsodV23 dtsod, ref int tabscount, StringBuilder? b = null)
{
tabscount++;
b ??= new StringBuilder();

View File

@ -1,70 +0,0 @@
using System.Threading;
using DTLib.Console;
namespace DTLib.Experimental
{
public class CompressedArray
{
public class Array1D<T> where T : IComparable<T>
{
byte[] Description;
T[] Memory;
public Array1D() { }
public Array1D(T[] sourceArray) => CompressArray(sourceArray);
public void CompressArray(T[] sourceArray)
{
var listMem = new List<T>();
var listDesc = new List<byte>();
T prevElement = sourceArray[0];
listMem.Add(sourceArray[0]);
listDesc.Add(1);
byte repeats = 1;
for (int i = 1; i < sourceArray.Length; i++)
{
if (prevElement.CompareTo(sourceArray[i]) == 0)
repeats++;
else
{
listMem.Add(sourceArray[i]);
listDesc.Add(1);
if (repeats > 1)
{
listDesc[listDesc.Count - 2] = repeats;
repeats = 1;
}
}
prevElement = sourceArray[i];
}
Memory = listMem.ToArray();
Description = listDesc.ToArray();
ColoredConsole.Write("b", "listMem.Count: ", "c", listMem.Count.ToString(), "b", " listDesc.Count: ", "c",
$"{listDesc.Count}\n");
for (short i = 0; i < listDesc.Count; i++)
{
ColoredConsole.Write("y", $"{Description[i]}:{Memory[i]}\n");
}
}
// блокирует обращение к памяти из нескольких потоков
Mutex storageUsing = new();
// возвращает элемент по индексу так, как если бы шло обращение к обычном массиву
public T GetElement(int index)
{
storageUsing.WaitOne();
T output = default;
int sum = 0;
for (int i = 0; i < Description.Length; i++)
{
if (sum < index)
sum += Description[i];
else output = sum == index ? Memory[i] : Memory[i - 1];
}
storageUsing.ReleaseMutex();
return output;
}
}
}
}

View File

@ -1,69 +0,0 @@
using DTLib.Dtsod;
using DTLib.Filesystem;
using System.Collections.Generic;
using static DTLib.PublicLog;
namespace DTLib.ConsoleGUI
{
public class Container : List<IDrawable>, IDrawable
{
public (ushort x, ushort y) AnchorPoint { get; set; }
public ushort Width { get; set; }
public ushort Height { get; set; }
public char[] Textmap { get; private set; }
public char[] Colormap { get; private set; }
public string Name { get; private set; }
public Container(string name, string layout_file)
{
Name=name;
ParseLayoutFile(layout_file);
}
void ParseLayoutFile(string layout_file)
{
DtsodV22 layout = new(File.ReadAllText(layout_file));
AnchorPoint=(layout[Name]["anchor"][0], layout[Name]["anchor"][1]);
Width=layout[Name]["width"];
Height=layout[Name]["height"];
foreach(string element_name in layout[Name]["children"].Keys)
{
switch(layout[Name]["children"][element_name]["type"])
{
case "label":
Add(new Label(element_name,
layout[Name]["children"][element_name]["resdir"]+$"\\{element_name}.textmap",
layout[Name]["children"][element_name]["resdir"]+$"\\{element_name}.colormap")
{
AnchorPoint=(layout[Name]["children"][element_name]["anchor"][0],
layout[Name]["children"][element_name]["anchor"][1])
});
break;
}
}
}
public void GenTextmap()
{
Textmap=new char[Width*Height];
for(int i = 0; i<Textmap.Length; i++)
Textmap[i]=' ';
foreach(IDrawable element in this)
{
element.GenTextmap();
Log("m", $"Length: {element.Textmap.Length} calculated: {element.Width*element.Height}\n");
for(ushort y = 0; y<element.Height; y++)
for(ushort x = 0; x<element.Width; x++)
{
//Textmap[(element.AnchorPoint.y + y) * Width + element.AnchorPoint.x + x] = element.Textmap[y * element.Width + x];
Textmap[(y)*Width+x]=element.Textmap[y*element.Width+x];
}
}
}
public void GenColormap()
{
}
}
}

View File

@ -1,16 +0,0 @@
namespace DTLib.ConsoleGUI
{
public class Control : Label
{
public new void GenColormap()
{
}
public new void GenTextmap()
{
}
}
}

View File

@ -1,17 +0,0 @@
namespace DTLib.ConsoleGUI
{
public interface IDrawable
{
public (ushort x, ushort y) AnchorPoint { get; set; }
public ushort Width { get; }
public ushort Height { get; }
public char[] Textmap { get; }
public char[] Colormap { get; }
public string Name { get; }
public void GenTextmap();
public void GenColormap();
}
}

View File

@ -1,35 +0,0 @@
using DTLib.Filesystem;
namespace DTLib.ConsoleGUI
{
public class Label : IDrawable
{
public (ushort x, ushort y) AnchorPoint { get; set; } = (0, 0);
public ushort Width { get; private set; }
public ushort Height { get; private set; }
public char[] Textmap { get; private set; }
public char[] Colormap { get; private set; }
public string TextmapFile { get; set; }
public string ColormapFile { get; set; }
public string Name { get; init; }
public Label() { }
public Label(string name, string textmapFile, string colormapFile)
{
TextmapFile=textmapFile;
ColormapFile=colormapFile;
Name=name;
}
public void GenColormap() => Colormap=File.ReadAllText(ColormapFile).ToCharArray();
public void GenTextmap()
{
Textmap=File.ReadAllText(TextmapFile).ToCharArray();
Width=12;
Height=3;
}
}
}

View File

@ -1,36 +0,0 @@
using DTLib.Filesystem;
using System;
using System.Text;
namespace DTLib.ConsoleGUI
{
//
// создание gui из текста в консоли
//
public class Window : Container
{
public Window(string layout_file) : base("window", layout_file)
{
Console.Clear();
Console.SetWindowSize(Width+1, Height+1);
Console.SetBufferSize(Width+1, Height+1);
Console.OutputEncoding=Encoding.Unicode;
Console.InputEncoding=Encoding.Unicode;
Console.CursorVisible=false;
}
// выводит все символы
public void RenderFile(string file)
{
Console.Clear();
Console.WriteLine(File.ReadAllText(file));
}
public void Render()
{
GenTextmap();
Console.WriteLine(SimpleConverter.MergeToString(Textmap));
}
}
}

View File

@ -1,186 +0,0 @@
using DTLib.Filesystem;
using System;
using System.Collections.Generic;
using System.Text;
namespace DTLib.ConsoleGUI
{
//
// создание gui из текста в консоли
//
public class WindowOld
{
public int WindowWidth { get; private set; }
public int WindowHeight { get; private set; }
public char[,] Text;
public char[,] nowText;
public char[,] TextColors;
public char[,] nowTextColors;
public Container WindowContainer;
public WindowOld(int windowWidth, int windowHeight)
{
WindowWidth=windowWidth;
WindowHeight=windowHeight;
Text=new char[windowWidth, windowHeight];
TextColors=new char[windowWidth, windowHeight];
nowText=TextColors;
nowTextColors=new char[windowWidth, windowHeight];
Console.WindowWidth=WindowWidth+1;
Console.WindowHeight=WindowHeight+1;
Console.BufferWidth=WindowWidth+1;
Console.BufferHeight=WindowHeight+1;
Console.OutputEncoding=Encoding.Unicode;
Console.InputEncoding=Encoding.Unicode;
Console.CursorVisible=false;
// заполнение массивов
for(sbyte y = 0; y<WindowHeight; y++)
{
for(sbyte x = 0; x<WindowWidth; x++)
{
Text[x, y]=' ';
TextColors[x, y]='w';
}
}
nowText=TextColors;
}
/*// считывает массив символов из файла
// ширина и высота текста должны быть как указанные при инициализации объекта этого класса
public void ReadFromFile(string path)
{
var r = new StreamReader(path, SimpleConverter.UTF8);
char[] s = new char[1];
// считывание текста
sbyte y = 0, x = 0;
r.Read(s, 0, 1);
while (!r.EndOfStream && y < WindowHeight)
{
if (x == WindowWidth)
{
r.Read(s, 0, 1);
x = 0;
y++;
}
else
{
Text[x, y] = s[0];
x++;
}
r.Read(s, 0, 1);
}
r.Read(s, 0, 1);
// считывание цвета
// если не находит цвет в файле, оставляет старый
if (s[0] == '\n')
{
r.Read(s, 0, 1);
y = 0;
x = 0;
while (!r.EndOfStream && y < WindowHeight)
{
if (x == WindowWidth)
{
r.Read(s, 0, 1);
x = 0;
y++;
}
else
{
TextColors[x, y] = s[0];
x++;
}
r.Read(s, 0, 1);
}
}
r.Close();
}*/
public void ResetCursor() => Console.SetCursorPosition(0, WindowHeight);
// заменяет символ выведенный, использовать после ShowAll()
public void ChangeChar(sbyte x, sbyte y, char ch)
{
Text[x, y]=ch;
nowText[x, y]=ch;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(TextColors[x, y].ToString(), ch.ToString());
}
public void ChangeColor(sbyte x, sbyte y, char color)
{
TextColors[x, y]=color;
nowTextColors[x, y]=color;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(color.ToString(), Text[x, y].ToString());
}
public void ChangeCharAndColor(sbyte x, sbyte y, char color, char ch)
{
Text[x, y]=ch;
nowText[x, y]=ch;
TextColors[x, y]=color;
nowTextColors[x, y]=color;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(color.ToString(), ch.ToString());
}
public void ChangeLine(sbyte x, sbyte y, char color, string line)
{
Console.SetCursorPosition(x, y);
for(sbyte i = 0; i<line.Length; i++)
{
Text[x+i, y]=line[i];
nowText[x+i, y]=line[i];
TextColors[x+i, y]=color;
nowTextColors[x+i, y]=color;
}
ColoredConsole.Write(color.ToString(), line);
}
// выводит все символы
public void ShowAll()
{
var l = new List<string>();
for(sbyte y = 0; y<WindowHeight; y++)
{
for(sbyte x = 0; x<WindowWidth; x++)
{
l.Add(TextColors[x, y].ToString());
l.Add(Text[x, y].ToString());
nowText[x, y]=Text[x, y];
nowTextColors[x, y]=TextColors[x, y];
}
l.Add("w");
l.Add("\n");
}
ColoredConsole.Write(l.ToArray());
//Console.WriteLine();
}
public void UpdateAll()
{
for(sbyte y = 0; y<WindowHeight; y++)
{
for(sbyte x = 0; x<WindowWidth; x++)
{
Console.SetCursorPosition(x, y);
if(TextColors[x, y]!=nowTextColors[x, y]||Text[x, y]!=nowText[x, y])
{
ColoredConsole.Write(TextColors[x, y].ToString(), Text[x, y].ToString());
nowText[x, y]=Text[x, y];
nowTextColors[x, y]=TextColors[x, y];
}
}
Console.Write('\n');
}
}
public void RenderFile(string file)
{
Console.Clear();
Console.WriteLine(File.ReadAllText(file));
}
}
}

View File

@ -1,8 +0,0 @@
namespace DTLib.Experimental;
// по идее это нужно, чтоб делать так: SomeEvent?.Invoke().Wait()
public delegate Task EventHandlerAsyncDelegate();
public delegate Task EventHandlerAsyncDelegate<T>(T e);
public delegate Task EventHandlerAsyncDelegate<T0, T1>(T0 e0, T1 e1);
public delegate Task EventHandlerAsyncDelegate<T0, T1, T2>(T0 e0, T1 e1, T2 e2);
public delegate Task EventHandlerAsyncDelegate<T0, T1, T2, T3>(T0 e0, T1 e1, T2 e2, T3 e3);

View File

@ -1,45 +0,0 @@
using System.IO;
namespace DTLib.Experimental;
public class FileInstance
{
public enum FileOpenMode
{
// open a file for reading
Read=1,
// (re)create a file for writing
Write=2,
// opens file for writing additional data to the end / creates new file
Append=4,
// (re)creates file for reading/writing
ReadWrite=Read|Write,
// opens file for readng/writing additional data to the end / creates new file
ReadAppend=Read|Append
}
public readonly FileOpenMode Mode;
public readonly FileStream Stream;
public string Name;
public FileInstance(string path, FileOpenMode mode)
{
if (path.IsNullOrEmpty())
throw new NullReferenceException("path is null");
if(!System.IO.File.Exists(path))
{
if (mode == FileOpenMode.Read)
throw new Exception($"file <{path}> is not found");
}
Mode = mode;
Stream = mode switch
{
FileOpenMode.Read => System.IO.File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),
FileOpenMode.Write => System.IO.File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite),
FileOpenMode.Append => System.IO.File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite),
FileOpenMode.ReadWrite => System.IO.File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite),
FileOpenMode.ReadAppend => System.IO.File.Open(path, FileMode.Append, FileAccess.ReadWrite, FileShare.ReadWrite),
_ => throw new Exception($"unknown file mode: {mode}")
};
}
}

View File

@ -1,96 +0,0 @@
namespace DTLib.Experimental.Reactive
{
public class ReactiveListener<T> : ReactiveProvider<T>
{
public ReactiveListener() { }
public ReactiveListener(ReactiveStream<T> stream) : base(stream) { }
public ReactiveListener(ICollection<ReactiveStream<T>> streams) : base(streams) { }
public event Action<ReactiveStream<T>, T> ElementAddedEvent;
void ElementAdded(ReactiveStream<T> stream, TimeSignedObject<T> e) => ElementAdded(stream, e.Value);
void ElementAdded(ReactiveStream<T> stream, T e) =>
Task.Run(() => ElementAddedEvent?.Invoke(stream, e));
public override void Join(ReactiveStream<T> stream)
{
base.Join(stream);
lock (Streams) stream.ElementAddedEvent += ElementAdded;
}
public override void Leave(ReactiveStream<T> stream)
{
base.Leave(stream);
lock (Streams) stream.ElementAddedEvent -= ElementAdded;
}
public T GetFirst()
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
TimeSignedObject<T> rezult = null;
foreach (ReactiveStream<T> stream in Streams)
if (stream.Count != 0)
{
TimeSignedObject<T> e = stream[0];
if (rezult is null) rezult = e;
else if (rezult.Time > e.Time) rezult = e;
}
return rezult.Value;
}
public T GetLast()
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
TimeSignedObject<T> rezult = null;
foreach (ReactiveStream<T> stream in Streams)
if (stream.Count != 0)
{
TimeSignedObject<T> e = stream[stream.Count - 1];
if (rezult is null) rezult = e;
else if (rezult.Time < e.Time) rezult = e;
}
return rezult.Value;
}
public T FindOne(Func<T, bool> condition)
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
foreach (ReactiveStream<T> stream in Streams)
foreach (TimeSignedObject<T> el in stream)
if (condition(el.Value))
return el.Value;
return default;
}
public TimeSignedObject<T> FindOne(Func<TimeSignedObject<T>, bool> condition)
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
foreach (ReactiveStream<T> stream in Streams)
foreach (TimeSignedObject<T> el in stream)
if (condition(el))
return el;
return default;
}
public List<T> FindAll(Func<T, bool> condition)
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
List<T> rezults = new();
foreach (ReactiveStream<T> stream in Streams)
foreach (TimeSignedObject<T> el in stream)
if (condition(el.Value))
rezults.Add(el.Value);
return rezults;
}
public List<TimeSignedObject<T>> FindAll(Func<TimeSignedObject<T>, bool> condition)
{
if (Streams.Count == 0) throw new Exception("ReactiveListener is not connected to any streams");
List<TimeSignedObject<T>> rezults = new();
foreach (ReactiveStream<T> stream in Streams)
foreach (TimeSignedObject<T> el in stream)
if (condition(el))
rezults.Add(el);
return rezults;
}
}
}

View File

@ -1,31 +0,0 @@
namespace DTLib.Experimental.Reactive
{
public abstract class ReactiveProvider<T>
{
protected List<ReactiveStream<T>> Streams
{
get
{ lock (_streams) return _streams; }
set
{ lock (_streams) _streams = value; }
}
private List<ReactiveStream<T>> _streams = new();
public ReactiveProvider() { }
public ReactiveProvider(ReactiveStream<T> stream) => Streams.Add(stream);
public ReactiveProvider(ICollection<ReactiveStream<T>> streams) => Streams = streams.ToList();
public virtual void Join(ReactiveStream<T> stream)
{
if (IsConnetcedTo(stream)) throw new Exception("ReactiveListener is already connected to the stream");
Streams.Add(stream);
}
public virtual void Leave(ReactiveStream<T> stream)
{
if (!Streams.Remove(stream)) throw new Exception("ReactiveListener is not connected to the stream");
}
public bool IsConnetcedTo(ReactiveStream<T> stream) => Streams.Contains(stream);
}
}

View File

@ -1,16 +0,0 @@
namespace DTLib.Experimental.Reactive
{
public class ReactiveSender<T> : ReactiveProvider<T>
{
public ReactiveSender() { }
public ReactiveSender(ReactiveStream<T> stream) : base(stream) { }
public ReactiveSender(ICollection<ReactiveStream<T>> streams) : base(streams) { }
public void Send(T e)
{
foreach (ReactiveStream<T> s in Streams)
s.Add(e);
}
}
}

View File

@ -1,68 +0,0 @@
namespace DTLib.Experimental.Reactive
{
public class ReactiveStream<T> : IList<TimeSignedObject<T>>
{
List<TimeSignedObject<T>> _storage = new();
List<TimeSignedObject<T>> Storage
{
get
{ lock (_storage) return _storage; }
}
public int Count => Storage.Count;
public TimeSignedObject<T> this[int index]
{
get => Storage[index];
set => throw new NotImplementedException();
}
public event Action<ReactiveStream<T>, TimeSignedObject<T>> ElementAddedEvent;
public void Add(TimeSignedObject<T> elem)
{
Storage.Add(elem);
ElementAddedEvent?.Invoke(this, elem);
}
public void Add(T elem) => Add(new TimeSignedObject<T>(elem));
public void Clear() => Storage.Clear();
public int IndexOf(TimeSignedObject<T> item) => Storage.IndexOf(item);
public bool Contains(TimeSignedObject<T> item) => Storage.Contains(item);
public IEnumerator<TimeSignedObject<T>> GetEnumerator() => new Enumerator(Storage);
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(Storage);
struct Enumerator : IEnumerator<TimeSignedObject<T>>
{
public Enumerator(List<TimeSignedObject<T>> storage)
{
_storage = storage;
_index = storage.Count - 1;
}
List<TimeSignedObject<T>> _storage;
int _index;
public TimeSignedObject<T> Current => _storage[_index];
object IEnumerator.Current => Current;
public void Dispose() => _storage = null;
public bool MoveNext()
{
if (_index < 0)
return false;
_index--;
return true;
}
public void Reset() => _index = _storage.Count - 1;
}
bool ICollection<TimeSignedObject<T>>.IsReadOnly { get; } = false;
public void Insert(int index, TimeSignedObject<T> item) => throw new NotImplementedException();
public void RemoveAt(int index) => throw new NotImplementedException();
public void CopyTo(TimeSignedObject<T>[] array, int arrayIndex) => throw new NotImplementedException();
public bool Remove(TimeSignedObject<T> item) => throw new NotImplementedException();
}
}

View File

@ -1,14 +0,0 @@
namespace DTLib.Experimental.Reactive
{
public class TimeSignedObject<T>
{
public T Value { get; init; }
public long Time { get; init; }
public TimeSignedObject(T value)
{
Value = value;
Time = DateTime.Now.Ticks;
}
}
}

View File

@ -1,35 +0,0 @@
namespace DTLib.Experimental
{
//
// Вычисление псевдослучайного числа из множества параметров.
// Работает медленнее чем класс System.Random, но выдаёт более случайные значения
//
public class SecureRandom
{
/*private RNGCryptoServiceProvider crypt = new();
// получение массива случайных байтов
public byte[] GenBytes(uint length)
{
byte[] output = new byte[length];
crypt.GetNonZeroBytes(output);
return output;
}
// получение случайного числа от 0 до 2147483647
public int NextInt(uint from, int to)
{
int output = 0;
int rez = 0;
while (true)
{
rez = output * 10 + NextBytes(1)[0];
if (rez < to && rez > from)
{
output = rez;
return output;
}
}
}*/
}
}

View File

@ -1,9 +0,0 @@
using System.ComponentModel;
// включает init и record из c# 9.0
#if !NET6_0 && !NET7_0 && !NET8_0
namespace System.Runtime.CompilerServices;
[EditorBrowsable(EditorBrowsableState.Never)]
public class IsExternalInit { }
#endif

View File

@ -1,4 +1,4 @@
#if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
#if NETSTANDARD2_1
namespace DTLib.Extensions;
public static class SpanHelper

View File

@ -32,7 +32,7 @@ public static class Directory
Copy_internal(sourceDir, newDir, owerwrite, conflicts);
}
private static void Copy_internal(IOPath sourceDir, IOPath newDir, bool owerwrite, List<IOPath> conflicts)
private static void Copy_internal(IOPath sourceDir, IOPath newDir, bool owerwrite, List<IOPath>? conflicts)
{
bool countConflicts = conflicts is not null;
List<IOPath> files = GetAllFiles(sourceDir);
@ -41,7 +41,7 @@ public static class Directory
{
var newfile = files[i].ReplaceBase(sourceDir, newDir);
if (countConflicts && File.Exists(newfile))
conflicts.Add(newfile);
conflicts!.Add(newfile);
File.Copy(files[i], newfile, owerwrite);
}
}
@ -86,7 +86,7 @@ public static class Directory
all_subdirs = new List<IOPath>();
return GetAllFiles_internal(dir, all_subdirs);
}
private static List<IOPath> GetAllFiles_internal(IOPath dir, List<IOPath> all_subdirs)
private static List<IOPath> GetAllFiles_internal(IOPath dir, List<IOPath>? all_subdirs)
{
bool rememberSubdirs = all_subdirs is not null;
var all_files = new List<IOPath>();
@ -97,7 +97,7 @@ public static class Directory
for (int i = 0; i < cur_subdirs.Length; i++)
{
if(rememberSubdirs)
all_subdirs.Add(cur_subdirs[i]);
all_subdirs?.Add(cur_subdirs[i]);
all_files.AddRange(GetAllFiles_internal(cur_subdirs[i], all_subdirs));
}
return all_files;

View File

@ -5,14 +5,14 @@ namespace DTLib.Filesystem;
public static class EmbeddedResources
{
public static Stream GetResourceStream(string resourcePath, Assembly assembly = null)
public static Stream GetResourceStream(string resourcePath, Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
return assembly.GetManifestResourceStream(resourcePath)
?? throw new Exception($"embedded resource <{resourcePath}> not found in assembly {assembly.FullName}");
}
public static byte[] ReadBynary(string resourcePath, Assembly assembly = null)
public static byte[] ReadBynary(string resourcePath, Assembly? assembly = null)
{
// is required to get the Assembly called ReadBynary
// otherwise Assembly.GetCallingAssembly() in GetResourceStream will get DTLib assembly always
@ -22,14 +22,14 @@ public static class EmbeddedResources
}
public static string ReadText(string resourcePath, Assembly assembly = null)
public static string ReadText(string resourcePath, Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
using var reader = new StreamReader(GetResourceStream(resourcePath, assembly));
return reader.ReadToEnd();
}
public static void CopyToFile(string resourcePath, string filePath, Assembly assembly = null)
public static void CopyToFile(string resourcePath, string filePath, Assembly? assembly = null)
{
assembly ??= Assembly.GetCallingAssembly();
using var file = File.OpenWrite(filePath);

View File

@ -1,4 +1,4 @@
#if NETSTANDARD2_1 || NET6_0 || NET7_0 || NET8_0
#if NETSTANDARD2_1
#define USE_SPAN
#endif
@ -63,7 +63,7 @@ public readonly struct IOPath
public static explicit operator string(IOPath p) => p.Str;
public override string ToString() => Str;
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is null) return false;
return Str == obj.ToString();

View File

@ -1,56 +0,0 @@
namespace DTLib.Filesystem;
//
// некоторые старые методы, которые хорошо бы вырезать
//
public static class OldFilework
{
// чтение параметров из конфига
public static string ReadFromConfig(string configfile, string key)
{
lock (new object())
{
key += ": ";
using var reader = new System.IO.StreamReader(configfile);
while (!reader.EndOfStream)
{
string st = reader.ReadLine();
if (st.StartsWith(key))
{
string value = "";
for (int i = key.Length; i < st.Length; i++)
{
if (st[i] == '#')
return value;
if (st[i] == '%')
{
bool stop = false;
string placeholder = "";
i++;
while (!stop)
{
if (st[i] == '%')
{
stop = true;
value += ReadFromConfig(configfile, placeholder);
}
else
{
placeholder += st[i];
i++;
}
}
}
else
value += st[i];
}
reader.Close();
//if (value.NullOrEmpty()) throw new System.Exception($"ReadFromConfig({configfile}, {key}) error: key not found");
return value;
}
}
reader.Close();
throw new Exception($"ReadFromConfig({configfile}, {key}) error: key not found");
}
}
}

9
DTLib/InitSetterFix.cs Normal file
View File

@ -0,0 +1,9 @@
// включает init и record из c# 9.0
#if NETSTANDARD
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
public class IsExternalInit { }
}
#endif

View File

@ -1,99 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace KerepWrapper.Autoarr;
public class Autoarr<T> : IEnumerable<T>, IDisposable where T : struct
{
public readonly IntPtr UnmanagedPtr;
//if true, destructor frees allocated unmanaged memory
public bool AutoDispose;
private readonly AutoarrFunctions<T> Funcs;
public readonly uint MaxLength;
public uint Length { get; private set; }
public Autoarr(IntPtr ptr, bool autoDispose)
{
AutoDispose = autoDispose;
Funcs = AutoarrFunctions<T>.GetFunctions();
UnmanagedPtr = ptr;
MaxLength = Funcs.MaxLength(UnmanagedPtr);
Length = Funcs.Length(UnmanagedPtr);
}
public Autoarr(ushort blockCount, ushort blockLength, bool autoDispose=true)
{
AutoDispose = autoDispose;
Funcs = AutoarrFunctions<T>.GetFunctions();
UnmanagedPtr = Funcs.Create(blockCount, blockLength);
MaxLength = Funcs.MaxLength(UnmanagedPtr);
Length = Funcs.Length(UnmanagedPtr);
}
public T this[uint i]
{
get
{
if (i < Length) return Funcs.Get(UnmanagedPtr, i);
throw new IndexOutOfRangeException($"index {i} >= Autoarr.Length {Length}");
}
set
{
if (i < Length) Funcs.Set(UnmanagedPtr, i, value);
else throw new IndexOutOfRangeException($"index {i} >= Autoarr.Length {Length}");
}
}
public void Dispose()
{
if(AutoDispose)
Funcs.Free(UnmanagedPtr);
}
public IEnumerator<T> GetEnumerator() => new AutoarrEnumerator(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void Add(T value)
{
if (Length < MaxLength)
{
Funcs.Add(UnmanagedPtr, value);
Length++;
}
else throw new IndexOutOfRangeException($"Autoarr.Length == MaxLength ({MaxLength})");
}
~Autoarr()
{
if (AutoDispose) Dispose();
}
private class AutoarrEnumerator : IEnumerator<T>
{
private readonly Autoarr<T> arr;
private uint index;
public AutoarrEnumerator(Autoarr<T> ar) => arr = ar;
public T Current { get; private set; }
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext()
{
if (index >= arr.Length) return false;
Current = arr[index];
index++;
return true;
}
public void Reset()
{
index = 0;
}
}
}

View File

@ -1,38 +0,0 @@
using System;
using DTLib;
using KerepWrapper.KerepTypes;
namespace KerepWrapper.Autoarr;
using AutoarrPtr=DtsodPtr;
public abstract class AutoarrFunctions<T>
{
static AutoarrFunctions()
{
DependencyResolver.CopyLibs();
}
internal abstract AutoarrPtr Create(ushort maxBlocksCount, ushort maxBlockLength);
internal abstract void Free(AutoarrPtr ar);
internal abstract T Get(AutoarrPtr ar, uint index);
internal abstract void Add(AutoarrPtr ar, T element);
internal abstract void Set(AutoarrPtr ar, uint index, T element);
internal abstract uint Length(AutoarrPtr ar);
internal abstract uint MaxLength(AutoarrPtr ar);
private static AutoarrFunctions<Unitype> f_uni = new AutoarrUnitypeFunctions();
private static AutoarrFunctions<KVPair> f_kvp = new AutoarrKVPairFunctions();
static internal AutoarrFunctions<T> GetFunctions()
{
if (f_kvp is AutoarrFunctions<T> f)
return f;
else if (f_uni is AutoarrFunctions<T> ff)
return ff;
else throw new Exception($"unsupported type: {typeof(T)}");
/*if (typeof(T) == typeof(Unitype))
return (AutoarrFunctions<T>)Convert.ChangeType(f_uni, typeof(AutoarrFunctions<T>));
else if (typeof(T) == typeof(KVPair))
return (AutoarrFunctions<T>) Convert.ChangeType(f_kvp, typeof(AutoarrFunctions<T>));
else throw new Exception($"unsupported type: {typeof(T)}");*/
}
}

View File

@ -1,52 +0,0 @@
using System.Runtime.InteropServices;
using KerepWrapper.KerepTypes;
namespace KerepWrapper.Autoarr;
internal class AutoarrKVPairFunctions : AutoarrFunctions<KVPair>
{
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_KVPair_create(ushort max_blocks_count, ushort max_block_length, out AutoarrKVPairPtr output);
internal override AutoarrKVPairPtr Create(ushort maxBlocksCount, ushort maxBlockLength)
{
kerep_Autoarr_KVPair_create(maxBlocksCount, maxBlockLength, out var ar);
return ar;
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_KVPair_free(AutoarrKVPairPtr ar);
internal override void Free(AutoarrKVPairPtr ar) => kerep_Autoarr_KVPair_free(ar);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_KVPair_get(AutoarrKVPairPtr ar, uint index, out KVPair output);
internal override KVPair Get(AutoarrKVPairPtr ar, uint index)
{
kerep_Autoarr_KVPair_get(ar, index, out var output);
return output;
}
[DllImport("kerep",CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_KVPair_add(AutoarrKVPairPtr ar, KVPair element);
internal override void Add(AutoarrKVPairPtr ar, KVPair element) => kerep_Autoarr_KVPair_add(ar, element);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_KVPair_set(AutoarrKVPairPtr ar, uint index, KVPair element);
internal override void Set(AutoarrKVPairPtr ar, uint index, KVPair element) =>
kerep_Autoarr_KVPair_set(ar, index, element);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_KVPair_length(AutoarrKVPairPtr ar, out uint output);
internal override uint Length(AutoarrKVPairPtr ar)
{
kerep_Autoarr_KVPair_length(ar, out var l);
return l;
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_KVPair_max_length(AutoarrKVPairPtr ar, out uint output);
internal override uint MaxLength(AutoarrKVPairPtr ar)
{
kerep_Autoarr_KVPair_max_length(ar, out var l);
return l;
}
}

View File

@ -1,52 +0,0 @@
using System.Runtime.InteropServices;
using KerepWrapper.KerepTypes;
namespace KerepWrapper.Autoarr;
internal class AutoarrUnitypeFunctions : AutoarrFunctions<Unitype>
{
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_Unitype_create(ushort max_blocks_count, ushort max_block_length, out AutoarrUnitypePtr output);
internal override AutoarrUnitypePtr Create(ushort maxBlocksCount, ushort maxBlockLength)
{
kerep_Autoarr_Unitype_create(maxBlocksCount, maxBlockLength, out var ar);
return ar;
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_Unitype_free(AutoarrUnitypePtr ar);
internal override void Free(AutoarrUnitypePtr ar) => kerep_Autoarr_Unitype_free(ar);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_Unitype_get(AutoarrUnitypePtr ar, uint index, out Unitype output);
internal override Unitype Get(AutoarrUnitypePtr ar, uint index)
{
kerep_Autoarr_Unitype_get(ar, index, out var output);
return output;
}
[DllImport("kerep",CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_Unitype_add(AutoarrUnitypePtr ar, Unitype element);
internal override void Add(AutoarrUnitypePtr ar, Unitype element) => kerep_Autoarr_Unitype_add(ar, element);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
internal static extern void kerep_Autoarr_Unitype_set(AutoarrUnitypePtr ar, uint index, Unitype element);
internal override void Set(AutoarrUnitypePtr ar, uint index, Unitype element) =>
kerep_Autoarr_Unitype_set(ar, index, element);
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_Unitype_length(AutoarrUnitypePtr ar, out uint output);
internal override uint Length(AutoarrUnitypePtr ar)
{
kerep_Autoarr_Unitype_length(ar, out var l);
return l;
}
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_Autoarr_Unitype_max_length(AutoarrUnitypePtr ar, out uint output);
internal override uint MaxLength(AutoarrUnitypePtr ar)
{
kerep_Autoarr_Unitype_max_length(ar, out var l);
return l;
}
}

View File

@ -1,115 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using DTLib.Dtsod;
using DTLib.Extensions;
using KerepWrapper.KerepTypes;
using KerepWrapper.Autoarr;
using Funcs=KerepWrapper.Dtsod.DtsodV24Functions;
namespace KerepWrapper.Dtsod;
public class DtsodV24 : IDtsod, IEnumerable<KVPair>, IDisposable
{
public DtsodVersion Version => DtsodVersion.V24;
public readonly DtsodPtr UnmanagedPtr;
//if true, destructor frees allocated unmanaged memory
public bool AutoDispose = true;
public ushort Height => Funcs.Height(UnmanagedPtr);
public DtsodV24(DtsodPtr ptr) => UnmanagedPtr = ptr;
public DtsodV24(string text, bool autoDispose = true) : this(Funcs.Deserialize(text))
=> AutoDispose = autoDispose;
public DtsodV24(bool autoDispose=true) : this(" ", autoDispose) { }
public DtsodV24(IDictionary<string,dynamic> dict, bool autoDispose=true) : this(autoDispose)
{
foreach (KeyValuePair<string, dynamic> pair in dict)
{
if (pair.Value is not null) AddOrSet(pair.Key, pair.Value);
//else Log("y", $"skiping key <{pair.Key}> with null value");
}
}
public IDictionary<string, dynamic> ToDictionary()
{
Dictionary<string, dynamic> dict = new();
foreach (var p in this)
dict.Add(p.key.HGlobalUTF8ToString(),p.value.ToDynamic());
return dict;
}
public bool TryGet(string key, out dynamic elem)
{
var g = Funcs.Get(UnmanagedPtr, key);
elem = g.ToDynamic();
return g.TypeCode == KerepTypeCode.Null;
}
public void AddOrSet(string key, dynamic value) =>
Funcs.AddOrSet(UnmanagedPtr, key, new Unitype(value));
public dynamic this[string key]
{
get
{
if (!TryGet(key, out var v)) throw new KeyNotFoundException($"key <{key}> not found");
return v;
}
set => AddOrSet(key, value);
}
public bool TryRemove(string key) => Funcs.Remove(UnmanagedPtr,key);
[Obsolete("do you really need to use this? look at TryGet/TryRemove/AddOrSet")]
public bool ContainsKey(string key) => Funcs.Contains(UnmanagedPtr, key);
public override string ToString() => Funcs.Serialize(UnmanagedPtr);
public void Dispose() => Funcs.Free(UnmanagedPtr);
~DtsodV24()
{
if(AutoDispose) Dispose();
}
public IEnumerator<KVPair> GetEnumerator() => new DtsodV24Enumerator(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
class DtsodV24Enumerator: IEnumerator<KVPair>
{
private readonly DtsodV24 d;
private ushort h;
private IEnumerator<KVPair> arEnumerator;
public DtsodV24Enumerator(DtsodV24 _d) => d = _d;
bool NextAr()
{
if (h >= Funcs.Height(d.UnmanagedPtr)) return false;
var ar = new Autoarr<KVPair>(Funcs.GetRow(d.UnmanagedPtr, h), false);
arEnumerator = ar.GetEnumerator();
h++;
return true;
}
public bool MoveNext()
{
if(arEnumerator==null)
NextAr();
while(!arEnumerator.MoveNext())
if(!NextAr()) return false;
Current = arEnumerator.Current;
return true;
}
public void Reset() => h = 0;
public KVPair Current { get; private set; }
object IEnumerator.Current => Current;
public void Dispose() { }
}
}

View File

@ -1,110 +0,0 @@
global using DtsodPtr=System.IntPtr;
global using AutoarrKVPairPtr=System.IntPtr;
global using AutoarrUnitypePtr=System.IntPtr;
global using CharPtr=System.IntPtr;
using System;
using System.Runtime.InteropServices;
using DTLib;
using DTLib.Extensions;
using KerepWrapper.KerepTypes;
namespace KerepWrapper.Dtsod;
internal static class DtsodV24Functions
{
private const string kereplib = "kerep";
static DtsodV24Functions()
{
DependencyResolver.CopyLibs();
}
static void TryThrowErrmsg(CharPtr err)
{
if (err == IntPtr.Zero) return;
string errmsg = Unmanaged.HGlobalUTF8ToString(err);
Marshal.FreeHGlobal(err);
throw new Exception(errmsg);
}
//parses text to binary values
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_deserialize(string text, out DtsodPtr output, out CharPtr errmsg);
internal static DtsodPtr Deserialize(string text)
{
kerep_DtsodV24_deserialize(text, out var dtsod,out var err);
TryThrowErrmsg(err);
return dtsod;
}
//creates text representation of dtsod
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_serialize(DtsodPtr dtsod, out CharPtr output, out CharPtr errmsg);
internal static string Serialize(DtsodPtr dtsod)
{
kerep_DtsodV24_serialize(dtsod, out var text, out var err);
TryThrowErrmsg(err);
return Unmanaged.HGlobalUTF8ToString(text);
}
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_get(DtsodPtr dtsod, string key, out Unitype output);
//returns value or UniNull if key not found
internal static Unitype Get(DtsodPtr dtsod, string key)
{
kerep_DtsodV24_get(dtsod, key, out var output);
return output;
}
[DllImport(kereplib,EntryPoint = "kerep_DtsodV24_addOrSet",CallingConvention = CallingConvention.Cdecl)]
//adds or sets value
static extern void kerep_DtsodV24_addOrSet(DtsodPtr dtsod, IntPtr key, Unitype value);
internal static void AddOrSet(DtsodPtr dtsod, string key, Unitype value)
{
IntPtr keyptr = key.StringToHGlobalUTF8();
kerep_DtsodV24_addOrSet(dtsod, keyptr, value);
}
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
//checks for dtsod contains value or dont
static extern void kerep_DtsodV24_contains(DtsodPtr dtsod, string key, [MarshalAs(UnmanagedType.I1)] out bool output);
internal static bool Contains(DtsodPtr dtsod, string key)
{
kerep_DtsodV24_contains(dtsod, key, out var output);
return output;
}
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_remove(DtsodPtr dtsod, string key, [MarshalAs(UnmanagedType.I1)] out bool output);
//replaces value with UniNull if key exists in dtsod
internal static bool Remove(DtsodPtr dtsod, string key)
{
kerep_DtsodV24_remove(dtsod, key, out var output);
return output;
}
[DllImport(kereplib,EntryPoint="kerep_DtsodV24_free", CallingConvention = CallingConvention.Cdecl)]
//replaces value with UniNull if key exists in dtsod
internal static extern void Free(DtsodPtr dtsod);
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_height(DtsodPtr dtsod, out ushort heigth);
//returns current amounts of rows (Autoarrs of KVPairs) in hashtable
internal static ushort Height(DtsodPtr ptr)
{
kerep_DtsodV24_height(ptr, out var h);
return h;
}
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
static extern void kerep_DtsodV24_getrow(DtsodPtr dtsod, ushort h, out AutoarrKVPairPtr row);
//Returns row from hashtable.
//check current hashtable height before calling this.
internal static AutoarrKVPairPtr GetRow(DtsodPtr ptr, ushort height)
{
kerep_DtsodV24_getrow(ptr, height, out var rowptr);
return rowptr;
}
}

View File

@ -1,27 +0,0 @@
using System.Runtime.InteropServices;
using DTLib.Extensions;
namespace KerepWrapper.KerepTypes;
[StructLayout(LayoutKind.Sequential)]
public struct KVPair
{
public DtsodPtr key;
public Unitype value;
public KVPair(DtsodPtr k, Unitype v)
{
key = k;
value = v;
}
public KVPair(string k, Unitype v)
{
key = k.StringToHGlobalUTF8();
value = v;
}
public override string ToString()
{
return $"{{{Unmanaged.HGlobalUTF8ToString(key)}, {value}}}";
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
namespace KerepWrapper.KerepTypes;
public enum KerepTypeCode : byte
{
Null, Float32, Float64, Char, Bool,
UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
CharPtr, STNodePtr, HashtablePtr,
UniversalType,
AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
AutoarrUnitypePtr, AutoarrKVPairPtr
}
public static class KerepTypeHelper
{
static readonly Dictionary<Type, KerepTypeCode> type_comparsion_dict = new()
{
{typeof(bool), KerepTypeCode.Bool},
{typeof(byte), KerepTypeCode.UInt8},
{typeof(ushort), KerepTypeCode.UInt16},
{typeof(uint), KerepTypeCode.UInt32},
{typeof(ulong), KerepTypeCode.UInt64},
{typeof(sbyte), KerepTypeCode.Int8},
{typeof(short), KerepTypeCode.Int16},
{typeof(int), KerepTypeCode.Int32},
{typeof(long), KerepTypeCode.Int64},
{typeof(float), KerepTypeCode.Float32},
{typeof(double), KerepTypeCode.Float64},
{typeof(string), KerepTypeCode.CharPtr}
};
public static KerepTypeCode GetKerepTypeCode(object something)
{
if (type_comparsion_dict.TryGetValue(something.GetType(), out var ktype))
return ktype;
else return something switch
{
IList<object> => KerepTypeCode.AutoarrUnitypePtr,
IDictionary<string, object> => KerepTypeCode.HashtablePtr,
_ => throw new Exception($"can't get KerepTypeCode for type {something.GetType()}")
};
}
}

View File

@ -1,106 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using DTLib.Extensions;
using KerepWrapper.Autoarr;
using KerepWrapper.Dtsod;
namespace KerepWrapper.KerepTypes;
[StructLayout(LayoutKind.Explicit)]
public struct Unitype
{
[FieldOffset(0)] public long Int64;
[FieldOffset(0)] public ulong UInt64;
[FieldOffset(0)] public double Float64;
[MarshalAs(UnmanagedType.I1)]
[FieldOffset(0)] public bool Bool;
[FieldOffset(0)] public DtsodPtr VoidPtr;
[FieldOffset(8)] public KerepTypeCode TypeCode;
public Unitype(object v) : this()
{
TypeCode = KerepTypeHelper.GetKerepTypeCode(v);
switch (TypeCode)
{
case KerepTypeCode.Bool:
Bool = (bool) v;
break;
case KerepTypeCode.UInt8:
case KerepTypeCode.UInt16:
case KerepTypeCode.UInt32:
UInt64 = v.ToULong();
TypeCode = KerepTypeCode.UInt64;
break;
case KerepTypeCode.UInt64:
UInt64 = (ulong) v;
break;
case KerepTypeCode.Int8:
case KerepTypeCode.Int16:
case KerepTypeCode.Int32:
Int64 = v.ToLong();
TypeCode = KerepTypeCode.Int64;
break;
case KerepTypeCode.Int64:
Int64 = (long) v;
break;
case KerepTypeCode.Float32:
Float64 = v.ToDouble();
TypeCode = KerepTypeCode.Float64;
break;
case KerepTypeCode.Float64:
Float64 = (double) v;
break;
case KerepTypeCode.CharPtr:
VoidPtr = ((string)v).StringToHGlobalUTF8();
break;
case KerepTypeCode.AutoarrUnitypePtr:
TypeCode = KerepTypeCode.AutoarrUnitypePtr;
var ar = new Autoarr<Unitype>(64,1024,false);
foreach (var sub in (List<object>)v)
ar.Add(new Unitype(sub));
VoidPtr = ar.UnmanagedPtr;
break;
case KerepTypeCode.HashtablePtr:
TypeCode = KerepTypeCode.HashtablePtr;
var ht = new DtsodV24((IDictionary<string,object>)v,false);
VoidPtr = ht.UnmanagedPtr;
break;
default: throw new Exception($"can't box value of type {TypeCode}");
}
}
public dynamic ToDynamic()
{
switch (TypeCode)
{
case KerepTypeCode.Null: return null;
case KerepTypeCode.Bool: return Bool;
case KerepTypeCode.Int64: return Int64;
case KerepTypeCode.UInt64: return UInt64;
case KerepTypeCode.Float64: return Float64;
case KerepTypeCode.CharPtr: return VoidPtr.HGlobalUTF8ToString();
case KerepTypeCode.AutoarrUnitypePtr: return new Autoarr<Unitype>(VoidPtr, false);
case KerepTypeCode.AutoarrKVPairPtr: return new Autoarr<KVPair>(VoidPtr, false);
case KerepTypeCode.HashtablePtr: return new DtsodV24(VoidPtr);
default: throw new Exception($"can't unbox value of type {TypeCode}");
}
}
public override string ToString()
{
switch (TypeCode)
{
case KerepTypeCode.Null: return "{Null}";
case KerepTypeCode.Bool: return $"{{Bool:{Bool}}}";
case KerepTypeCode.Int64: return $"{{Int64:{Int64}}}";
case KerepTypeCode.UInt64: return $"{{UInt64:{UInt64}}}";
case KerepTypeCode.Float64: return $"{{Float64:{Float64}}}";
case KerepTypeCode.CharPtr: return $"{{CharPtr:{Unmanaged.HGlobalUTF8ToString(VoidPtr)}}}";
case KerepTypeCode.AutoarrUnitypePtr: return $"{{AutoarrUnitypePtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.AutoarrKVPairPtr: return $"{{AutoarrKVPairPtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.HashtablePtr: return $"{{HashtablePtr:{VoidPtr.ToString()}}}";
default: throw new Exception($"can't unbox value of type {TypeCode}");
}
}
}

View File

@ -1,48 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--package info-->
<PackageId>KerepWrapper</PackageId>
<Version>0.2.0</Version>
<Authors>Timerix</Authors>
<Description>Definitely not json</Description>
<RepositoryType>GIT</RepositoryType>
<RepositoryUrl>https://github.com/Timerix22/DTLib</RepositoryUrl>
<PackageProjectUrl>https://github.com/Timerix22/DTLib</PackageProjectUrl>
<Configuration>Release</Configuration>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<!--compilation properties-->
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<!--language features-->
<LangVersion>12</LangVersion>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
<!--external dependencies-->
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup>
<!--DTLib dependencies-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\DTLib\DTLib.csproj" />
<ProjectReference Include="..\DTLib.Dtsod\DTLib.Dtsod.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.3.4" />
<PackageReference Include="DTLib.Dtsod" Version="1.3.4" />
</ItemGroup>
<!--project files-->
<ItemGroup>
<Content Include="runtimes\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Pack>true</Pack>
<PackagePath>runtimes/</PackagePath>
</Content>
<Compile Remove="Experimental/**/*" />
<None Include="Experimental/**/*" />
</ItemGroup>
</Project>

View File

@ -22,12 +22,9 @@ function create_package() {
}
set +x
create_package DTLib
create_package DTLib.Ben.Demystifier
create_package DTLib.Dtsod
create_package DTLib.Logging
create_package DTLib.Logging.Microsoft
create_package DTLib.Network
create_package DTLib.XXHash
create_package DTLib
create_package DTLib.Logging.Microsoft
ls -lh nuget