diff --git a/ZeroLevel.Discovery/DiscoveryService.cs b/Apps/ZeroLevel.Discovery/DiscoveryService.cs similarity index 100% rename from ZeroLevel.Discovery/DiscoveryService.cs rename to Apps/ZeroLevel.Discovery/DiscoveryService.cs diff --git a/ZeroLevel.Discovery/Program.cs b/Apps/ZeroLevel.Discovery/Program.cs similarity index 100% rename from ZeroLevel.Discovery/Program.cs rename to Apps/ZeroLevel.Discovery/Program.cs diff --git a/ZeroLevel.Discovery/Properties/PublishProfiles/FolderProfile.pubxml b/Apps/ZeroLevel.Discovery/Properties/PublishProfiles/FolderProfile.pubxml similarity index 100% rename from ZeroLevel.Discovery/Properties/PublishProfiles/FolderProfile.pubxml rename to Apps/ZeroLevel.Discovery/Properties/PublishProfiles/FolderProfile.pubxml diff --git a/ZeroLevel.Discovery/ServiceEndpointsTable.cs b/Apps/ZeroLevel.Discovery/ServiceEndpointsTable.cs similarity index 100% rename from ZeroLevel.Discovery/ServiceEndpointsTable.cs rename to Apps/ZeroLevel.Discovery/ServiceEndpointsTable.cs diff --git a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj b/Apps/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj similarity index 85% rename from ZeroLevel.Discovery/ZeroLevel.Discovery.csproj rename to Apps/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj index e6651e9..2b9352f 100644 --- a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj +++ b/Apps/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj @@ -12,7 +12,7 @@ - + diff --git a/ZeroLevel.Discovery/app.config b/Apps/ZeroLevel.Discovery/app.config similarity index 100% rename from ZeroLevel.Discovery/app.config rename to Apps/ZeroLevel.Discovery/app.config diff --git a/ZeroLevel.Logger/App.config b/Apps/ZeroLevel.Logger/App.config similarity index 100% rename from ZeroLevel.Logger/App.config rename to Apps/ZeroLevel.Logger/App.config diff --git a/ZeroLevel.Logger/LogService.cs b/Apps/ZeroLevel.Logger/LogService.cs similarity index 100% rename from ZeroLevel.Logger/LogService.cs rename to Apps/ZeroLevel.Logger/LogService.cs diff --git a/ZeroLevel.Logger/Program.cs b/Apps/ZeroLevel.Logger/Program.cs similarity index 100% rename from ZeroLevel.Logger/Program.cs rename to Apps/ZeroLevel.Logger/Program.cs diff --git a/ZeroLevel.Logger/Properties/PublishProfiles/FolderProfile.pubxml b/Apps/ZeroLevel.Logger/Properties/PublishProfiles/FolderProfile.pubxml similarity index 100% rename from ZeroLevel.Logger/Properties/PublishProfiles/FolderProfile.pubxml rename to Apps/ZeroLevel.Logger/Properties/PublishProfiles/FolderProfile.pubxml diff --git a/ZeroLevel.Logger/ProxySample/LogMessage.cs b/Apps/ZeroLevel.Logger/ProxySample/LogMessage.cs similarity index 100% rename from ZeroLevel.Logger/ProxySample/LogMessage.cs rename to Apps/ZeroLevel.Logger/ProxySample/LogMessage.cs diff --git a/ZeroLevel.Logger/ProxySample/LogProxy.cs b/Apps/ZeroLevel.Logger/ProxySample/LogProxy.cs similarity index 100% rename from ZeroLevel.Logger/ProxySample/LogProxy.cs rename to Apps/ZeroLevel.Logger/ProxySample/LogProxy.cs diff --git a/ZeroLevel.Logger/ZeroLevel.Logger.csproj b/Apps/ZeroLevel.Logger/ZeroLevel.Logger.csproj similarity index 77% rename from ZeroLevel.Logger/ZeroLevel.Logger.csproj rename to Apps/ZeroLevel.Logger/ZeroLevel.Logger.csproj index f9b6f57..c24edfc 100644 --- a/ZeroLevel.Logger/ZeroLevel.Logger.csproj +++ b/Apps/ZeroLevel.Logger/ZeroLevel.Logger.csproj @@ -7,7 +7,7 @@ - + diff --git a/ZeroNetworkMonitor/App.xaml b/Apps/ZeroNetworkMonitor/App.xaml similarity index 100% rename from ZeroNetworkMonitor/App.xaml rename to Apps/ZeroNetworkMonitor/App.xaml diff --git a/ZeroNetworkMonitor/App.xaml.cs b/Apps/ZeroNetworkMonitor/App.xaml.cs similarity index 100% rename from ZeroNetworkMonitor/App.xaml.cs rename to Apps/ZeroNetworkMonitor/App.xaml.cs diff --git a/ZeroNetworkMonitor/AssemblyInfo.cs b/Apps/ZeroNetworkMonitor/AssemblyInfo.cs similarity index 100% rename from ZeroNetworkMonitor/AssemblyInfo.cs rename to Apps/ZeroNetworkMonitor/AssemblyInfo.cs diff --git a/ZeroNetworkMonitor/MainWindow.xaml b/Apps/ZeroNetworkMonitor/MainWindow.xaml similarity index 100% rename from ZeroNetworkMonitor/MainWindow.xaml rename to Apps/ZeroNetworkMonitor/MainWindow.xaml diff --git a/ZeroNetworkMonitor/MainWindow.xaml.cs b/Apps/ZeroNetworkMonitor/MainWindow.xaml.cs similarity index 100% rename from ZeroNetworkMonitor/MainWindow.xaml.cs rename to Apps/ZeroNetworkMonitor/MainWindow.xaml.cs diff --git a/ZeroNetworkMonitor/ServiceControlPanel.xaml b/Apps/ZeroNetworkMonitor/ServiceControlPanel.xaml similarity index 100% rename from ZeroNetworkMonitor/ServiceControlPanel.xaml rename to Apps/ZeroNetworkMonitor/ServiceControlPanel.xaml diff --git a/ZeroNetworkMonitor/ServiceControlPanel.xaml.cs b/Apps/ZeroNetworkMonitor/ServiceControlPanel.xaml.cs similarity index 100% rename from ZeroNetworkMonitor/ServiceControlPanel.xaml.cs rename to Apps/ZeroNetworkMonitor/ServiceControlPanel.xaml.cs diff --git a/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj b/Apps/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj similarity index 88% rename from ZeroNetworkMonitor/ZeroNetworkMonitor.csproj rename to Apps/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj index 0331aec..0fb5a3d 100644 --- a/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj +++ b/Apps/ZeroNetworkMonitor/ZeroNetworkMonitor.csproj @@ -9,7 +9,7 @@ - + diff --git a/Tests/Sleopok.Tests/Program.cs b/Tests/Sleopok.Tests/Program.cs new file mode 100644 index 0000000..40e6f90 --- /dev/null +++ b/Tests/Sleopok.Tests/Program.cs @@ -0,0 +1,141 @@ +using ZeroLevel.Services.Semantic; +using ZeroLevel.Services.Serialization; +using ZeroLevel.Sleopok.Engine; +using ZeroLevel.Sleopok.Engine.Models; +using ZeroLevel.Sleopok.Engine.Services; +using ZeroLevel.Sleopok.Engine.Services.Storage; + +namespace Sleopok.Tests +{ + internal class Program + { + public sealed class BookDocument + { + public string Id { get; set; } + + [SleoIndex("title", 200.0f)] + public string Title { get; set; } + + [SleoIndex("titlelm", 100.0f)] + public string TitleLemmas { get; set; } + + [SleoIndex("author", 10.0f)] + public string Author { get; set; } + + [SleoIndex("genre", 1.0f)] + public string Genre { get; set; } + } + + private static Dictionary _titles = new Dictionary + { + { "66056bc0481e83af64c55022", "Документ без названия" }, + { "6605698d481e83af64c45ad7", "На развилке дорог. Часть 2"}, + { "660581bc481e83af64cb8b4d", "Паниклав"}, + { "66057aa2481e83af64c9bb11", "Князь. Война магов (сборник)"}, + { "66057f75481e83af64cb04f7", "Антология севетского детектива-8. Компиляция. Книги 1-17"}, + { "66057bd4481e83af64ca0779", "Вор черной масти"}, + { "66057247481e83af64c76860", "Выбор"}, + { "66056807481e83af64c3a64f", "Последняя лекция"}, + { "66057f13481e83af64caed5d", "Оружие Круппа. История династии пушечных королей"}, + { "66057a37481e83af64c9a14b", "Месть Черного Дракона"}, + { "660588e8481e83af64cd2d3e", "Мгла над старыми могилами"}, + { "66056e88481e83af64c64e81", "Кровь и железо"}, + { "66057a8e481e83af64c9b673", "Маленькая страна"}, + { "6605687d481e83af64c3e360", "Санкт-Петербург – история в преданиях и легендах"}, + { "66057987481e83af64c9770c", "Контракт на рабство"}, + { "66059052481e83af64cf5e31", "Агент космического сыска"}, + { "660580f9481e83af64cb61c9", "Две жизни Алессы Коэн"}, + { "66056807481e84af64c3a64f", "Последняя история"}, + { "66057f13481e85af64caed5d", "История Китая"}, + { "66057a37481e86af64c9a14b", "Время Черного Дракона"}, + { "660588e8481e87af64cd2d3e", "Страна которой нет"}, + }; + + static async Task Main(string[] args) + { + // TestCompression(); + // await FillOneFieldIndex(); + // await TestSearch(); + await TestEngine(); + } + + static async Task TestEngine() + { + var engine = new SleoEngine(@"H:\Test", b => b.Id); + using (var builder = engine.CreateBuilder()) + { + builder.Write(new[] + { + new BookDocument{ Id = "01", Title = "Страж птица", }, + new BookDocument{ Id = "02" }, + new BookDocument{ Id = "03" }, + new BookDocument{ Id = "04" }, + }); + } + } + + static void TestCompression() + { + var strings = new string[] + { + string.Empty, + "doc1", + "doc2", + "", + " ", + "\r\n", + "last", + "doc3", + "doc4", + "doc5", + "doc6", + "doc7", + "doc8", + "doc9", + "doc10", + }; + + var clearbytes = MessageSerializer.SerializeCompatible(strings).Length; + var compressed = Compressor.Compress(strings); + Console.WriteLine($"{compressed.Length} / {clearbytes} bytes"); + + var decomressed = Compressor.DecompressToDocuments(compressed); + int index = 0; + foreach (var s in decomressed) + { + if (!(string.IsNullOrEmpty(s) && string.IsNullOrEmpty(strings[index])) && 0 != string.CompareOrdinal(strings[index], s)) + { + Console.WriteLine($"Got {s}. Expected {strings[index]}"); + } + index++; + } + } + + static async Task FillOneFieldIndex() + { + var store = new DataStorage(@"H:\TEST"); + using (var writer = store.GetWriter("title")) + { + foreach (var kv in _titles) + { + var tokens = WordTokenizer.Tokenize(kv.Value); + foreach (var t in tokens) + { + await writer.Write(t, kv.Key); + } + } + await writer.Complete(); + } + } + + static async Task TestSearch() + { + var store = new DataStorage(@"H:\TEST"); + var docs = await store.GetDocuments("title", new string[] { "кровь", "страна", "железо", "история", "оружие" }, 1.0f, false); + foreach (var kv in docs.OrderByDescending(kv => kv.Value)) + { + Console.WriteLine($"[{kv.Key}: {kv.Value}] {_titles[kv.Key]}"); + } + } + } +} diff --git a/Tests/Sleopok.Tests/Sleopok.Tests.csproj b/Tests/Sleopok.Tests/Sleopok.Tests.csproj new file mode 100644 index 0000000..510152e --- /dev/null +++ b/Tests/Sleopok.Tests/Sleopok.Tests.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/ZeroLevel.Sleopok.Engine/Models/IndexInfo.cs b/ZeroLevel.Sleopok.Engine/Models/IndexInfo.cs new file mode 100644 index 0000000..fc45d4a --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Models/IndexInfo.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using ZeroLevel; +using ZeroLevel.Services.FileSystem; +using ZeroLevel.Services.Reflection; +using ZeroLevel.Services.Extensions; + +namespace ZeroLevel.Sleopok.Engine.Models +{ + internal class IndexInfo + { + private readonly Func _identityExtractor; + private readonly List _fields; + + public string GetId(T item) => _identityExtractor.Invoke(item); + + public IReadOnlyCollection Fields => _fields; + + public IndexInfo(Func identityExtractor) + { + _identityExtractor = identityExtractor; + _fields = new List(); + typeof(T).GetMembers( + BindingFlags.Public | + BindingFlags.FlattenHierarchy | + BindingFlags.GetField | + BindingFlags.GetProperty | + BindingFlags.Instance). + Do(members => + { + foreach (var member in members) + { + var sleoAttribute = member.GetCustomAttribute(); + if (sleoAttribute == null) continue; + + Func getter; + switch (member.MemberType) + { + case MemberTypes.Field: + getter = TypeGetterSetterBuilder.BuildGetter(member as FieldInfo); + break; + case MemberTypes.Property: + getter = TypeGetterSetterBuilder.BuildGetter(member as PropertyInfo); + break; + default: return; + } + var name = FSUtils.FileNameCorrection(string.IsNullOrWhiteSpace(sleoAttribute.Name) ? member.Name : sleoAttribute.Name); + _fields.Add(new SleoField + { + Boost = sleoAttribute.Boost, + Name = name, + Getter = getter, + ExactMatch = sleoAttribute.AvaliableForExactMatch + }); + } + }); + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Models/SleoField.cs b/ZeroLevel.Sleopok.Engine/Models/SleoField.cs new file mode 100644 index 0000000..21a61d7 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Models/SleoField.cs @@ -0,0 +1,12 @@ +using System; + +namespace ZeroLevel.Sleopok.Engine.Models +{ + internal sealed class SleoField + { + public string Name; + public float Boost; + public bool ExactMatch; + public Func Getter; + } +} diff --git a/ZeroLevel.Sleopok.Engine/Models/SleoIndexAttribute.cs b/ZeroLevel.Sleopok.Engine/Models/SleoIndexAttribute.cs new file mode 100644 index 0000000..c67aa6b --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Models/SleoIndexAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace ZeroLevel.Sleopok.Engine.Models +{ + public sealed class SleoIndexAttribute + : Attribute + { + public string Name { get; private set; } + public float Boost { get; private set; } = 1.0f; + public bool AvaliableForExactMatch { get; private set; } = false; + + public SleoIndexAttribute(string name, float boost = 1.0f, bool avaliableForExactMatch = false) + { + Name = name; + Boost = boost; + AvaliableForExactMatch = avaliableForExactMatch; + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Compressor.cs b/ZeroLevel.Sleopok.Engine/Services/Compressor.cs new file mode 100644 index 0000000..29aaae7 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Compressor.cs @@ -0,0 +1,57 @@ +using System.IO; +using System.IO.Compression; +using ZeroLevel.Services.Serialization; + +namespace ZeroLevel.Sleopok.Engine.Services +{ + public static class Compressor + { + private static void CopyTo(Stream src, Stream dest) + { + byte[] bytes = new byte[4096]; + int cnt; + while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) + { + dest.Write(bytes, 0, cnt); + } + } + + public static byte[] Compress(string[] documents) + { + return Compress(MessageSerializer.SerializeCompatible(documents)); + } + + public static string[] DecompressToDocuments(byte[] data) + { + var bytes = Decompress(data); + return MessageSerializer.DeserializeCompatible(bytes); + } + + public static byte[] Compress(byte[] data) + { + using (var msi = new MemoryStream(data)) + using (var mso = new MemoryStream()) + { + using (var gs = new GZipStream(mso, CompressionMode.Compress)) + { + CopyTo(msi, gs); + } + return mso.ToArray(); + } + } + + public static byte[] Decompress(byte[] data) + { + using (var msi = new MemoryStream(data)) + using (var mso = new MemoryStream()) + { + using (var gs = new GZipStream(msi, CompressionMode.Decompress)) + { + CopyTo(gs, mso); + } + return mso.ToArray(); + } + } + + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexBuilder.cs b/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexBuilder.cs new file mode 100644 index 0000000..2af4715 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexBuilder.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ZeroLevel.Sleopok.Engine.Services.Indexes +{ + public interface IIndexBuilder + : IDisposable + { + Task Write(IEnumerable batch); + Task Complete(); + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexReader.cs b/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexReader.cs new file mode 100644 index 0000000..e5fd213 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Indexes/IIndexReader.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ZeroLevel.Sleopok.Engine.Services.Indexes +{ + public interface IIndexReader + { + Task> Search(string[] tokens, bool exactMatch); + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexBuilder.cs b/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexBuilder.cs new file mode 100644 index 0000000..66f172e --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexBuilder.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using ZeroLevel.Sleopok.Engine.Models; +using ZeroLevel.Sleopok.Engine.Services.Storage; + +namespace ZeroLevel.Sleopok.Engine.Services.Indexes +{ + internal sealed class IndexBuilder + : IIndexBuilder + { + private readonly DataStorage _storage; + private readonly IndexInfo _indexInfo; + private readonly Dictionary Indexers = new Dictionary(); + public IndexBuilder(DataStorage storage, IndexInfo indexInfo) + { + _storage = storage; + _indexInfo = indexInfo; + foreach (var field in indexInfo.Fields) + { + Indexers[field.Name] = _storage.GetWriter(field.Name); + } + } + + public async Task Complete() + { + foreach (var i in Indexers) + { + await i.Value.Complete(); + i.Value.Dispose(); + } + } + + public async Task Write(IEnumerable batch) + { + foreach (var doc in batch) + { + var doc_id = _indexInfo.GetId(doc); + foreach (var field in _indexInfo.Fields) + { + var value = field.Getter(doc!)?.ToString() ?? string.Empty; + if (string.IsNullOrWhiteSpace(value) == false) + { + foreach (var t in value.Split(' ')) + { + await Indexers[field.Name].Write(t, doc_id); + } + } + } + } + } + + public void Dispose() + { + Complete().Wait(); + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexReader.cs b/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexReader.cs new file mode 100644 index 0000000..f428193 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Indexes/IndexReader.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using ZeroLevel.Sleopok.Engine.Models; +using ZeroLevel.Sleopok.Engine.Services.Storage; + +namespace ZeroLevel.Sleopok.Engine.Services.Indexes +{ + internal sealed class IndexReader + : IIndexReader + { + private readonly DataStorage _storage; + private readonly IndexInfo _indexInfo; + public IndexReader(DataStorage storage, IndexInfo indexInfo) + { + _storage = storage; + _indexInfo = indexInfo; + } + + public async Task> Search(string[] tokens, bool exactMatch) + { + var documents = new Dictionary(); + + foreach (var field in _indexInfo.Fields) + { + if (exactMatch && field.ExactMatch == false) + continue; + var docs = await _storage.GetDocuments(field.Name, tokens, field.Boost, exactMatch); + foreach (var doc in docs) + { + if (doc.Value > 0.0001f) + { + if (documents.ContainsKey(doc.Key) == false) + { + documents[doc.Key] = doc.Value; + } + else + { + documents[doc.Key] += doc.Value; + } + } + } + } + return documents; + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Storage/DataStorage.cs b/ZeroLevel.Sleopok.Engine/Services/Storage/DataStorage.cs new file mode 100644 index 0000000..d19493d --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Storage/DataStorage.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using ZeroLevel.Services.HashFunctions; +using ZeroLevel.Services.PartitionStorage; + +namespace ZeroLevel.Sleopok.Engine.Services.Storage +{ + public sealed class DataStorage + { + private readonly IStore _store; + + private class DateSourceWriter : + IPartitionDataWriter + { + private readonly IStorePartitionBuilder _builder; + public DateSourceWriter(IStorePartitionBuilder builder) + { + _builder = builder; + } + + public async Task Complete() + { + _builder.CompleteAdding(); + _builder.Compress(); + await _builder.RebuildIndex(); + _builder.Dispose(); + } + + public async Task Write(string host, string document) + { + await _builder.Store(host, document); + } + + public long GetTotalRecords() => _builder.TotalRecords; + + public void Dispose() + { + _builder.Dispose(); + } + } + + public DataStorage(string rootFolder) + { + var serializers = new StoreSerializers( + async (w, n) => await w.WriteStringAsync(n), + async (w, n) => await w.WriteStringAsync(n), + async (w, n) => await w.WriteBytesAsync(n), + + async (r) => { try { return new DeserializeResult(true, await r.ReadStringAsync()); } catch { return new DeserializeResult(false, string.Empty); } }, + async (r) => { try { return new DeserializeResult(true, await r.ReadStringAsync()); } catch { return new DeserializeResult(false, string.Empty); } }, + async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } }); + + var options = new StoreOptions + { + Index = new IndexOptions + { + Enabled = true, + StepType = IndexStepType.Step, + StepValue = 32, + EnableIndexInMemoryCachee = false + }, + RootFolder = rootFolder, + FilePartition = new StoreFilePartition("Token hash", (token, _) => Math.Abs(StringHash.DotNetFullHash(token) % 47).ToString()), + MergeFunction = list => + { + return Compressor.Compress(list.OrderBy(c => c).ToArray()); + }, + Partitions = new List> + { + new StoreCatalogPartition("Field", m => m.Field) + }, + KeyComparer = (left, right) => string.Compare(left, right, true), + ThreadSafeWriting = true + }; + _store = new Store(options, serializers); + } + + public IPartitionDataWriter GetWriter(string field) + { + return new DateSourceWriter(_store.CreateBuilder(new StoreMetadata { Field = field })); + } + + private class PositionDocScore + { + private float score = 0.0f; + private int _last_position = -1; + private int count = 0; + + public float GetScore(int total, bool exactMatch) + { + if (exactMatch) + { + return (count == total) ? 1.0f : 0f; + } + return (score / (float)total) * count; + } + + public void Increase(int position) + { + if (position == 0) + { + score = 1.0f; + } + else + { + var diff = position - _last_position; + score += 1.0f / diff; + } + _last_position = position; + count++; + } + } + + public async Task> GetDocuments(string field, string[] tokens, float boost, bool exactMatch) + { + var documents = new Dictionary(); + var accessor = _store.CreateAccessor(new StoreMetadata { Field = field }); + if (accessor != null) + { + using (accessor) + { + int step = 0; + foreach (var token in tokens) + { + var sr = await accessor.Find(token); + if (sr.Success) + { + foreach (var doc in Compressor.DecompressToDocuments(sr.Value)) + { + if (false == documents.ContainsKey(doc)) + { + documents.Add(doc, new PositionDocScore()); + } + documents[doc].Increase(step); + } + } + } + } + } + return documents.ToDictionary(d => d.Key, d => boost * d.Value.GetScore(tokens.Length, exactMatch)); + } + + public async Task Dump(string key, Stream stream) + { + using (TextWriter writer = new StreamWriter(stream)) + { + await foreach (var i in _store.Bypass(new StoreMetadata { Field = key })) + { + writer.WriteLine(i.Key); + writer.WriteLine(string.Join(' ', Compressor.DecompressToDocuments(i.Value))); + } + } + } + + public int HasData(string field) + { + var partition = _store.CreateAccessor(new StoreMetadata { Field = field }); + if (partition != null) + { + using (partition) + { + return partition.CountDataFiles(); + } + } + return 0; + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Storage/IPartitionDataWriter.cs b/ZeroLevel.Sleopok.Engine/Services/Storage/IPartitionDataWriter.cs new file mode 100644 index 0000000..7858e56 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Storage/IPartitionDataWriter.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading.Tasks; + +namespace ZeroLevel.Sleopok.Engine.Services.Storage +{ + public interface IPartitionDataWriter + : IDisposable + { + Task Write(string token, string document); + Task Complete(); + long GetTotalRecords(); + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Storage/StoreMetadata.cs b/ZeroLevel.Sleopok.Engine/Services/Storage/StoreMetadata.cs new file mode 100644 index 0000000..db37074 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Storage/StoreMetadata.cs @@ -0,0 +1,13 @@ +namespace ZeroLevel.Sleopok.Engine.Services.Storage +{ + /// + /// Мета + /// + public sealed class StoreMetadata + { + /// + /// Поле документа + /// + public string Field { get; set; } + } +} diff --git a/ZeroLevel.Sleopok.Engine/Services/Storage/StoreRecord.cs b/ZeroLevel.Sleopok.Engine/Services/Storage/StoreRecord.cs new file mode 100644 index 0000000..15bf68b --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/Services/Storage/StoreRecord.cs @@ -0,0 +1,14 @@ +namespace ZeroLevel.Sleopok.Engine.Services.Storage +{ + public sealed class StoreRecord + { + /// + /// Токен / ключ + /// + public string Token { get; set; } + /// + /// Идентификаторы документов / значение + /// + public string[] Documents { get; set; } + } +} diff --git a/ZeroLevel.Sleopok.Engine/SleoEngine.cs b/ZeroLevel.Sleopok.Engine/SleoEngine.cs new file mode 100644 index 0000000..5f1f9b7 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/SleoEngine.cs @@ -0,0 +1,41 @@ +using System; +using ZeroLevel.Sleopok.Engine.Models; +using ZeroLevel.Sleopok.Engine.Services.Indexes; +using ZeroLevel.Sleopok.Engine.Services.Storage; + +namespace ZeroLevel.Sleopok.Engine +{ + public class SleoEngine + { + private readonly DataStorage _storage; + private readonly IndexInfo _indexInfo; + public SleoEngine(string indexFolder, Func identityExtractor) + { + _storage = new DataStorage(indexFolder); + _indexInfo = new IndexInfo(identityExtractor); + } + + public bool HasData() + { + var total = 0; + // healthy + foreach (var field in _indexInfo.Fields) + { + var count = _storage.HasData(field.Name); + Log.Debug($"Field: {field.Name}: {count} files"); + total += count; + } + return total > 0; + } + + public IIndexBuilder CreateBuilder() + { + return new IndexBuilder(_storage, _indexInfo); + } + + public IIndexReader CreateReader() + { + return new IndexReader(_storage, _indexInfo); + } + } +} diff --git a/ZeroLevel.Sleopok.Engine/ZeroLevel.Sleopok.Engine.csproj b/ZeroLevel.Sleopok.Engine/ZeroLevel.Sleopok.Engine.csproj new file mode 100644 index 0000000..20c1104 --- /dev/null +++ b/ZeroLevel.Sleopok.Engine/ZeroLevel.Sleopok.Engine.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.1 + enable + + + + + + + diff --git a/ZeroLevel.sln b/ZeroLevel.sln index 96652e9..60c687d 100644 --- a/ZeroLevel.sln +++ b/ZeroLevel.sln @@ -3,14 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Discovery", "ZeroLevel.Discovery\ZeroLevel.Discovery.csproj", "{5CE51CC9-7884-4E21-9D68-2321CA14312E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileTransferTest", "FileTransferTest", "{FC074553-5D9F-4DF1-9130-7092E37DE768}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestPipeLine", "TestPipeLine", "{03ACF314-93FC-46FE-9FB8-3F46A01A5A15}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Logger", "ZeroLevel.Logger\ZeroLevel.Logger.csproj", "{D1C061DB-3565-43C3-B8F3-628DE4908750}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WPFExamples", "WPFExamples", "{7CCA0125-7A96-48FA-9F0D-BCF7EAD8FF9D}" ProjectSection(SolutionItems) = preProject WPFExamples\Controls\AlignableWrapPanel.cs = WPFExamples\Controls\AlignableWrapPanel.cs @@ -27,8 +23,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WPFExamples", "WPFExamples" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConnectionTest", "ConnectionTest", "{D5207A5A-2F27-4992-9BA5-0BDCFC59F133}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroNetworkMonitor", "ZeroNetworkMonitor\ZeroNetworkMonitor.csproj", "{B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{380C828E-55D0-488B-A95F-4EFD20597BF5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consumer", "Tests\TestPipeLine\Consumer\Consumer.csproj", "{6C87E9EF-423F-47FC-BCFC-1A8E51336F02}" @@ -53,11 +47,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp", "Tests\TestApp\Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.UnitTests", "Tests\ZeroLevel.UnitTests\ZeroLevel.UnitTests.csproj", "{F73E2055-376A-4DC4-996E-E99009EC62D6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel", "ZeroLevel\ZeroLevel.csproj", "{301D5818-59C5-4B46-9F80-A1054CC6CAA3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel", "ZeroLevel\ZeroLevel.csproj", "{301D5818-59C5-4B46-9F80-A1054CC6CAA3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.MsSql", "ZeroLevel.MsSql\ZeroLevel.MsSql.csproj", "{3F9E6132-926C-46DE-B202-2355C126FD67}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.ML", "ZeroLevel.ML\ZeroLevel.ML.csproj", "{9F6690E5-D35D-4FA7-BDF0-FE320C4878E0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{D60EF108-4E66-48A6-B3A9-59CF39C0D028}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Discovery", "Apps\ZeroLevel.Discovery\ZeroLevel.Discovery.csproj", "{0DD8B913-013E-4531-BBDF-EB535FFBC218}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.Logger", "Apps\ZeroLevel.Logger\ZeroLevel.Logger.csproj", "{F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroNetworkMonitor", "Apps\ZeroNetworkMonitor\ZeroNetworkMonitor.csproj", "{D1506C69-4CA0-4D2C-8A07-3D786B449C68}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.MsSql", "ZeroLevel.MsSql\ZeroLevel.MsSql.csproj", "{3F9E6132-926C-46DE-B202-2355C126FD67}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.Sleopok.Engine", "ZeroLevel.Sleopok.Engine\ZeroLevel.Sleopok.Engine.csproj", "{469078A3-1CA9-46AD-BBBE-408A007FCEC8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.ML", "ZeroLevel.ML\ZeroLevel.ML.csproj", "{9F6690E5-D35D-4FA7-BDF0-FE320C4878E0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sleopok.Tests", "Tests\Sleopok.Tests\Sleopok.Tests.csproj", "{4F5251A0-6639-40B0-91A7-6A1F39DF823E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -69,42 +75,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|x64.ActiveCfg = Debug|x64 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|x64.Build.0 = Debug|x64 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|x86.ActiveCfg = Debug|x86 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Debug|x86.Build.0 = Debug|x86 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|Any CPU.Build.0 = Release|Any CPU - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.ActiveCfg = Release|x64 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x64.Build.0 = Release|x64 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x86.ActiveCfg = Release|x86 - {5CE51CC9-7884-4E21-9D68-2321CA14312E}.Release|x86.Build.0 = Release|x86 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x64.ActiveCfg = Debug|x64 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x64.Build.0 = Debug|x64 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x86.ActiveCfg = Debug|x86 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Debug|x86.Build.0 = Debug|x86 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|Any CPU.Build.0 = Release|Any CPU - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.ActiveCfg = Release|x64 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x64.Build.0 = Release|x64 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x86.ActiveCfg = Release|x86 - {D1C061DB-3565-43C3-B8F3-628DE4908750}.Release|x86.Build.0 = Release|x86 - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|x64.ActiveCfg = Debug|x64 - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|x64.Build.0 = Debug|x64 - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|x86.ActiveCfg = Debug|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Debug|x86.Build.0 = Debug|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|Any CPU.Build.0 = Release|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|x64.ActiveCfg = Release|x64 - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|x64.Build.0 = Release|x64 - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|x86.ActiveCfg = Release|Any CPU - {B89249F8-BD37-4AF7-9BB5-65855FA3B3FA}.Release|x86.Build.0 = Release|Any CPU {6C87E9EF-423F-47FC-BCFC-1A8E51336F02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C87E9EF-423F-47FC-BCFC-1A8E51336F02}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C87E9EF-423F-47FC-BCFC-1A8E51336F02}.Debug|x64.ActiveCfg = Debug|x64 @@ -273,6 +243,66 @@ Global {9F6690E5-D35D-4FA7-BDF0-FE320C4878E0}.Release|x64.Build.0 = Release|Any CPU {9F6690E5-D35D-4FA7-BDF0-FE320C4878E0}.Release|x86.ActiveCfg = Release|Any CPU {9F6690E5-D35D-4FA7-BDF0-FE320C4878E0}.Release|x86.Build.0 = Release|Any CPU + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|x64.ActiveCfg = Debug|x64 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|x64.Build.0 = Debug|x64 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|x86.ActiveCfg = Debug|x86 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Debug|x86.Build.0 = Debug|x86 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|Any CPU.Build.0 = Release|Any CPU + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|x64.ActiveCfg = Release|x64 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|x64.Build.0 = Release|x64 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|x86.ActiveCfg = Release|x86 + {0DD8B913-013E-4531-BBDF-EB535FFBC218}.Release|x86.Build.0 = Release|x86 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|x64.ActiveCfg = Debug|x64 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|x64.Build.0 = Debug|x64 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|x86.ActiveCfg = Debug|x86 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Debug|x86.Build.0 = Debug|x86 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|Any CPU.Build.0 = Release|Any CPU + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|x64.ActiveCfg = Release|x64 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|x64.Build.0 = Release|x64 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|x86.ActiveCfg = Release|x86 + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6}.Release|x86.Build.0 = Release|x86 + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|x64.ActiveCfg = Debug|x64 + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|x64.Build.0 = Debug|x64 + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|x86.ActiveCfg = Debug|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Debug|x86.Build.0 = Debug|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|Any CPU.Build.0 = Release|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|x64.ActiveCfg = Release|x64 + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|x64.Build.0 = Release|x64 + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|x86.ActiveCfg = Release|Any CPU + {D1506C69-4CA0-4D2C-8A07-3D786B449C68}.Release|x86.Build.0 = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|x64.ActiveCfg = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|x64.Build.0 = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|x86.ActiveCfg = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Debug|x86.Build.0 = Debug|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|Any CPU.Build.0 = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|x64.ActiveCfg = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|x64.Build.0 = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|x86.ActiveCfg = Release|Any CPU + {469078A3-1CA9-46AD-BBBE-408A007FCEC8}.Release|x86.Build.0 = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|x64.Build.0 = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Debug|x86.Build.0 = Debug|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|Any CPU.Build.0 = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|x64.ActiveCfg = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|x64.Build.0 = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|x86.ActiveCfg = Release|Any CPU + {4F5251A0-6639-40B0-91A7-6A1F39DF823E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -292,6 +322,10 @@ Global {9525DFC1-91F4-4B38-BDD0-7C46507C636F} = {380C828E-55D0-488B-A95F-4EFD20597BF5} {3C6C5D02-93B7-4842-97C0-870B4B6AF5F5} = {380C828E-55D0-488B-A95F-4EFD20597BF5} {F73E2055-376A-4DC4-996E-E99009EC62D6} = {380C828E-55D0-488B-A95F-4EFD20597BF5} + {0DD8B913-013E-4531-BBDF-EB535FFBC218} = {D60EF108-4E66-48A6-B3A9-59CF39C0D028} + {F7464B5D-B66A-412C-8ED3-346A1AC9CBE6} = {D60EF108-4E66-48A6-B3A9-59CF39C0D028} + {D1506C69-4CA0-4D2C-8A07-3D786B449C68} = {D60EF108-4E66-48A6-B3A9-59CF39C0D028} + {4F5251A0-6639-40B0-91A7-6A1F39DF823E} = {380C828E-55D0-488B-A95F-4EFD20597BF5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A65DB16F-877D-4586-A9F3-8BBBFBAF5CEB} diff --git a/ZeroLevel/Models/BaseModel.cs b/ZeroLevel/Models/BaseModel.cs index 8696d64..a10f7ab 100644 --- a/ZeroLevel/Models/BaseModel.cs +++ b/ZeroLevel/Models/BaseModel.cs @@ -11,9 +11,9 @@ namespace ZeroLevel.Models public bool Equals(BaseModel other) { - if (this == null) + if (this == null!) throw new NullReferenceException(); - if (other == null) + if (other == null!) return false; if (ReferenceEquals(this, other)) return true; @@ -24,10 +24,10 @@ namespace ZeroLevel.Models public override bool Equals(object obj) { - if (this == null) + if (this == null!) throw new NullReferenceException(); - return Equals(obj as BaseModel); + return Equals((obj as BaseModel)!); } public static bool operator ==(BaseModel first, BaseModel second) => Equals(first, second); diff --git a/ZeroLevel/Services/BaseZeroService.cs b/ZeroLevel/Services/BaseZeroService.cs index 281b599..c46e014 100644 --- a/ZeroLevel/Services/BaseZeroService.cs +++ b/ZeroLevel/Services/BaseZeroService.cs @@ -72,30 +72,30 @@ namespace ZeroLevel.Services.Applications this.Type = ReadServiceType(set); } - private string ReadName(IConfigurationSet set = null) + private string ReadName(IConfigurationSet set = null!) { return FindInConfig(set, new[] { "ServiceName", "AppName" }, string.Empty, "service") ?? this.GetType().Name; } - private string ReadKey(IConfigurationSet set = null) + private string ReadKey(IConfigurationSet set = null!) { return FindInConfig(set, new[] { "ServiceKey", "AppKey" }, string.Empty, "service"); } - private string ReadVersion(IConfigurationSet set = null) + private string ReadVersion(IConfigurationSet set = null!) { return FindInConfig(set, new[] { "Version", "AppVersion" }, string.Empty, "service") ?? "1.0"; } - private string ReadServiceGroup(IConfigurationSet set = null) + private string ReadServiceGroup(IConfigurationSet set = null!) { return FindInConfig(set, new[] { "DiscoveryGroup", "ServiceGroup" }, string.Empty, "service") ?? DEFAULT_GROUP_NAME; } - private string ReadServiceType(IConfigurationSet set = null) + private string ReadServiceType(IConfigurationSet set = null!) { return FindInConfig(set, new[] { "DiscoveryType", "ServiceType" }, string.Empty, "service") ?? DEFAULT_TYPE_NAME; @@ -299,13 +299,13 @@ namespace ZeroLevel.Services.Applications if (args.Length == 1) { var handler = CreateDelegate(typeof(MessageHandler), mi, this); - register_message_handler.Invoke(server, new object[] { (attr as ExchangeHandlerAttribute).Inbox, handler }); + register_message_handler.Invoke(server, new object[] { (attr as ExchangeHandlerAttribute)!.Inbox, handler }); } else { var handler = CreateDelegate(typeof(MessageHandler<>).MakeGenericType(args[1].ParameterType), mi, this); MethodInfo genericMethod = register_message_handler_with_msg.MakeGenericMethod(args[1].ParameterType); - genericMethod.Invoke(server, new object[] { (attr as ExchangeHandlerAttribute).Inbox, handler }); + genericMethod.Invoke(server, new object[] { (attr as ExchangeHandlerAttribute)!.Inbox, handler }); } } @@ -323,7 +323,7 @@ namespace ZeroLevel.Services.Applications var genArgType = args[1].ParameterType; MethodInfo genericMethod = register_request_handler.MakeGenericMethod(genArgType, returnType); var requestHandler = CreateDelegate(typeof(RequestHandler<,>).MakeGenericType(args[1].ParameterType, returnType), mi, this); - genericMethod.Invoke(server, new object[] { (attr as ExchangeReplierAttribute).Inbox, requestHandler }); + genericMethod.Invoke(server, new object[] { (attr as ExchangeReplierAttribute)!.Inbox, requestHandler }); } else if (attr.GetType() == typeof(ExchangeMainReplierWithoutArgAttribute)) @@ -338,7 +338,7 @@ namespace ZeroLevel.Services.Applications var returnType = mi.ReturnType; MethodInfo genericMethod = register_request_handler_without_msg.MakeGenericMethod(returnType); var requestHandler = CreateDelegate(typeof(RequestHandler<>).MakeGenericType(returnType), mi, this); - genericMethod.Invoke(server, new object[] { (attr as ExchangeReplierWithoutArgAttribute).Inbox, requestHandler }); + genericMethod.Invoke(server, new object[] { (attr as ExchangeReplierWithoutArgAttribute)!.Inbox, requestHandler }); } } } diff --git a/ZeroLevel/Services/Bootstrap.cs b/ZeroLevel/Services/Bootstrap.cs index c0e861c..f10504a 100644 --- a/ZeroLevel/Services/Bootstrap.cs +++ b/ZeroLevel/Services/Bootstrap.cs @@ -127,32 +127,32 @@ namespace ZeroLevel } public static BootstrapFluent Startup(string[] args, - Func preStartConfiguration = null, - Func postStartConfiguration = null) + Func preStartConfiguration = null!, + Func postStartConfiguration = null!) where T : IZeroService { - var service = Initialize(args, null, + var service = Initialize(args, null!, preStartConfiguration, postStartConfiguration); return new BootstrapFluent(service); } public static BootstrapFluent Startup(string[] args, Func configuration, - Func preStartConfiguration = null, - Func postStartConfiguration = null) + Func preStartConfiguration = null!, + Func postStartConfiguration = null!) where T : IZeroService { - var service = Initialize(args, configuration?.Invoke(), preStartConfiguration, postStartConfiguration); + var service = Initialize(args, configuration?.Invoke()!, preStartConfiguration, postStartConfiguration); return new BootstrapFluent(service); } private static IZeroService Initialize(string[] args, IConfigurationSet configurationSet, - Func preStartConfiguration = null, - Func postStartConfiguration = null) + Func preStartConfiguration = null!, + Func postStartConfiguration = null!) where T : IZeroService { - IZeroService service = null; + IZeroService service = null!; IConfigurationSet config = Configuration.DefaultSet; config.CreateSection("commandline", Configuration.ReadFromCommandLine(args)); if (configurationSet != null) @@ -168,13 +168,13 @@ namespace ZeroLevel if (preStartConfiguration() == false) { Log.SystemInfo("[Bootstrap] Service start canceled, because custom preconfig return false"); - return null; + return null!; } } catch (Exception ex) { Log.SystemError(ex, "[Bootstrap] Service start canceled, preconfig faulted"); - return null; + return null!; } } try @@ -204,7 +204,7 @@ namespace ZeroLevel return service; } - public static IExchange CreateExchange() => new Exchange(null); + public static IExchange CreateExchange() => new Exchange(null!); public static void Shutdown() { diff --git a/ZeroLevel/Services/Collections/ConcurrentHashSet.cs b/ZeroLevel/Services/Collections/ConcurrentHashSet.cs index 3eadcc4..e8635cd 100644 --- a/ZeroLevel/Services/Collections/ConcurrentHashSet.cs +++ b/ZeroLevel/Services/Collections/ConcurrentHashSet.cs @@ -116,7 +116,7 @@ namespace ZeroLevel.Collections /// uses the default comparer for the item type. /// public ConcurrentHashSet() - : this(DefaultConcurrencyLevel, DefaultCapacity, true, null) + : this(DefaultConcurrencyLevel, DefaultCapacity, true, null!) { } @@ -136,7 +136,7 @@ namespace ZeroLevel.Collections /// is less than /// 0. public ConcurrentHashSet(int concurrencyLevel, int capacity) - : this(concurrencyLevel, capacity, false, null) + : this(concurrencyLevel, capacity, false, null!) { } @@ -152,7 +152,7 @@ namespace ZeroLevel.Collections /// . /// is a null reference. public ConcurrentHashSet(IEnumerable collection) - : this(collection, null) + : this(collection, null!) { } @@ -375,7 +375,7 @@ namespace ZeroLevel.Collections continue; } - Node previous = null; + Node previous = null!; for (var current = tables.Buckets[bucketNo]; current != null; current = current.Next) { Debug.Assert((previous == null && current == tables.Buckets[bucketNo]) || previous!.Next == current); @@ -455,8 +455,8 @@ namespace ZeroLevel.Collections public Enumerator(ConcurrentHashSet set) { _set = set; - _buckets = null; - _node = null; + _buckets = null!; + _node = null!; Current = default!; _i = -1; _state = StateUninitialized; @@ -468,15 +468,15 @@ namespace ZeroLevel.Collections /// The element in the collection at the current position of the enumerator. public T Current { get; private set; } - object IEnumerator.Current => Current; + object IEnumerator.Current => Current!; /// /// Sets the enumerator to its initial position, which is before the first element in the collection. /// public void Reset() { - _buckets = null; - _node = null; + _buckets = null!; + _node = null!; Current = default!; _i = -1; _state = StateUninitialized; diff --git a/ZeroLevel/Services/Collections/FixSizeQueue.cs b/ZeroLevel/Services/Collections/FixSizeQueue.cs index 1883fdb..fb3a399 100644 --- a/ZeroLevel/Services/Collections/FixSizeQueue.cs +++ b/ZeroLevel/Services/Collections/FixSizeQueue.cs @@ -46,13 +46,13 @@ namespace ZeroLevel.Services.Collections public bool Equals(T x, T y) { if (x == null && y == null) return true; - if ((object)x == (object)y) return true; if (x == null || y == null) return false; + if ((object)x == (object)y) return true; if (ReferenceEquals(x, y)) return true; return x.Equals(y); } - public bool Contains(T item, IComparer comparer = null) + public bool Contains(T item, IComparer comparer = null!) { lock (_accessLocker) { diff --git a/ZeroLevel/Services/Config/BaseConfiguration.cs b/ZeroLevel/Services/Config/BaseConfiguration.cs index ebf2541..0bad1bc 100644 --- a/ZeroLevel/Services/Config/BaseConfiguration.cs +++ b/ZeroLevel/Services/Config/BaseConfiguration.cs @@ -527,8 +527,8 @@ namespace ZeroLevel.Services.Config else { var elements = values.Select(v => parser.Parse(v)).ToArray(); - var arrayBuilder = CollectionFactory.CreateArray(itemType, (elements[0] as Array).Length); - foreach (var item in (elements[0] as Array)) + var arrayBuilder = CollectionFactory.CreateArray(itemType, (elements[0] as Array)?.Length ?? 0); + foreach (var item in (elements[0] as Array) ?? Array.Empty()) { arrayBuilder.Set(item, index); index++; diff --git a/ZeroLevel/Services/Config/Implementation/AppWebConfigReader.cs b/ZeroLevel/Services/Config/Implementation/AppWebConfigReader.cs index 51c7b69..95d4894 100644 --- a/ZeroLevel/Services/Config/Implementation/AppWebConfigReader.cs +++ b/ZeroLevel/Services/Config/Implementation/AppWebConfigReader.cs @@ -12,7 +12,7 @@ namespace ZeroLevel.Services.Config.Implementation public bool ExistsAppConfigFile => string.IsNullOrWhiteSpace(_configFilePath) == false; - internal AppWebConfigReader(string configFilePath = null) + internal AppWebConfigReader(string configFilePath = null!) { if (configFilePath == null) { @@ -69,14 +69,16 @@ namespace ZeroLevel.Services.Config.Implementation SelectMany(x => x.Nodes().Where(n => null != (n as XElement)).Select(n => { var xe = n as XElement; - return new Tuple(FindName(xe), FindValue(xe)); - })); + return new Tuple(FindName(xe!), FindValue(xe!)); + })) + .Where(t => string.IsNullOrWhiteSpace(t.Item1) == false); } return Enumerable.Empty>(); } private static string FindName(XElement n) { + if (n == null) return string.Empty; var attributes = n.Attributes(). ToDictionary(i => i.Name.LocalName.ToLowerInvariant(), j => j.Value); foreach (var v in new[] { "key", "name", "code", "id" }) @@ -89,6 +91,7 @@ namespace ZeroLevel.Services.Config.Implementation private static string FindValue(XElement n) { + if (n == null) return string.Empty; var attributes = n.Attributes(). ToDictionary(i => i.Name.LocalName.ToLowerInvariant(), j => j.Value); foreach (var v in new[] { "value", "val", "file", "db", "connectionstring" }) diff --git a/ZeroLevel/Services/Config/Implementation/EnvironmentVariablesConfigReader.cs b/ZeroLevel/Services/Config/Implementation/EnvironmentVariablesConfigReader.cs index 3ab089e..3a6c8ff 100644 --- a/ZeroLevel/Services/Config/Implementation/EnvironmentVariablesConfigReader.cs +++ b/ZeroLevel/Services/Config/Implementation/EnvironmentVariablesConfigReader.cs @@ -12,7 +12,7 @@ namespace ZeroLevel.Services.Config.Implementation while (enumerator.MoveNext()) { string key = (string)enumerator.Entry.Key; - string value = ((string)enumerator.Entry.Value) ?? string.Empty; + string value = (enumerator.Entry.Value as string) ?? string.Empty; result.Append(key, value); } return result; @@ -23,4 +23,4 @@ namespace ZeroLevel.Services.Config.Implementation return Configuration.CreateSet(ReadConfiguration()); } } -} +} \ No newline at end of file diff --git a/ZeroLevel/Services/DOM/DSL/Model/TFlowRules.cs b/ZeroLevel/Services/DOM/DSL/Model/TFlowRules.cs index 30d81c4..9b87b7e 100644 --- a/ZeroLevel/Services/DOM/DSL/Model/TFlowRules.cs +++ b/ZeroLevel/Services/DOM/DSL/Model/TFlowRules.cs @@ -68,54 +68,54 @@ namespace DOM.DSL.Model public void Bootstrap() { - if (null == SectionPrefix) SectionPrefix = null; - if (null == SectionPostfix) SectionPostfix = null; - if (null == ParagraphPrefix) ParagraphPrefix = null; - if (null == ParagraphPostfix) ParagraphPostfix = null; - if (null == ListPrefix) ListPrefix = null; - if (null == ListPostfix) ListPostfix = null; - if (null == ListItemPrefix) ListItemPrefix = null; - if (null == ListItemPostfix) ListItemPostfix = null; - if (null == TablePrefix) TablePrefix = null; - if (null == TablePostfix) TablePostfix = null; - if (null == ColumnsPrefix) ColumnsPrefix = null; - if (null == ColumnsPostfix) ColumnsPostfix = null; - if (null == ColumnPrefix) ColumnPrefix = null; - if (null == ColumnTemplate) ColumnTemplate = null; - if (null == ColumnPostfix) ColumnPostfix = null; - if (null == RowPrefix) RowPrefix = null; - if (null == RowPostfix) RowPostfix = null; - if (null == CellPrefix) CellPrefix = null; - if (null == CellPostfix) CellPostfix = null; - if (null == FirstRowCellPrefix) FirstRowCellPrefix = null; - if (null == FirstRowCellPostfix) FirstRowCellPostfix = null; - if (null == AudioplayerPrefix) AudioplayerPrefix = null; - if (null == AudioplayerPostfix) AudioplayerPostfix = null; - if (null == VideoplayerPrefix) VideoplayerPrefix = null; - if (null == VideoplayerPostfix) VideoplayerPostfix = null; - if (null == GalleryPrefix) GalleryPrefix = null; - if (null == GalleryPostfix) GalleryPostfix = null; - if (null == FormPrefix) FormPrefix = null; - if (null == FormTemplate) FormTemplate = null; - if (null == FormPostfix) FormPostfix = null; - if (null == VideoPrefix) VideoPrefix = null; - if (null == VideoTemplate) VideoTemplate = null; - if (null == VideoPostfix) VideoPostfix = null; - if (null == AudioPrefix) AudioPrefix = null; - if (null == AudioTemplate) AudioTemplate = null; - if (null == AudioPostfix) AudioPostfix = null; - if (null == ImagePrefix) ImagePrefix = null; - if (null == ImageTemplate) ImageTemplate = null; - if (null == ImagePostfix) ImagePostfix = null; - if (null == LinkPrefix) LinkPrefix = null; - if (null == LinkTemplate) LinkTemplate = null; - if (null == LinkPostfix) LinkPostfix = null; - if (null == QuotePrefix) QuotePrefix = null; + if (null == SectionPrefix) SectionPrefix = null!; + if (null == SectionPostfix) SectionPostfix = null!; + if (null == ParagraphPrefix) ParagraphPrefix = null!; + if (null == ParagraphPostfix) ParagraphPostfix = null!; + if (null == ListPrefix) ListPrefix = null!; + if (null == ListPostfix) ListPostfix = null!; + if (null == ListItemPrefix) ListItemPrefix = null!; + if (null == ListItemPostfix) ListItemPostfix = null!; + if (null == TablePrefix) TablePrefix = null!; + if (null == TablePostfix) TablePostfix = null!; + if (null == ColumnsPrefix) ColumnsPrefix = null!; + if (null == ColumnsPostfix) ColumnsPostfix = null!; + if (null == ColumnPrefix) ColumnPrefix = null!; + if (null == ColumnTemplate) ColumnTemplate = null!; + if (null == ColumnPostfix) ColumnPostfix = null!; + if (null == RowPrefix) RowPrefix = null!; + if (null == RowPostfix) RowPostfix = null!; + if (null == CellPrefix) CellPrefix = null!; + if (null == CellPostfix) CellPostfix = null!; + if (null == FirstRowCellPrefix) FirstRowCellPrefix = null!; + if (null == FirstRowCellPostfix) FirstRowCellPostfix = null!; + if (null == AudioplayerPrefix) AudioplayerPrefix = null!; + if (null == AudioplayerPostfix) AudioplayerPostfix = null!; + if (null == VideoplayerPrefix) VideoplayerPrefix = null!; + if (null == VideoplayerPostfix) VideoplayerPostfix = null!; + if (null == GalleryPrefix) GalleryPrefix = null!; + if (null == GalleryPostfix) GalleryPostfix = null!; + if (null == FormPrefix) FormPrefix = null!; + if (null == FormTemplate) FormTemplate = null!; + if (null == FormPostfix) FormPostfix = null!; + if (null == VideoPrefix) VideoPrefix = null!; + if (null == VideoTemplate) VideoTemplate = null!; + if (null == VideoPostfix) VideoPostfix = null!; + if (null == AudioPrefix) AudioPrefix = null!; + if (null == AudioTemplate) AudioTemplate = null!; + if (null == AudioPostfix) AudioPostfix = null!; + if (null == ImagePrefix) ImagePrefix = null!; + if (null == ImageTemplate) ImageTemplate = null!; + if (null == ImagePostfix) ImagePostfix = null!; + if (null == LinkPrefix) LinkPrefix = null!; + if (null == LinkTemplate) LinkTemplate = null!; + if (null == LinkPostfix) LinkPostfix = null!; + if (null == QuotePrefix) QuotePrefix = null!; if (null == QuoteTemplate) QuoteTemplate = new TBlockToken(new[] { new TElementToken { ElementName = "self" } }); - if (null == QuotePostfix) QuotePostfix = null; - if (null == TextPrefix) TextPrefix = null; + if (null == QuotePostfix) QuotePostfix = null!; + if (null == TextPrefix) TextPrefix = null!; if (null == TextTemplate) TextTemplate = new TBlockToken(new[] { new TElementToken { ElementName = "self" } }); - if (null == TextPostfix) TextPostfix = null; + if (null == TextPostfix) TextPostfix = null!; } public void UpdateRule(string elementName, string functionName, TBlockToken rule_token, string special) @@ -134,7 +134,7 @@ namespace DOM.DSL.Model break; case "ignore": - ListPostfix = ListPrefix = null; + ListPostfix = ListPrefix = null!; break; } break; @@ -151,7 +151,7 @@ namespace DOM.DSL.Model break; case "ignore": - ListItemPrefix = ListItemPostfix = null; + ListItemPrefix = ListItemPostfix = null!; break; } break; @@ -172,7 +172,7 @@ namespace DOM.DSL.Model break; case "ignore": - TextPrefix = TextTemplate = TextPostfix = null; + TextPrefix = TextTemplate = TextPostfix = null!; break; } break; @@ -193,7 +193,7 @@ namespace DOM.DSL.Model break; case "ignore": - LinkPrefix = LinkTemplate = LinkPostfix = null; + LinkPrefix = LinkTemplate = LinkPostfix = null!; break; } break; @@ -214,7 +214,7 @@ namespace DOM.DSL.Model break; case "ignore": - ImagePrefix = ImageTemplate = ImagePostfix = null; + ImagePrefix = ImageTemplate = ImagePostfix = null!; break; } break; @@ -235,7 +235,7 @@ namespace DOM.DSL.Model break; case "ignore": - QuotePrefix = QuoteTemplate = QuotePostfix = null; + QuotePrefix = QuoteTemplate = QuotePostfix = null!; break; } break; @@ -256,7 +256,7 @@ namespace DOM.DSL.Model break; case "ignore": - FormPrefix = FormTemplate = FormPostfix = null; + FormPrefix = FormTemplate = FormPostfix = null!; break; } break; @@ -277,7 +277,7 @@ namespace DOM.DSL.Model break; case "ignore": - VideoPrefix = VideoTemplate = VideoPostfix = null; + VideoPrefix = VideoTemplate = VideoPostfix = null!; break; } break; @@ -298,7 +298,7 @@ namespace DOM.DSL.Model break; case "ignore": - AudioPrefix = AudioTemplate = AudioPostfix = null; + AudioPrefix = AudioTemplate = AudioPostfix = null!; break; } break; @@ -315,7 +315,7 @@ namespace DOM.DSL.Model break; case "ignore": - SectionPrefix = SectionPostfix = null; + SectionPrefix = SectionPostfix = null!; break; } break; @@ -332,7 +332,7 @@ namespace DOM.DSL.Model break; case "ignore": - ParagraphPrefix = ParagraphPostfix = null; + ParagraphPrefix = ParagraphPostfix = null!; break; } break; @@ -349,15 +349,15 @@ namespace DOM.DSL.Model break; case "ignore": - TablePrefix = TablePostfix = null; + TablePrefix = TablePostfix = null!; break; case "special": // Using a hardcoded table conversion //TablePrefix = TablePostfix = null; - ColumnsPrefix = ColumnsPostfix = null; - ColumnPrefix = ColumnTemplate = ColumnPostfix = null; - RowPrefix = RowPostfix = null; - CellPrefix = CellPostfix = null; + ColumnsPrefix = ColumnsPostfix = null!; + ColumnPrefix = ColumnTemplate = ColumnPostfix = null!; + RowPrefix = RowPostfix = null!; + CellPrefix = CellPostfix = null!; // Args: (style, paddings l-t-r-b, maxcellwidth, maxtablewidth) UseSpecialTableBuilder = true; SpecialTableBuilder = SpecialTableBuilderFactory.CreateSpecialTableBuilder(special); @@ -378,7 +378,7 @@ namespace DOM.DSL.Model break; case "ignore": - ColumnsPrefix = ColumnsPostfix = null; + ColumnsPrefix = ColumnsPostfix = null!; break; } break; @@ -399,7 +399,7 @@ namespace DOM.DSL.Model break; case "ignore": - ColumnPrefix = ColumnTemplate = ColumnPostfix = null; + ColumnPrefix = ColumnTemplate = ColumnPostfix = null!; break; } break; @@ -416,7 +416,7 @@ namespace DOM.DSL.Model break; case "ignore": - RowPrefix = RowPostfix = null; + RowPrefix = RowPostfix = null!; break; } break; @@ -433,7 +433,7 @@ namespace DOM.DSL.Model break; case "ignore": - CellPrefix = CellPostfix = null; + CellPrefix = CellPostfix = null!; break; } break; @@ -450,7 +450,7 @@ namespace DOM.DSL.Model break; case "ignore": - VideoplayerPrefix = VideoplayerPostfix = null; + VideoplayerPrefix = VideoplayerPostfix = null!; break; } break; @@ -467,7 +467,7 @@ namespace DOM.DSL.Model break; case "ignore": - AudioplayerPrefix = AudioplayerPostfix = null; + AudioplayerPrefix = AudioplayerPostfix = null!; break; } break; @@ -484,7 +484,7 @@ namespace DOM.DSL.Model break; case "ignore": - GalleryPrefix = GalleryPostfix = null; + GalleryPrefix = GalleryPostfix = null!; break; } break; diff --git a/ZeroLevel/Services/DOM/DSL/Services/SpecialTableBuilderFactory.cs b/ZeroLevel/Services/DOM/DSL/Services/SpecialTableBuilderFactory.cs index 161ce40..f7eee0f 100644 --- a/ZeroLevel/Services/DOM/DSL/Services/SpecialTableBuilderFactory.cs +++ b/ZeroLevel/Services/DOM/DSL/Services/SpecialTableBuilderFactory.cs @@ -9,8 +9,8 @@ namespace DOM.DSL.Services { public static ISpecialTableBuilder CreateSpecialTableBuilder(string command) { - if (string.IsNullOrWhiteSpace(command)) return null; - ISpecialTableBuilder result = null; + if (string.IsNullOrWhiteSpace(command)) return null!; + ISpecialTableBuilder result = null!; var args = command.Split(',').Select(s => s.Trim()).ToArray(); switch (args[0]) { diff --git a/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs b/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs index 1118fd4..e07f151 100644 --- a/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs +++ b/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs @@ -63,7 +63,7 @@ namespace DOM.DSL.Services foreach (var i in _list) list.Add(i.ToString()); _elementType = typeof(string); _list.Clear(); - _list = null; + _list = null!; _list = list; list.Add(item.ToString()); } @@ -72,7 +72,7 @@ namespace DOM.DSL.Services public object First() { - return (_list.Count > 0) ? _list[0] : null; + return (_list.Count > 0) ? _list[0] : null!; } public IList Complete() @@ -907,7 +907,7 @@ namespace DOM.DSL.Services private void SelectProperty(TagMetadata tags, string property, string propertyIndex) { - IList enumerable = null; + IList enumerable = null!; switch (property.Trim().ToLowerInvariant()) { case "places": @@ -1322,7 +1322,7 @@ namespace DOM.DSL.Services { if (headers.Count == 0) { - Reset(null); + Reset(null!); } else if (headers.Count == 1) { @@ -1390,7 +1390,7 @@ namespace DOM.DSL.Services { if (_current == null) { - args = null; + args = null!; return; } //args = args_getter(this); @@ -1418,7 +1418,7 @@ namespace DOM.DSL.Services var container = _factory.Get(i); if (args.Length > 1) { - container.MoveToProperty(args[1].ToString(), null); + container.MoveToProperty(args[1].ToString(), null!); } if (result.Length > 0) result.Append(separator); result.Append(container.ToString()); @@ -1439,7 +1439,7 @@ namespace DOM.DSL.Services { var format = (args != null && args.Length > 0) ? args[0].ToString() : null; var culture = (args != null && args.Length > 1) ? args[1].ToString() : null; - Reset(FormattedDateTime((DateTime)_current, format, culture)); + Reset(FormattedDateTime((DateTime)_current, format!, culture!)); } break; @@ -1792,16 +1792,16 @@ namespace DOM.DSL.Services var key = args[0].ToString(); if (_render.BufferDictionary.ContainsKey(key) == false) { - _render.BufferDictionary.Add(key, this._current); + _render.BufferDictionary.Add(key, this._current!); } else { - _render.BufferDictionary[key] = this._current; + _render.BufferDictionary[key] = this._current!; } - Reset(null); + Reset(null!); } } - args = null; + args = null!; return; } if (function.Equals("where", StringComparison.OrdinalIgnoreCase)) @@ -1923,7 +1923,7 @@ namespace DOM.DSL.Services } else { - Reset(null); + Reset(null!); } } else if (_current is string) @@ -1935,7 +1935,7 @@ namespace DOM.DSL.Services } else { - Reset(null); + Reset(null!); } } else if (_current is IEnumerable) @@ -1950,7 +1950,7 @@ namespace DOM.DSL.Services } _i++; } - if (found == false) Reset(null); + if (found == false) Reset(null!); } } } @@ -1969,7 +1969,7 @@ namespace DOM.DSL.Services { if (i == null) continue; var container = _factory.Get(i); - container.MoveToProperty(property, property_index); + container.MoveToProperty(property, property_index!); list.Append(container.Current); _factory.Release(container); } @@ -1978,7 +1978,7 @@ namespace DOM.DSL.Services else { var container = _factory.Get(_current); - container.MoveToProperty(property, property_index); + container.MoveToProperty(property, property_index!); Reset(container.Current); _factory.Release(container); } @@ -2081,10 +2081,15 @@ namespace DOM.DSL.Services if (_current is List) { var list = _current as List; + if (list == null) + { + _current = new List(); + list = _current as List; + } foreach (var i in args) - list.Add(i); - Reset(list); - args = null; + list!.Add(i); + Reset(list!); + args = null!; } break; } @@ -2491,10 +2496,10 @@ namespace DOM.DSL.Services #region Conditions - public bool Any(TContainer[] set = null, bool ignoreCase = true) + public bool Any(TContainer[] set = null!, bool ignoreCase = true) { if (_current == null) return false; - if (set.Any()) + if (set?.Any() ?? false) { if (_current is IEnumerable && false == (_current is string)) { @@ -2524,7 +2529,7 @@ namespace DOM.DSL.Services if (set == null || set?.Length == 0) return false; if (_current is IEnumerable && false == (_current is string)) { - foreach (var t in set) + foreach (var t in set!) { bool contains = false; foreach (var c in (IEnumerable)_current) @@ -2541,7 +2546,7 @@ namespace DOM.DSL.Services else if (_current is string) { var line = (string)_current; - foreach (var t in set) + foreach (var t in set!) { if (line.IndexOf(t.ToString(), StringComparison.OrdinalIgnoreCase) == -1) return false; } @@ -2549,7 +2554,7 @@ namespace DOM.DSL.Services } else { - foreach (var t in set) + foreach (var t in set!) { if (CompareWith(t, ignoreCase) != 0) return false; } @@ -2726,7 +2731,7 @@ namespace DOM.DSL.Services private const string DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; - private static string FormattedDateTime(DateTime dt, string format = null, string culture = null) + private static string FormattedDateTime(DateTime dt, string format = null!, string culture = null!) { CultureInfo ci; if (culture != null) diff --git a/ZeroLevel/Services/DOM/DSL/Services/TRender.cs b/ZeroLevel/Services/DOM/DSL/Services/TRender.cs index ca34f2c..1b69212 100644 --- a/ZeroLevel/Services/DOM/DSL/Services/TRender.cs +++ b/ZeroLevel/Services/DOM/DSL/Services/TRender.cs @@ -57,7 +57,7 @@ namespace DOM.DSL.Services Factory = new TContainerFactory(this); } - public void Resolve(TToken token, Action handler, bool release = true, TContainer self = null) + public void Resolve(TToken token, Action handler, bool release = true, TContainer self = null!) { var self_copy = self == null ? null : Factory.Get(self.Current, self.Index); try @@ -70,7 +70,7 @@ namespace DOM.DSL.Services } else if (token is TElementToken) { - var containers = ResolveElementToken(token.AsElementToken(), self_copy); + var containers = ResolveElementToken(token.AsElementToken(), self_copy!); foreach (var c in containers) { handler(c); @@ -79,7 +79,7 @@ namespace DOM.DSL.Services } else if (token is TBlockToken) { - var containers = ResolveBlockToken(token.AsBlockToken(), self_copy); + var containers = ResolveBlockToken(token.AsBlockToken(), self_copy!); foreach (var c in containers) { handler(c); @@ -89,13 +89,13 @@ namespace DOM.DSL.Services } finally { - Factory.Release(self_copy); + Factory.Release(self_copy!); } } - private TContainer[] ResolveElementToken(TElementToken token, TContainer self = null) + private TContainer[] ResolveElementToken(TElementToken token, TContainer self = null!) { - TContainer container = null; + TContainer container = null!; switch (token.ElementName.Trim().ToLowerInvariant()) { // External @@ -147,7 +147,7 @@ namespace DOM.DSL.Services case "content": container = Factory.Get(new TContentElement(_document)); break; case "aside": container = Factory.Get(_document.Attachments); break; case "assotiations": container = Factory.Get(_document.Assotiations); break; - case "null": container = Factory.Get(null); break; + case "null": container = Factory.Get(null!); break; case "empty": container = Factory.Get(string.Empty); break; // Blocks @@ -165,7 +165,7 @@ namespace DOM.DSL.Services } } - if (container == null) container = Factory.Get(null); + if (container == null) container = Factory.Get(null!); if (token.NextToken is TPropertyToken) { @@ -184,7 +184,7 @@ namespace DOM.DSL.Services private TContainer ResolvePropertyToken(TPropertyToken token, TContainer container) { - string property_index = null; + string property_index = null!; Resolve(token.PropertyIndex, c => property_index = c.ToString()); container.MoveToProperty(token.PropertyName, property_index); if (token.NextToken is TPropertyToken) @@ -223,13 +223,13 @@ namespace DOM.DSL.Services return container; } - private IEnumerable ResolveBlockToken(TBlockToken blockToken, TContainer self_parent = null) + private IEnumerable ResolveBlockToken(TBlockToken blockToken, TContainer self_parent = null!) { switch (blockToken.Name) { case "block": { - string name = null; + string name = null!; Resolve(blockToken.Condition, c => name = c.ToString(), true); if (false == string.IsNullOrWhiteSpace(name)) { @@ -254,19 +254,19 @@ namespace DOM.DSL.Services if (success) { var ls = self_parent == null ? null : Factory.Get(self_parent.Current, self_parent.Index); - result = ResolveSimpleBlockToken(blockToken, ls); + result = ResolveSimpleBlockToken(blockToken, ls!); Factory.Release(ls); } else { - result = new List { Factory.Get(null) }; + result = new List { Factory.Get(null!) }; } return result; } case "for": { var list = new List(); - TContainer self_container = null; + TContainer self_container = null!; Resolve(blockToken.Condition, c => self_container = c, false, self_parent); if (self_container != null) { @@ -292,14 +292,14 @@ namespace DOM.DSL.Services } } } - Factory.Release(self_container); + Factory.Release(self_container!); return list; } } return ResolveSimpleBlockToken(blockToken, self_parent); } - private List ResolveSimpleBlockToken(TBlockToken token, TContainer self = null) + private List ResolveSimpleBlockToken(TBlockToken token, TContainer self = null!) { var block = new List(); foreach (var t in token.Body) @@ -319,23 +319,26 @@ namespace DOM.DSL.Services { var function = token.AsElementToken()?.NextToken?.AsFunctionToken(); var elementName = token.AsElementToken()?.ElementName; - var functionName = function?.FunctionName; - var rule_token = function?.FunctionArgs == null ? - null : - new TBlockToken(function.FunctionArgs.Select(a => a.Clone())); - string special = null; - if (functionName.Equals("special", StringComparison.OrdinalIgnoreCase)) + if (elementName != null) { - var args = new List(); - foreach (var a in function.FunctionArgs) + var functionName = function?.FunctionName ?? string.Empty; + var rule_token = function?.FunctionArgs == null ? + null : + new TBlockToken(function.FunctionArgs.Select(a => a.Clone())); + string special = null!; + if (functionName.Equals("special", StringComparison.OrdinalIgnoreCase)) { - Resolve(a, c => args.Add(c), false); + var args = new List(); + foreach (var a in function?.FunctionArgs ?? Enumerable.Empty()) + { + Resolve(a, c => args.Add(c), false); + } + special = string.Join(",", args.Select(a => a.ToString())); + foreach (var a in args) + Factory.Release(a); } - special = string.Join(",", args.Select(a => a.ToString())); - foreach (var a in args) - Factory.Release(a); + rules.UpdateRule(elementName, functionName, rule_token!, special); } - rules.UpdateRule(elementName, functionName, rule_token, special); } } return Factory.Get(DocumentContentReader.ReadAs(_document, new TContentToStringConverter(this, rules))); @@ -399,7 +402,7 @@ namespace DOM.DSL.Services } break; } - foreach (var a in args) + foreach (var a in args!) { Factory.Release(a); } diff --git a/ZeroLevel/Services/DOM/DSL/Tokens/TBlockToken.cs b/ZeroLevel/Services/DOM/DSL/Tokens/TBlockToken.cs index 29350c7..d45c7ec 100644 --- a/ZeroLevel/Services/DOM/DSL/Tokens/TBlockToken.cs +++ b/ZeroLevel/Services/DOM/DSL/Tokens/TBlockToken.cs @@ -15,20 +15,20 @@ namespace DOM.DSL.Tokens IEnumerable body) { Name = name; - Condition = condition?.Clone(); + Condition = condition?.Clone()!; Body = body.Select(b => b.Clone()).ToArray(); } public TBlockToken(IEnumerable body) { Name = string.Empty; - Condition = null; + Condition = null!; Body = body.Select(b => b.Clone()).ToArray(); } public override TToken Clone() { - return new TBlockToken(this.Name, this.Condition?.Clone(), this.Body?.Select(b => b.Clone()).ToArray()); + return new TBlockToken(this.Name, this.Condition?.Clone()!, this.Body?.Select(b => b.Clone()!).ToArray()!); } public override TToken CloneLocal() diff --git a/ZeroLevel/Services/DOM/Model/DescriptiveMetadata.cs b/ZeroLevel/Services/DOM/Model/DescriptiveMetadata.cs index 5ca4f57..512e287 100644 --- a/ZeroLevel/Services/DOM/Model/DescriptiveMetadata.cs +++ b/ZeroLevel/Services/DOM/Model/DescriptiveMetadata.cs @@ -96,7 +96,7 @@ namespace ZeroLevel.DocumentObjectModel { this.Byline = reader.ReadString(); this.CopyrightNotice = reader.ReadString(); - this.Created = reader.ReadDateTime().Value; + this.Created = reader.ReadDateTime()!.Value; this.Headers = reader.ReadCollection
(); this.Language = reader.ReadString(); this.Original = new Tag(); diff --git a/ZeroLevel/Services/DOM/Model/Document.cs b/ZeroLevel/Services/DOM/Model/Document.cs index 4c23eb3..e59e2ca 100644 --- a/ZeroLevel/Services/DOM/Model/Document.cs +++ b/ZeroLevel/Services/DOM/Model/Document.cs @@ -20,12 +20,14 @@ namespace ZeroLevel.DocumentObjectModel public Document() { - Id = Guid.NewGuid(); Initialize(); + Id = Guid.NewGuid(); + Initialize(); } public Document(Guid id) { - Id = id; Initialize(); + Id = id; + Initialize(); } public Document(IBinaryReader reader) diff --git a/ZeroLevel/Services/DOM/Model/Flow/Audioplayer.cs b/ZeroLevel/Services/DOM/Model/Flow/Audioplayer.cs index 831bea9..48bef67 100644 --- a/ZeroLevel/Services/DOM/Model/Flow/Audioplayer.cs +++ b/ZeroLevel/Services/DOM/Model/Flow/Audioplayer.cs @@ -20,6 +20,8 @@ namespace ZeroLevel.DocumentObjectModel.Flow Deserialize(reader); } + public void SetTitle(Text title) => this.Title = title; + public override void Deserialize(IBinaryReader reader) { Title = reader.Read(); diff --git a/ZeroLevel/Services/DOM/Model/Flow/Gallery.cs b/ZeroLevel/Services/DOM/Model/Flow/Gallery.cs index 487f6aa..8df2524 100644 --- a/ZeroLevel/Services/DOM/Model/Flow/Gallery.cs +++ b/ZeroLevel/Services/DOM/Model/Flow/Gallery.cs @@ -17,6 +17,8 @@ namespace ZeroLevel.DocumentObjectModel.Flow Deserialize(reader); } + public void SetTitle(Text title) => this.Title = title; + public override void Deserialize(IBinaryReader reader) { Title = reader.Read(); diff --git a/ZeroLevel/Services/DOM/Model/Flow/Table.cs b/ZeroLevel/Services/DOM/Model/Flow/Table.cs index 3723206..d26f861 100644 --- a/ZeroLevel/Services/DOM/Model/Flow/Table.cs +++ b/ZeroLevel/Services/DOM/Model/Flow/Table.cs @@ -11,7 +11,8 @@ namespace ZeroLevel.DocumentObjectModel.Flow public List Columns = new List(); public List Rows = new List(); - public Table() : base(ContentElementType.Table) + public Table() + : base(ContentElementType.Table) { } diff --git a/ZeroLevel/Services/DOM/Model/Flow/Videoplayer.cs b/ZeroLevel/Services/DOM/Model/Flow/Videoplayer.cs index 915ed50..9afa56e 100644 --- a/ZeroLevel/Services/DOM/Model/Flow/Videoplayer.cs +++ b/ZeroLevel/Services/DOM/Model/Flow/Videoplayer.cs @@ -20,6 +20,8 @@ namespace ZeroLevel.DocumentObjectModel.Flow Deserialize(reader); } + public void SetTitle(Text title) => this.Title = title; + public override void Deserialize(IBinaryReader reader) { Title = reader.Read(); diff --git a/ZeroLevel/Services/DOM/Services/ContentBuilder.cs b/ZeroLevel/Services/DOM/Services/ContentBuilder.cs index 9e8c22b..f708fc3 100644 --- a/ZeroLevel/Services/DOM/Services/ContentBuilder.cs +++ b/ZeroLevel/Services/DOM/Services/ContentBuilder.cs @@ -185,62 +185,62 @@ namespace DOM.Services switch (current.Type) { case ContentElementType.Section: - (current as Section).Parts.Add(element); + (current as Section)?.Parts?.Add(element); break; case ContentElementType.Paragraph: - (current as Paragraph).Parts.Add(element); + (current as Paragraph)?.Parts?.Add(element); break; case ContentElementType.List: - (current as List).Items.Add(element); + (current as List)?.Items?.Add(element); break; case ContentElementType.Row: - (current as Row).Cells.Add(element); + (current as Row)?.Cells?.Add(element); break; case ContentElementType.Audioplayer: if (element.Type == ContentElementType.Text) { - (current as Audioplayer).Title = element as ZeroLevel.DocumentObjectModel.Flow.Text; + (current as Audioplayer)?.SetTitle((element as ZeroLevel.DocumentObjectModel.Flow.Text)!); } else { - (current as Audioplayer).Tracks.Add(element as Audio); + (current as Audioplayer)?.Tracks?.Add((element as Audio)!); } break; case ContentElementType.Videoplayer: if (element.Type == ContentElementType.Text) { - (current as Videoplayer).Title = element as ZeroLevel.DocumentObjectModel.Flow.Text; + (current as Videoplayer)?.SetTitle((element as ZeroLevel.DocumentObjectModel.Flow.Text)!); } else { - (current as Videoplayer).Playlist.Add(element as Video); + (current as Videoplayer)?.Playlist?.Add((element as Video)!); } break; case ContentElementType.Gallery: if (element.Type == ContentElementType.Text) { - (current as Gallery).Title = element as ZeroLevel.DocumentObjectModel.Flow.Text; + (current as Gallery)?.SetTitle((element as ZeroLevel.DocumentObjectModel.Flow.Text)!); } else { - (current as Gallery).Images.Add(element as Image); + (current as Gallery)?.Images?.Add((element as Image)!); } break; case ContentElementType.Table: if (element.Type == ContentElementType.Column) { - (current as Table).Columns.Add(element as Column); + (current as Table)?.Columns?.Add((element as Column)!); } else if (element.Type == ContentElementType.Row) { - (current as Table).Rows.Add(element as Row); + (current as Table)?.Rows?.Add((element as Row)!); } break; } diff --git a/ZeroLevel/Services/DOM/Services/DocumentContentReader.cs b/ZeroLevel/Services/DOM/Services/DocumentContentReader.cs index d5aafab..f6bbcd7 100644 --- a/ZeroLevel/Services/DOM/Services/DocumentContentReader.cs +++ b/ZeroLevel/Services/DOM/Services/DocumentContentReader.cs @@ -17,132 +17,156 @@ namespace DOM.Services { // Primitives case ContentElementType.Text: - reader.ReadText(element as ZeroLevel.DocumentObjectModel.Flow.Text); + reader.ReadText((element as ZeroLevel.DocumentObjectModel.Flow.Text)!); break; case ContentElementType.Quote: - reader.ReadQuote(element as Quote); + reader.ReadQuote((element as Quote)!); break; case ContentElementType.Link: counter.IncLinkId(); - reader.ReadLink(element as Link, counter.LinkId); + reader.ReadLink((element as Link)!, counter.LinkId); break; case ContentElementType.Image: counter.IncImageId(); - reader.ReadImage(element as Image, counter.ImageId); + reader.ReadImage((element as Image)!, counter.ImageId); break; case ContentElementType.Audio: counter.IncAudioId(); - reader.ReadAudio(element as Audio, counter.AudioId); + reader.ReadAudio((element as Audio)!, counter.AudioId); break; case ContentElementType.Video: counter.IncVideoId(); - reader.ReadVideo(element as Video, counter.VideoId); + reader.ReadVideo((element as Video)!, counter.VideoId); break; case ContentElementType.Form: - reader.ReadForm(element as FormContent); + reader.ReadForm((element as FormContent)!); break; // Containers case ContentElementType.Content: { var content = (element as FlowContent); - for (int i = 0; i < content.Sections.Count; i++) + if (content != null) { - TraversElement(content.Sections[i], reader, counter); + for (int i = 0; i < content.Sections.Count; i++) + { + TraversElement(content.Sections[i], reader, counter); + } } } break; case ContentElementType.Section: var section = (element as Section); - reader.EnterSection(section); - for (int i = 0; i < section.Parts.Count; i++) + if (section != null) { - TraversElement(section.Parts[i], reader, counter); + reader.EnterSection(section); + for (int i = 0; i < section.Parts.Count; i++) + { + TraversElement(section.Parts[i], reader, counter); + } + reader.LeaveSection(section); } - reader.LeaveSection(section); break; case ContentElementType.Paragraph: var paragraph = (element as Paragraph); - reader.EnterParagraph(paragraph); - for (int i = 0; i < paragraph.Parts.Count; i++) + if (paragraph != null) { - TraversElement(paragraph.Parts[i], reader, counter); + reader.EnterParagraph(paragraph); + for (int i = 0; i < paragraph.Parts.Count; i++) + { + TraversElement(paragraph.Parts[i], reader, counter); + } + reader.LeaveParagraph(paragraph); } - reader.LeaveParagraph(paragraph); break; case ContentElementType.List: var list = (element as List); - reader.EnterList(list); - for (int i = 0; i < list.Items.Count; i++) + if (list != null) { - reader.EnterListItem(list, list.Items[i], i); - TraversElement(list.Items[i], reader, counter); - reader.LeaveListItem(list, list.Items[i], i); + reader.EnterList(list); + for (int i = 0; i < list.Items.Count; i++) + { + reader.EnterListItem(list, list.Items[i], i); + TraversElement(list.Items[i], reader, counter); + reader.LeaveListItem(list, list.Items[i], i); + } + reader.LeaveList(list); } - reader.LeaveList(list); break; case ContentElementType.Gallery: var gallery = (element as Gallery); - reader.EnterGallery(gallery); - for (int i = 0; i < gallery.Images.Count; i++) + if (gallery != null) { - reader.ReadImage(gallery.Images[i], i); + reader.EnterGallery(gallery); + for (int i = 0; i < gallery.Images.Count; i++) + { + reader.ReadImage(gallery.Images[i], i); + } + reader.LeaveGallery(gallery); } - reader.LeaveGallery(gallery); break; case ContentElementType.Audioplayer: var audioplayer = (element as Audioplayer); - reader.EnterAudioplayer(audioplayer); - for (int i = 0; i < audioplayer.Tracks.Count; i++) + if (audioplayer != null) { - reader.ReadAudio(audioplayer.Tracks[i], i); + reader.EnterAudioplayer(audioplayer); + for (int i = 0; i < audioplayer.Tracks.Count; i++) + { + reader.ReadAudio(audioplayer.Tracks[i], i); + } + reader.LeaveAudioplayer(audioplayer); } - reader.LeaveAudioplayer(audioplayer); break; case ContentElementType.Videoplayer: var videoplayer = (element as Videoplayer); - reader.EnterVideoplayer(videoplayer); - for (int i = 0; i < videoplayer.Playlist.Count; i++) + if (videoplayer != null) { - reader.ReadVideo(videoplayer.Playlist[i], i); + reader.EnterVideoplayer(videoplayer); + for (int i = 0; i < videoplayer.Playlist.Count; i++) + { + reader.ReadVideo(videoplayer.Playlist[i], i); + } + reader.LeaveVideoplayer(videoplayer); } - reader.LeaveVideoplayer(videoplayer); break; case ContentElementType.Table: var table = (element as Table); - reader.EnterTable(table); - reader.EnterColumns(table); - for (int i = 0; i < table.Columns.Count; i++) + if (table != null) { - reader.ReadColumn(table, table.Columns[i], i); - } - reader.LeaveColumns(table); - for (int ri = 0; ri < table.Rows.Count; ri++) - { - var row = table.Rows[ri]; - reader.EnterRow(table, row, ri); - for (int i = 0; i < row.Cells.Count; i++) + reader.EnterTable(table); + reader.EnterColumns(table); + for (int i = 0; i < table.Columns.Count; i++) + { + reader.ReadColumn(table, table.Columns[i], i); + } + reader.LeaveColumns(table); + for (int ri = 0; ri < table.Rows.Count; ri++) { - reader.EnterRowCell(table, row, row.Cells[i], i); - TraversElement(row.Cells[i], reader, counter); - reader.LeaveRowCell(table, row, row.Cells[i], i); + var row = table.Rows[ri]; + reader.EnterRow(table, row, ri); + for (int i = 0; i < row.Cells.Count; i++) + { + reader.EnterRowCell(table, row, row.Cells[i], i); + TraversElement(row.Cells[i], reader, counter); + reader.LeaveRowCell(table, row, row.Cells[i], i); + } + reader.LeaveRow(table, row, ri); } - reader.LeaveRow(table, row, ri); + reader.LeaveTable(table); } - reader.LeaveTable(table); break; } } diff --git a/ZeroLevel/Services/DependencyInjection/Container.cs b/ZeroLevel/Services/DependencyInjection/Container.cs index a329b59..61176f6 100644 --- a/ZeroLevel/Services/DependencyInjection/Container.cs +++ b/ZeroLevel/Services/DependencyInjection/Container.cs @@ -7,7 +7,7 @@ using System.Threading; using ZeroLevel.Services.Collections; namespace ZeroLevel.DependencyInjection -{ +{ internal sealed class Container : IContainer { @@ -15,29 +15,30 @@ namespace ZeroLevel.DependencyInjection private static object Activate(Type type, object[] args) { + if (type == null) return null!; var flags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public; - CultureInfo culture = null; // use InvariantCulture or other if you prefer + CultureInfo culture = null!; // use InvariantCulture or other if you prefer return Activator.CreateInstance(type, flags, null, args, culture); } public T CreateInstance(string resolveName = "") { - T instance = default(T); + T instance = default(T)!; try { instance = Resolve(resolveName); } catch { - instance = (T)Activate(typeof(T), null); + instance = (T)Activate(typeof(T), null!); } - Compose(instance); + Compose(instance!); return instance; } public T CreateInstance(object[] args, string resolveName = "") { - T instance = default(T); + T instance = default(T)!; try { instance = Resolve(resolveName, args); @@ -46,20 +47,20 @@ namespace ZeroLevel.DependencyInjection { instance = (T)Activate(typeof(T), args); } - Compose(instance); + Compose(instance!); return instance; } public object CreateInstance(Type type, string resolveName = "") { - object instance = null; + object instance = null!; try { instance = Resolve(type, resolveName); } catch { - instance = Activate(type, null); + instance = Activate(type, null!); } Compose(instance); return instance; @@ -67,7 +68,7 @@ namespace ZeroLevel.DependencyInjection public object CreateInstance(Type type, object[] args, string resolveName = "") { - object instance = null; + object instance = null!; try { instance = Resolve(type, resolveName, args); @@ -258,12 +259,12 @@ namespace ZeroLevel.DependencyInjection } var resolveType = FindResolving(maybyType, resolveAttribute?.ResolveName ?? string.Empty, - resolveAttribute?.ContractType); + resolveAttribute?.ContractType!); try { if (is_generic) - return MakeGenericResolving(resolveType, type, null); - return MakeResolving(resolveType, null); + return MakeGenericResolving(resolveType, type, null!); + return MakeResolving(resolveType, null!); } catch (Exception ex) { @@ -375,7 +376,7 @@ namespace ZeroLevel.DependencyInjection if (_resolvingMap[contractType]. Any(it => it.ResolveKey.Equals(resolveType.ResolveKey, StringComparison.OrdinalIgnoreCase))) { - throw new Exception($"Resolve type with the same name '{resolveType.ResolveKey}' already has been defined. Contract: { contractType.FullName}"); + throw new Exception($"Resolve type with the same name '{resolveType.ResolveKey}' already has been defined. Contract: {contractType.FullName}"); } } try @@ -667,7 +668,7 @@ namespace ZeroLevel.DependencyInjection #region Safe register - public bool TryRegister(Action fallback = null) + public bool TryRegister(Action fallback = null!) { try { @@ -681,7 +682,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(bool shared, Action fallback = null) + public bool TryRegister(bool shared, Action fallback = null!) { try { @@ -695,7 +696,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(string resolveName, Action fallback = null) + public bool TryRegister(string resolveName, Action fallback = null!) { try { @@ -709,7 +710,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(string resolveName, bool shared, Action fallback = null) + public bool TryRegister(string resolveName, bool shared, Action fallback = null!) { try { @@ -723,7 +724,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(Type contractType, Type implementationType, Action fallback = null) + public bool TryRegister(Type contractType, Type implementationType, Action fallback = null!) { try { @@ -737,7 +738,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(Type contractType, Type implementationType, string resolveName, Action fallback = null) + public bool TryRegister(Type contractType, Type implementationType, string resolveName, Action fallback = null!) { try { @@ -751,7 +752,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(Type contractType, Type implementationType, bool shared, Action fallback = null) + public bool TryRegister(Type contractType, Type implementationType, bool shared, Action fallback = null!) { try { @@ -765,7 +766,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryRegister(Type contractType, Type implementationType, string resolveName, bool shared, Action fallback = null) + public bool TryRegister(Type contractType, Type implementationType, string resolveName, bool shared, Action fallback = null!) { try { @@ -783,7 +784,7 @@ namespace ZeroLevel.DependencyInjection #region Safe register with parameters - public bool TryParameterizedRegister(object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(object[] constructorParameters, Action fallback = null!) { try { @@ -797,7 +798,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(string resolveName, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(string resolveName, object[] constructorParameters, Action fallback = null!) { try { @@ -811,7 +812,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(bool shared, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(bool shared, object[] constructorParameters, Action fallback = null!) { try { @@ -825,7 +826,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(string resolveName, bool shared, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(string resolveName, bool shared, object[] constructorParameters, Action fallback = null!) { try { @@ -839,7 +840,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(Type contractType, Type implementationType, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(Type contractType, Type implementationType, object[] constructorParameters, Action fallback = null!) { try { @@ -853,7 +854,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(Type contractType, Type implementationType, string resolveName, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(Type contractType, Type implementationType, string resolveName, object[] constructorParameters, Action fallback = null!) { try { @@ -867,7 +868,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(Type contractType, Type implementationType, bool shared, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(Type contractType, Type implementationType, bool shared, object[] constructorParameters, Action fallback = null!) { try { @@ -881,7 +882,7 @@ namespace ZeroLevel.DependencyInjection } } - public bool TryParameterizedRegister(Type contractType, Type implementationType, string resolveName, bool shared, object[] constructorParameters, Action fallback = null) + public bool TryParameterizedRegister(Type contractType, Type implementationType, string resolveName, bool shared, object[] constructorParameters, Action fallback = null!) { try { @@ -901,7 +902,7 @@ namespace ZeroLevel.DependencyInjection public object Resolve(Type type, bool compose = true) { - return Resolve(type, string.Empty, null, compose); + return Resolve(type, string.Empty, null!, compose); } public object Resolve(Type type, object[] args, bool compose = true) @@ -911,12 +912,12 @@ namespace ZeroLevel.DependencyInjection public object Resolve(Type type, string resolveName, bool compose = true) { - return Resolve(type, resolveName, null, compose); + return Resolve(type, resolveName, null!, compose); } public T Resolve(bool compose = true) { - return (T)Resolve(typeof(T), string.Empty, null, compose); + return (T)Resolve(typeof(T), string.Empty, null!, compose); } public T Resolve(object[] args, bool compose = true) @@ -926,7 +927,7 @@ namespace ZeroLevel.DependencyInjection public T Resolve(string resolveName, bool compose = true) { - return (T)Resolve(typeof(T), resolveName, null, compose); + return (T)Resolve(typeof(T), resolveName, null!, compose); } public T Resolve(string resolveName, object[] args, bool compose = true) @@ -980,7 +981,7 @@ namespace ZeroLevel.DependencyInjection { _rwLock.ExitReadLock(); } - return new Tuple(null, false); + return new Tuple(null!, false); } public object Resolve(Type type, string resolveName, object[] args, bool compose = true) @@ -1009,7 +1010,7 @@ namespace ZeroLevel.DependencyInjection public object TryResolve(Type type, out object result, bool compose = true) { - return TryResolve(type, string.Empty, null, out result, compose); + return TryResolve(type, string.Empty, null!, out result, compose); } public object TryResolve(Type type, object[] args, out object result, bool compose = true) @@ -1019,18 +1020,18 @@ namespace ZeroLevel.DependencyInjection public object TryResolve(Type type, string resolveName, out object result, bool compose = true) { - return TryResolve(type, resolveName, null, out result, compose); + return TryResolve(type, resolveName, null!, out result, compose); } public bool TryResolve(out T result, bool compose = true) { object instance; - if (TryResolve(typeof(T), string.Empty, null, out instance, compose)) + if (TryResolve(typeof(T), string.Empty, null!, out instance, compose)) { result = (T)instance; return true; } - result = default(T); + result = default(T)!; return false; } @@ -1042,19 +1043,19 @@ namespace ZeroLevel.DependencyInjection result = (T)instance; return true; } - result = default(T); + result = default(T)!; return false; } public bool TryResolve(string resolveName, out T result, bool compose = true) { object instance; - if (TryResolve(typeof(T), resolveName, null, out instance, compose)) + if (TryResolve(typeof(T), resolveName, null!, out instance, compose)) { result = (T)instance; return true; } - result = default(T); + result = default(T)!; return false; } @@ -1066,7 +1067,7 @@ namespace ZeroLevel.DependencyInjection result = (T)instance; return true; } - result = default(T); + result = default(T)!; return false; } @@ -1076,7 +1077,7 @@ namespace ZeroLevel.DependencyInjection var resolve = GetResolvedType(type, resolveName); if (null == resolve.Item1) { - result = null; + result = null!; return false; } try @@ -1096,7 +1097,7 @@ namespace ZeroLevel.DependencyInjection Log.SystemWarning( $"Can't create type '{type.FullName}' instance for resolve dependency with contract type '{type.FullName}' and dependency name '{resolveName}'", ex); } - result = null; + result = null!; return false; } @@ -1109,62 +1110,71 @@ namespace ZeroLevel.DependencyInjection /// private void FillParametrizedFieldsAndProperties(object instance) { - foreach (var property in instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)) + if (instance != null) { - var attr = property.GetCustomAttribute(); - if (attr != null) + foreach (var property in instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)) { - var parameterType = attr.Type ?? property.PropertyType; - var parameterName = attr.Name ?? property.Name; - property.SetValue(instance, this.Get(parameterType, parameterName)); + var attr = property.GetCustomAttribute(); + if (attr != null) + { + var parameterType = attr.Type ?? property.PropertyType; + var parameterName = attr.Name ?? property.Name; + property.SetValue(instance, this.Get(parameterType, parameterName)); + } } - } - foreach (var field in instance.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)) - { - var attr = field.GetCustomAttribute(); - if (attr != null) + foreach (var field in instance.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)) { - var parameterType = attr.Type ?? field.FieldType; - var parameterName = string.IsNullOrWhiteSpace(attr.Name) ? field.Name : attr.Name; - field.SetValue(instance, this.Get(parameterType, parameterName)); + var attr = field.GetCustomAttribute(); + if (attr != null) + { + var parameterType = attr.Type ?? field.FieldType; + var parameterName = string.IsNullOrWhiteSpace(attr.Name) ? field.Name : attr.Name; + field.SetValue(instance, this.Get(parameterType, parameterName)); + } } } } private void ComposeParts(object instance) { - var resolve_properties = CollectResolvingProperties(instance.GetType()); - var resolve_fields = CollectResolvingFields(instance.GetType()); - foreach (var p in resolve_properties) - { - var resolve_instance = MakeInstanceBy(p.PropertyType, - p.GetCustomAttribute()); - p.SetValue(instance, resolve_instance); - } - foreach (var f in resolve_fields) + if (instance != null) { - var resolve_instance = MakeInstanceBy(f.FieldType, - f.GetCustomAttribute()); - f.SetValue(instance, resolve_instance); + var resolve_properties = CollectResolvingProperties(instance.GetType()); + var resolve_fields = CollectResolvingFields(instance.GetType()); + foreach (var p in resolve_properties) + { + var resolve_instance = MakeInstanceBy(p.PropertyType, + p.GetCustomAttribute()); + p.SetValue(instance, resolve_instance); + } + foreach (var f in resolve_fields) + { + var resolve_instance = MakeInstanceBy(f.FieldType, + f.GetCustomAttribute()); + f.SetValue(instance, resolve_instance); + } } FillParametrizedFieldsAndProperties(instance); } private void RecursiveCompose(object instance, HashSet set) { - foreach (var f in + if (instance != null) + { + foreach (var f in instance.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) - { - if (f.FieldType.IsClass || f.FieldType.IsInterface) { - var next = f.GetValue(instance); - if (null != next) + if (f.FieldType.IsClass || f.FieldType.IsInterface) { - if (set.Add(next)) + var next = f.GetValue(instance); + if (null != next) { - RecursiveCompose(next, set); + if (set.Add(next)) + { + RecursiveCompose(next, set); + } } } } @@ -1219,7 +1229,7 @@ namespace ZeroLevel.DependencyInjection { Log.SystemError(ex, $"[Container] Singletone dispose error. Instance: '{item?.GetType()?.FullName ?? string.Empty}'"); } - if (item.GenericInstanceCachee != null) + if (item!.GenericInstanceCachee != null) { foreach (var gitem in item.GenericInstanceCachee.Values) { diff --git a/ZeroLevel/Services/FileSystem/FSUtils.cs b/ZeroLevel/Services/FileSystem/FSUtils.cs index 4e8dcbb..844a656 100644 --- a/ZeroLevel/Services/FileSystem/FSUtils.cs +++ b/ZeroLevel/Services/FileSystem/FSUtils.cs @@ -275,7 +275,7 @@ namespace ZeroLevel.Services.FileSystem /// public static bool IsFileLocked(FileInfo file) { - FileStream fileStream = null; + FileStream fileStream = null!; try { fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None); @@ -291,14 +291,14 @@ namespace ZeroLevel.Services.FileSystem fileStream.Close(); fileStream.Dispose(); } - file = null; + file = null!; } return false; } public static bool IsFileLocked(string file) { - FileStream fileStream = null; + FileStream fileStream = null!; try { fileStream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None); @@ -314,7 +314,7 @@ namespace ZeroLevel.Services.FileSystem fileStream.Close(); fileStream.Dispose(); } - file = null; + file = null!; } return false; } diff --git a/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs b/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs index 25ce6eb..a0f4926 100644 --- a/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs +++ b/ZeroLevel/Services/FileSystem/PeriodicFileSystemWatcher.cs @@ -65,7 +65,7 @@ namespace ZeroLevel.Services.FileSystem private void CheckSourceFolder() { - string[] files = null; + string[] files = null!; try { files = GetFilesFromSource(); diff --git a/ZeroLevel/Services/IL.cs b/ZeroLevel/Services/IL.cs index e2612ac..2a62ba6 100644 --- a/ZeroLevel/Services/IL.cs +++ b/ZeroLevel/Services/IL.cs @@ -172,7 +172,7 @@ namespace ZeroLevel.Services var returnType = method.ReturnType; var parametersTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); var hasReturnValue = returnType != typeof(void); - MethodBuilder dynamicMethod = null; + MethodBuilder dynamicMethod = null!; switch (methodType) { case MethodType.DirectProxy: diff --git a/ZeroLevel/Services/Invokation/InvokeWrapper.cs b/ZeroLevel/Services/Invokation/InvokeWrapper.cs index f3ff41d..6cb11ab 100644 --- a/ZeroLevel/Services/Invokation/InvokeWrapper.cs +++ b/ZeroLevel/Services/Invokation/InvokeWrapper.cs @@ -157,8 +157,12 @@ namespace ZeroLevel.Services.Invokation BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.Where(filter) ?.Select(method => method.MakeGenericMethod(typeof(T))).Select(CreateCompiledExpression); - Configure(result); - return result.Select(r => r.Item1).ToList(); + if (result != null) + { + Configure(result); + return result.Select(r => r.Item1).ToList(); + } + return Enumerable.Empty(); } public IEnumerable ConfigureGeneric(Type instanceType, Type genericType, Func filter) @@ -169,8 +173,12 @@ namespace ZeroLevel.Services.Invokation BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.Where(filter) ?.Select(method => method.MakeGenericMethod(genericType)).Select(CreateCompiledExpression); - Configure(result); - return result.Select(r => r.Item1).ToList(); + if (result != null) + { + Configure(result); + return result.Select(r => r.Item1).ToList(); + } + return Enumerable.Empty(); } public IEnumerable Configure(Type instanceType, Func filter) @@ -181,8 +189,12 @@ namespace ZeroLevel.Services.Invokation BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.Where(filter) ?.Select(CreateCompiledExpression); - Configure(result); - return result.Select(r => r.Item1).ToList(); + if (result != null) + { + Configure(result); + return result.Select(r => r.Item1).ToList(); + } + return Enumerable.Empty(); } #endregion Configure by Type diff --git a/ZeroLevel/Services/Logging/Implementation/EncryptedFileLog.cs b/ZeroLevel/Services/Logging/Implementation/EncryptedFileLog.cs index 17d9066..6efb184 100644 --- a/ZeroLevel/Services/Logging/Implementation/EncryptedFileLog.cs +++ b/ZeroLevel/Services/Logging/Implementation/EncryptedFileLog.cs @@ -112,7 +112,7 @@ namespace ZeroLevel.Logging { var nextFileName = GetNextFileName(); CloseCurrentWriter(); - Stream stream = null; + Stream stream = null!; try { _currentLogFile = nextFileName; diff --git a/ZeroLevel/Services/MemoryPools/Collections/Linq/Distinct.Enumerable.cs b/ZeroLevel/Services/MemoryPools/Collections/Linq/Distinct.Enumerable.cs index 4d50c67..649eaff 100644 --- a/ZeroLevel/Services/MemoryPools/Collections/Linq/Distinct.Enumerable.cs +++ b/ZeroLevel/Services/MemoryPools/Collections/Linq/Distinct.Enumerable.cs @@ -74,20 +74,20 @@ namespace MemoryPools.Collections.Linq public void Reset() => _src.Reset(); - object IPoolingEnumerator.Current => Current; + object IPoolingEnumerator.Current => Current!; public T Current => _src.Current; public void Dispose() { _parent?.Dispose(); - _parent = default; + _parent = default!; _hashset?.Dispose(); - _hashset = default; + _hashset = default!; - _src = default; - _selector = default; + _src = default!; + _selector = default!; Pool.Return(this); } } diff --git a/ZeroLevel/Services/MemoryPools/Collections/Specialized/LocalList.cs b/ZeroLevel/Services/MemoryPools/Collections/Specialized/LocalList.cs index ef61350..59283f6 100644 --- a/ZeroLevel/Services/MemoryPools/Collections/Specialized/LocalList.cs +++ b/ZeroLevel/Services/MemoryPools/Collections/Specialized/LocalList.cs @@ -16,8 +16,8 @@ namespace MemoryPools.Collections.Specialized private IList _other; // Static lists to store real length (-1 field in struct) - private static readonly IList LengthIs1 = new List {default}; - private static readonly IList LengthIs2 = new List {default, default}; + private static readonly IList LengthIs1 = new List {default!}; + private static readonly IList LengthIs2 = new List {default!, default!}; private const int DefaultListCapacity = 8; public const int LocalStoreCapacity = 2; @@ -238,7 +238,7 @@ namespace MemoryPools.Collections.Specialized throw new IndexOutOfRangeException(); if (_other?.Count > LocalStoreCapacity) return _other[index]; - if (_other.Count > 0 && index == 0) return _items.Item1; + if (_other!.Count > 0 && index == 0) return _items.Item1; if (_other.Count > 1 && index == 1) return _items.Item2; throw new InvalidOperationException("Uncovered branch"); diff --git a/ZeroLevel/Services/Semantic/Trie.cs b/ZeroLevel/Services/Semantic/Trie.cs index 357c5cd..760c754 100644 --- a/ZeroLevel/Services/Semantic/Trie.cs +++ b/ZeroLevel/Services/Semantic/Trie.cs @@ -76,7 +76,7 @@ namespace ZeroLevel.Services.Semantic } internal uint? GetKey(string word, int index) { - if (this.Children?.ContainsKey(word[index]) ?? false) + if (word != null && (this.Children?.ContainsKey(word[index]) ?? false)) { if (word.Length == index + 1) return this.Children[word[index]].Value; return this.Children[word[index]].GetKey(word, index + 1); @@ -103,7 +103,7 @@ namespace ZeroLevel.Services.Semantic internal void DestroyReverseIndex() { - this.Parent = null; + this.Parent = null!; this.Key = null; if (this.Children != null) { @@ -189,7 +189,7 @@ namespace ZeroLevel.Services.Semantic { do { - yield return node.Key.Value; + yield return node.Key!.Value; node = node.Parent; } while (node.Parent != null); } @@ -198,7 +198,7 @@ namespace ZeroLevel.Services.Semantic public bool Contains(string word) { if (word?.Length == 0) return false; - return _root.GetKey(word, 0).HasValue; + return _root.GetKey(word!, 0).HasValue; } public void Serialize(IBinaryWriter writer) @@ -224,7 +224,7 @@ namespace ZeroLevel.Services.Semantic { _reverse_index = new Dictionary(); } - _root.RebuildReverseIndex(null, ' ', _reverse_index); + _root.RebuildReverseIndex(null!, ' ', _reverse_index); } } @@ -233,7 +233,7 @@ namespace ZeroLevel.Services.Semantic if (_reverse_index != null) { _reverse_index.Clear(); - _reverse_index = null; + _reverse_index = null!; } _root.DestroyReverseIndex(); } diff --git a/ZeroLevel/Services/Serialization/MessageSerializer.cs b/ZeroLevel/Services/Serialization/MessageSerializer.cs index 0db4b79..ca60f00 100644 --- a/ZeroLevel/Services/Serialization/MessageSerializer.cs +++ b/ZeroLevel/Services/Serialization/MessageSerializer.cs @@ -213,12 +213,12 @@ namespace ZeroLevel.Services.Serialization public static T DeserializeCompatible(byte[] data) { - if (data == null || data.Length == 0) return default(T); + if (data == null || data.Length == 0) return default(T)!; if (typeof(IBinarySerializable).IsAssignableFrom(typeof(T))) { using (var reader = new MemoryStreamReader(data)) { - var direct = (IBinarySerializable)Activator.CreateInstance(); + var direct = (IBinarySerializable)Activator.CreateInstance()!; direct.Deserialize(reader); return (T)direct; } @@ -233,7 +233,7 @@ namespace ZeroLevel.Services.Serialization { if (typeof(IBinarySerializable).IsAssignableFrom(typeof(T))) { - var direct = (IBinarySerializable)Activator.CreateInstance(); + var direct = (IBinarySerializable)Activator.CreateInstance()!; direct.Deserialize(reader); return (T)direct; } @@ -243,16 +243,16 @@ namespace ZeroLevel.Services.Serialization { if (typeof(IAsyncBinarySerializable).IsAssignableFrom(typeof(T))) { - var direct = (IAsyncBinarySerializable)Activator.CreateInstance(); + var direct = (IAsyncBinarySerializable)Activator.CreateInstance()!; await direct.DeserializeAsync(reader); return (T)direct; } - return PrimitiveTypeSerializer.Deserialize(reader as IBinaryReader); + return PrimitiveTypeSerializer.Deserialize((reader as IBinaryReader)!); } public static object DeserializeCompatible(Type type, byte[] data) { - if (data == null || data.Length == 0) return null; + if (data == null || data.Length == 0) return null!; if (typeof(IBinarySerializable).IsAssignableFrom(type)) { using (var reader = new MemoryStreamReader(data)) @@ -271,7 +271,7 @@ namespace ZeroLevel.Services.Serialization public static T Copy(T value) where T : IBinarySerializable { - if (null == value) return default; + if (null == value) return default!; using (var writer = new MemoryStreamWriter()) { value.Serialize(writer); @@ -290,10 +290,10 @@ namespace ZeroLevel.Services.Serialization { using (var writer = new MemoryStreamWriter()) { - ((IBinarySerializable)value).Serialize(writer); + (value as IBinarySerializable)?.Serialize(writer); using (var reader = new MemoryStreamReader(writer.Complete())) { - var direct = (IBinarySerializable)Activator.CreateInstance(); + var direct = (IBinarySerializable)Activator.CreateInstance()!; direct.Deserialize(reader); return (T)direct; } diff --git a/ZeroLevel/Services/Specification/Services/SpecificationBuilder.cs b/ZeroLevel/Services/Specification/Services/SpecificationBuilder.cs index 0fd7208..08c2e91 100644 --- a/ZeroLevel/Services/Specification/Services/SpecificationBuilder.cs +++ b/ZeroLevel/Services/Specification/Services/SpecificationBuilder.cs @@ -81,14 +81,14 @@ namespace ZeroLevel.Specification case SpecificationConstructorParameterKind.Tree: var tree = (ITree)_values[i].Value; var list = new List(); - Action visitor = null; + Action visitor = null!; visitor = new Action(node => { if (node.IsSelected) { if (node.Tag != null || _values[i].ParameterType.GetElementType() != typeof(string)) { - list.Add(node.Tag); + list.Add(node.Tag!); } else { @@ -116,7 +116,7 @@ namespace ZeroLevel.Specification public override bool Equals(object obj) { - return this.Equals(obj as ISpecificationBuilder); + return this.Equals((obj as ISpecificationBuilder)!); } public bool Equals(ISpecificationBuilder other) diff --git a/ZeroLevel/Services/Web/UrlBuilder.cs b/ZeroLevel/Services/Web/UrlBuilder.cs index f1cff1a..1bc9e0a 100644 --- a/ZeroLevel/Services/Web/UrlBuilder.cs +++ b/ZeroLevel/Services/Web/UrlBuilder.cs @@ -20,7 +20,7 @@ namespace ZeroLevel.Services.Web { if (null == instance) { - return BuildRequestUrl(baseUri, resource, null); + return BuildRequestUrl(baseUri, resource, null!); } var members = typeof(T).GetMembers( BindingFlags.Public | @@ -34,10 +34,10 @@ namespace ZeroLevel.Services.Web switch (member.MemberType) { case MemberTypes.Property: - parameters.Add(member.Name.ToLowerInvariant(), (member as PropertyInfo).GetValue(instance)); + parameters.Add(member.Name.ToLowerInvariant(), (member as PropertyInfo)!.GetValue(instance)); break; case MemberTypes.Field: - parameters.Add(member.Name.ToLowerInvariant(), (member as FieldInfo).GetValue(instance)); + parameters.Add(member.Name.ToLowerInvariant(), (member as FieldInfo)!.GetValue(instance)); break; default: continue; diff --git a/ZeroLevel/Services/Web/UrlUtility.cs b/ZeroLevel/Services/Web/UrlUtility.cs index 5672420..4cf18cc 100644 --- a/ZeroLevel/Services/Web/UrlUtility.cs +++ b/ZeroLevel/Services/Web/UrlUtility.cs @@ -497,8 +497,8 @@ namespace ZeroLevel.Services.Web i++; } // extract the name / value pair - string name = null; - string value = null; + string name = null!; + string value = null!; if (ti >= 0) { name = s.Substring(si, ti - si); diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj index 4313e66..a1106e8 100644 --- a/ZeroLevel/ZeroLevel.csproj +++ b/ZeroLevel/ZeroLevel.csproj @@ -6,14 +6,37 @@ enable lz.ico True + ZeroLevel + 4.0.0.0 + 4.0.0.0 + latest + $(AssemblyVersion) + Ogoun + Basic Toolkit. + © ogoun + https://github.com/ogoun/Zero + lz.ico + https://github.com/ogoun/Zero + git + + + + 1701;1702;8618 + + + + 1701;1702;8618 - + - + + True + \ +