diff --git a/!Docs/Related Files/FileGrayscaleEffect.fx b/!Docs/Related Files/FileGrayscaleEffect.fx deleted file mode 100644 index 3a6d53b..0000000 --- a/!Docs/Related Files/FileGrayscaleEffect.fx +++ /dev/null @@ -1,8 +0,0 @@ -sampler2D implicitInput : register(s0); - -float4 main(float2 uv : TEXCOORD) : COLOR -{ - float4 color = tex2D(implicitInput, uv); - color.rgb = dot(color.rgb, float3(.3, .59, .11)); - return color; -} \ No newline at end of file diff --git a/!Docs/Related Files/GeoLite2.url b/!Docs/Related Files/GeoLite2.url deleted file mode 100644 index 6b3156a..0000000 --- a/!Docs/Related Files/GeoLite2.url +++ /dev/null @@ -1,5 +0,0 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,11 -[InternetShortcut] -IDList= -URL=https://dev.maxmind.com/geoip/geoip2/geolite2/ diff --git a/.gitignore b/.gitignore index be2577e..3698cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,4 @@ TestResults/ *~*.xlsx *~*.docx -$Build/ -$Help/ \ No newline at end of file +$Build/ \ No newline at end of file diff --git a/.nuget/Icons/namespace.png b/.nuget/Icons/namespace.png new file mode 100644 index 0000000..a47634d Binary files /dev/null and b/.nuget/Icons/namespace.png differ diff --git a/.nuget/PackageIcon.pdn b/.nuget/PackageIcon.pdn new file mode 100644 index 0000000..347df60 Binary files /dev/null and b/.nuget/PackageIcon.pdn differ diff --git a/.nuget/PackageIcon.png b/.nuget/PackageIcon.png new file mode 100644 index 0000000..ae5749a Binary files /dev/null and b/.nuget/PackageIcon.png differ diff --git a/Build.GeoIP/App.config b/Build.GeoIP/App.config deleted file mode 100644 index e0767ee..0000000 --- a/Build.GeoIP/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Build.GeoIP/Build.GeoIP.csproj b/Build.GeoIP/Build.GeoIP.csproj deleted file mode 100644 index a328bdd..0000000 --- a/Build.GeoIP/Build.GeoIP.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - - Debug - AnyCPU - {5EA1BD73-E9C2-453C-A76A-691E2F5096BC} - Exe - Build.GeoIP - Build.GeoIP - v4.6.1 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - latest - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - latest - false - - - - - - - - - - - - - - - - - - - - - - - - - - {a3e69e94-20b1-4e18-b3e3-15e56a7f0288} - BytecodeApi.FileFormats - - - {ea00307e-ce27-4a53-b7db-052181e1c24c} - BytecodeApi - - - - - - - \ No newline at end of file diff --git a/Build.GeoIP/CsvData.cs b/Build.GeoIP/CsvData.cs deleted file mode 100644 index 27bfa15..0000000 --- a/Build.GeoIP/CsvData.cs +++ /dev/null @@ -1,61 +0,0 @@ -using BytecodeApi.Data; -using BytecodeApi.IO; -using BytecodeApi.IO.Http; -using System.IO; -using System.Linq; - -namespace Build.GeoIP -{ - public class CsvData - { - public byte[] Country; - public byte[] Range; - public byte[] Range6; - public byte[] Asn; - public byte[] Asn6; - public byte[] City; - public byte[] CityRange; - public byte[] CityRange6; - - public static CsvData ImportFromCloud() - { - CsvData csvData = new CsvData(); - - BlobTree countryBlob = ZipCompression.Decompress(HttpClient.Default.CreateGetRequest("https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip").ReadBytes()); - BlobTree asnBlob = ZipCompression.Decompress(HttpClient.Default.CreateGetRequest("https://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN-CSV.zip").ReadBytes()); - BlobTree cityBlob = ZipCompression.Decompress(HttpClient.Default.CreateGetRequest("https://geolite.maxmind.com/download/geoip/database/GeoLite2-City-CSV.zip").ReadBytes()); - - csvData.Country = FindBlob(countryBlob, "GeoLite2-Country-Locations-en.csv"); - csvData.Range = FindBlob(countryBlob, "GeoLite2-Country-Blocks-IPv4.csv"); - csvData.Range6 = FindBlob(countryBlob, "GeoLite2-Country-Blocks-IPv6.csv"); - csvData.Asn = FindBlob(asnBlob, "GeoLite2-ASN-Blocks-IPv4.csv"); - csvData.Asn6 = FindBlob(asnBlob, "GeoLite2-ASN-Blocks-IPv6.csv"); - csvData.City = FindBlob(cityBlob, "GeoLite2-City-Locations-en.csv"); - csvData.CityRange = FindBlob(cityBlob, "GeoLite2-City-Blocks-IPv4.csv"); - csvData.CityRange6 = FindBlob(cityBlob, "GeoLite2-City-Blocks-IPv6.csv"); - - return csvData; - - byte[] FindBlob(BlobTree blobs, string name) - { - return blobs.Root.Nodes.First().Blobs[name].Content; - } - } - public static CsvData ImportFromFiles() - { - const string path = @"A:\Downloads"; - CsvData csvData = new CsvData(); - - csvData.Country = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-Country-CSV\GeoLite2-Country-Locations-en.csv")); - csvData.Range = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-Country-CSV\GeoLite2-Country-Blocks-IPv4.csv")); - csvData.Range6 = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-Country-CSV\GeoLite2-Country-Blocks-IPv6.csv")); - csvData.Asn = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-ASN-CSV\GeoLite2-ASN-Blocks-IPv4.csv")); - csvData.Asn6 = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-ASN-CSV\GeoLite2-ASN-Blocks-IPv6.csv")); - csvData.City = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-City-CSV\GeoLite2-City-Locations-en.csv")); - csvData.CityRange = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-City-CSV\GeoLite2-City-Blocks-IPv4.csv")); - csvData.CityRange6 = File.ReadAllBytes(Path.Combine(path, @"GeoLite2-City-CSV\GeoLite2-City-Blocks-IPv6.csv")); - - return csvData; - } - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/Asn.cs b/Build.GeoIP/Data/Asn.cs deleted file mode 100644 index 401eebb..0000000 --- a/Build.GeoIP/Data/Asn.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class Asn - { - public int Number; - public string Organization; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/AsnRange.cs b/Build.GeoIP/Data/AsnRange.cs deleted file mode 100644 index 880ca97..0000000 --- a/Build.GeoIP/Data/AsnRange.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class AsnRange - { - public int Asn; - public uint From; - public uint To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/AsnRange6.cs b/Build.GeoIP/Data/AsnRange6.cs deleted file mode 100644 index 07be9e5..0000000 --- a/Build.GeoIP/Data/AsnRange6.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class AsnRange6 - { - public int Asn; - public byte[] From; - public byte[] To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/City.cs b/Build.GeoIP/Data/City.cs deleted file mode 100644 index ef0ef2c..0000000 --- a/Build.GeoIP/Data/City.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class City - { - public int ID; - public byte CountryIndex; - public string Name; - public string Subdivision1Name; - public string Subdivision1IsoCode; - public string Subdivision2Name; - public string Subdivision2IsoCode; - public string TimeZone; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/CityRange.cs b/Build.GeoIP/Data/CityRange.cs deleted file mode 100644 index 8ff5324..0000000 --- a/Build.GeoIP/Data/CityRange.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class CityRange - { - public int CityIndex; - public string PostalCode; - public float Latitude; - public float Longitude; - public short AccuracyRadius; - public uint From; - public uint To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/CityRange6.cs b/Build.GeoIP/Data/CityRange6.cs deleted file mode 100644 index e5576f0..0000000 --- a/Build.GeoIP/Data/CityRange6.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class CityRange6 - { - public int CityIndex; - public string PostalCode; - public float Latitude; - public float Longitude; - public short AccuracyRadius; - public byte[] From; - public byte[] To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/Country.cs b/Build.GeoIP/Data/Country.cs deleted file mode 100644 index a189918..0000000 --- a/Build.GeoIP/Data/Country.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class Country - { - public int ID; - public string Name; - public string IsoCode; - public string Continent; - public string ContinentIsoCode; - public bool EuropeanUnion; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/IPRange.cs b/Build.GeoIP/Data/IPRange.cs deleted file mode 100644 index 61c0df4..0000000 --- a/Build.GeoIP/Data/IPRange.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class IPRange - { - public byte CountryIndex; - public uint From; - public uint To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Data/IPRange6.cs b/Build.GeoIP/Data/IPRange6.cs deleted file mode 100644 index 46e1947..0000000 --- a/Build.GeoIP/Data/IPRange6.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Build.GeoIP.Data -{ - public sealed class IPRange6 - { - public byte CountryIndex; - public byte[] From; - public byte[] To; - } -} \ No newline at end of file diff --git a/Build.GeoIP/Program.cs b/Build.GeoIP/Program.cs deleted file mode 100644 index 4336cf1..0000000 --- a/Build.GeoIP/Program.cs +++ /dev/null @@ -1,409 +0,0 @@ -using Build.GeoIP.Data; -using BytecodeApi; -using BytecodeApi.Extensions; -using BytecodeApi.FileFormats.Csv; -using BytecodeApi.IO; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; - -namespace Build.GeoIP -{ - public static class Program - { - private static CsvData Csv; - private static Country[] Countries; - private static IPRange[] IPRanges; - private static IPRange6[] IPRanges6; - private static List Asns; - private static AsnRange[] AsnRanges; - private static AsnRange6[] AsnRanges6; - private static City[] Cities; - private static CityRange[] CityRanges; - private static CityRange6[] CityRanges6; - - public static void Main() - { - Console.WriteLine("Importing CSV data"); - Csv = CsvData.ImportFromCloud(); - //Csv = CsvData.ImportFromFiles(); - - Console.WriteLine("Creating GeoIP.db"); - ParseCountries(); - Console.WriteLine("Writing GeoIP.db"); - WriteCountries(); - Console.WriteLine("Creating GeoIP.ASN.db"); - ParseAsn(); - Console.WriteLine("Writing GeoIP.ASN.db"); - WriteAsn(); - Console.WriteLine("Creating GeoIP.City.db"); - ParseCities(); - Console.WriteLine("Writing GeoIP.City.db"); - WriteCities(); - - Console.WriteLine("Done."); - } - - private static void ParseCountries() - { - Countries = CsvFile - .EnumerateBinary(Csv.Country, ",", true, false, Encoding.UTF8) - .Where(row => row[5].Value != "") - .Select(row => - { - string isoCode = row[4].Value.ToUpper(); - string continentIsoCode = row[2].Value.ToUpper(); - if (isoCode.Length != 2 || isoCode[0] > byte.MaxValue || isoCode[1] > byte.MaxValue) throw new FormatException("Country ISO code must be composed of two ANSI characters."); - if (continentIsoCode.Length != 2 || continentIsoCode[0] > byte.MaxValue || continentIsoCode[1] > byte.MaxValue) throw new FormatException("Country continent code must be composed of two ANSI characters."); - - return new Country - { - ID = row[0].Int32Value.Value, - Name = row[5].Value, - IsoCode = isoCode, - Continent = row[3].Value, - ContinentIsoCode = continentIsoCode, - EuropeanUnion = row[6].Int32Value.Value == 1 - }; - }) - .OrderBy(country => country.Name, StringComparer.OrdinalIgnoreCase) - .ToArray(); - - if (Countries.Length > 255) throw new OverflowException("The limit of 255 countries has been exceeded."); - - IPRanges = CsvFile - .EnumerateBinary(Csv.Range, ",", true, false, Encoding.UTF8) - .Where(row => row[1].Value != "") - .Select(row => new - { - Range = row[0].Value, - CountryIndex = GetCountryIndex(row[1].Int32Value.Value) - }) - .Where(range => range.CountryIndex != null) - .Select(range => - { - ConvertCidr(range.Range, out uint from, out uint to); - - return new IPRange - { - CountryIndex = range.CountryIndex.Value, - From = from, - To = to - }; - }) - .ToArray(); - - IPRanges6 = CsvFile - .EnumerateBinary(Csv.Range6, ",", true, false, Encoding.UTF8) - .Where(row => row[1].Value != "") - .Select(row => new - { - Range = row[0].Value, - CountryIndex = GetCountryIndex(row[1].Int32Value.Value) - }) - .Where(range => range.CountryIndex != null) - .Select(range => - { - ConvertCidr(range.Range, out byte[] from, out byte[] to); - - return new IPRange6 - { - CountryIndex = range.CountryIndex.Value, - From = from, - To = to - }; - }) - .ToArray(); - - byte? GetCountryIndex(int id) - { - int index = Countries.IndexOf(country => country.ID == id); - return index != -1 ? (byte)index : (byte?)null; - } - } - private static void ParseAsn() - { - Asns = new List(ushort.MaxValue); - List asnNumbers = new List(ushort.MaxValue); - - AsnRanges = CsvFile - .EnumerateBinary(Csv.Asn, ",", true, false, Encoding.UTF8) - .Select(row => - { - int number = row[1].Int32Value.Value; - - AddAsn(number, row[2].Value); - ConvertCidr(row[0].Value, out uint from, out uint to); - - return new AsnRange - { - Asn = number, - From = from, - To = to - }; - }) - .ToArray(); - - AsnRanges6 = CsvFile - .EnumerateBinary(Csv.Asn6, ",", true, false, Encoding.UTF8) - .Select(row => - { - int number = row[1].Int32Value.Value; - - AddAsn(number, row[2].Value); - ConvertCidr(row[0].Value, out byte[] from, out byte[] to); - - return new AsnRange6 - { - Asn = number, - From = from, - To = to - }; - }) - .ToArray(); - - Asns = Asns.OrderBy(asn => asn.Organization, StringComparer.OrdinalIgnoreCase).ToList(); - - void AddAsn(int number, string organization) - { - if (!asnNumbers.Contains(number)) - { - asnNumbers.Add(number); - Asns.Add(new Asn - { - Number = number, - Organization = organization - }); - } - } - } - private static void ParseCities() - { - Cities = CsvFile - .EnumerateBinary(Csv.City, ",", true, false, Encoding.UTF8) - .Select(row => new City - { - ID = row[0].Int32Value.Value, - CountryIndex = GetCountryIndex(row[4].Value), - Name = row[10].Value, - Subdivision1Name = row[7].Value, - Subdivision1IsoCode = row[6].Value, - Subdivision2Name = row[9].Value, - Subdivision2IsoCode = row[8].Value, - TimeZone = row[12].Value - }) - .OrderBy(city => city.Name, StringComparer.OrdinalIgnoreCase) - .ToArray(); - - int[] cityIndices = Create.Array(Cities.Max(city => city.ID) + 1, -1); - for (int i = 0; i < Cities.Length; i++) cityIndices[Cities[i].ID] = i; - - CityRanges = CsvFile - .EnumerateBinary(Csv.CityRange, ",", true, false, Encoding.UTF8) - .Where(row => row[1].Value != "") - .Select(row => - { - ConvertCidr(row[0].Value, out uint from, out uint to); - - return new CityRange - { - CityIndex = GetCityIndex(row[1].Int32Value.Value), - PostalCode = row[6].Value, - Latitude = row[7].Value.ToSingleOrNull().Value, - Longitude = row[8].Value.ToSingleOrNull().Value, - AccuracyRadius = Convert.ToInt16(row[9].Int32Value.Value), - From = from, - To = to - }; - }) - .ToArray(); - - CityRanges6 = CsvFile - .EnumerateBinary(Csv.CityRange6, ",", true, false, Encoding.UTF8) - .Where(row => row[1].Value != "") - .Select(row => - { - ConvertCidr(row[0].Value, out byte[] from, out byte[] to); - - return new CityRange6 - { - CityIndex = GetCityIndex(row[1].Int32Value.Value), - PostalCode = row[6].Value, - Latitude = row[7].Value.ToSingleOrNull().Value, - Longitude = row[8].Value.ToSingleOrNull().Value, - AccuracyRadius = Convert.ToInt16(row[9].Int32Value.Value), - From = from, - To = to - }; - }) - .ToArray(); - - byte GetCountryIndex(string isoCode) - { - int index = Countries.IndexOf(country => country.IsoCode == isoCode); - return index != -1 ? (byte)index : byte.MaxValue; - } - int GetCityIndex(int id) - { - int index = cityIndices[id]; - return index != -1 ? index : throw new FormatException("City ID '" + id + "' not found."); - } - } - private static void WriteCountries() - { - using MemoryStream memoryStream = new MemoryStream(); - - using (BinaryWriter writer = new BinaryWriter(memoryStream, Encoding.UTF8)) - { - writer.Write(DateTime.Now.Ticks); - writer.Write((byte)Countries.Length); - writer.Write(IPRanges.Length); - writer.Write(IPRanges6.Length); - - foreach (Country country in Countries) - { - writer.Write(country.Name); - writer.Write((byte)country.IsoCode[0]); - writer.Write((byte)country.IsoCode[1]); - writer.Write(country.Continent); - writer.Write((byte)country.ContinentIsoCode[0]); - writer.Write((byte)country.ContinentIsoCode[1]); - writer.Write(country.EuropeanUnion); - } - foreach (IPRange range in IPRanges) - { - writer.Write(range.CountryIndex); - writer.Write(range.From); - writer.Write(range.To); - } - foreach (IPRange6 range in IPRanges6) - { - writer.Write(range.CountryIndex); - writer.Write(range.From); - writer.Write(range.To); - } - } - - File.WriteAllBytes(@"..\..\..\BytecodeApi.GeoIP\Resources\GeoIP.db", Compression.Compress(memoryStream.ToArray())); - } - private static void WriteAsn() - { - int[] asnIndices = Create.Array(Asns.Max(asn => asn.Number) + 1, -1); - for (int i = 0; i < Asns.Count; i++) asnIndices[Asns[i].Number] = i; - - using MemoryStream memoryStream = new MemoryStream(); - - using (BinaryWriter writer = new BinaryWriter(memoryStream, Encoding.UTF8)) - { - writer.Write(DateTime.Now.Ticks); - writer.Write(Asns.Count); - writer.Write(AsnRanges.Length); - writer.Write(AsnRanges6.Length); - - foreach (Asn asn in Asns) - { - writer.Write(asn.Number); - writer.Write(asn.Organization); - } - foreach (AsnRange range in AsnRanges) - { - writer.Write(GetAsnIndex(range.Asn)); - writer.Write(range.From); - writer.Write(range.To); - } - foreach (AsnRange6 range in AsnRanges6) - { - writer.Write(GetAsnIndex(range.Asn)); - writer.Write(range.From); - writer.Write(range.To); - } - } - - File.WriteAllBytes(@"..\..\..\BytecodeApi.GeoIP.ASN\Resources\GeoIP.ASN.db", Compression.Compress(memoryStream.ToArray())); - - int GetAsnIndex(int number) - { - int index = asnIndices[number]; - return index != -1 ? index : throw new FormatException("ASN ID '" + number + "' not found."); - } - } - private static void WriteCities() - { - using MemoryStream memoryStream = new MemoryStream(); - - using (BinaryWriter writer = new BinaryWriter(memoryStream, Encoding.UTF8)) - { - writer.Write(DateTime.Now.Ticks); - writer.Write(Cities.Length); - writer.Write(CityRanges.Length); - writer.Write(CityRanges6.Length); - - foreach (City city in Cities) - { - writer.Write(city.CountryIndex); - writer.Write(city.Name); - writer.Write(city.Subdivision1Name); - writer.Write(city.Subdivision1IsoCode); - writer.Write(city.Subdivision2Name); - writer.Write(city.Subdivision2IsoCode); - writer.Write(city.TimeZone); - } - foreach (CityRange range in CityRanges) - { - writer.Write(range.CityIndex); - writer.Write(range.PostalCode); - writer.Write(range.Latitude); - writer.Write(range.Longitude); - writer.Write(range.AccuracyRadius); - writer.Write(range.From); - writer.Write(range.To); - } - foreach (CityRange6 range in CityRanges6) - { - writer.Write(range.CityIndex); - writer.Write(range.PostalCode); - writer.Write(range.Latitude); - writer.Write(range.Longitude); - writer.Write(range.AccuracyRadius); - writer.Write(range.From); - writer.Write(range.To); - } - } - - File.WriteAllBytes(@"..\..\..\BytecodeApi.GeoIP.City\Resources\GeoIP.City.db", Compression.Compress(memoryStream.ToArray())); - } - - private static void ConvertCidr(string cidr, out uint from, out uint to) - { - uint[] parts = cidr.Split('.', '/').Select(part => Convert.ToUInt32(part)).ToArray(); - uint ip = parts[0] << 24 | parts[1] << 16 | parts[2] << 8 | parts[3]; - uint mask = uint.MaxValue << (32 - (int)parts[4]); - - from = ip & mask; - to = ip | ~mask; - } - private static void ConvertCidr(string cidr, out byte[] from, out byte[] to) - { - string[] parts = cidr.Split('/'); - int prefix = Convert.ToInt32(parts[1]); - from = IPAddress.Parse(parts[0]).GetAddressBytes(); - to = from.ToArray(); - - for (int i = 0; i < 16; i++) - { - for (int j = 0; j < 8; j++) - { - if (i * 8 + j >= prefix) - { - byte mask = (byte)(byte.MaxValue << (8 - j)); - from[i] &= mask; - to[i] = (byte)(to[i] | ~mask); - } - } - } - } - } -} \ No newline at end of file diff --git a/BytecodeApi.CommandLineParser/.nuget/README.md b/BytecodeApi.CommandLineParser/.nuget/README.md new file mode 100644 index 0000000..6df3688 --- /dev/null +++ b/BytecodeApi.CommandLineParser/.nuget/README.md @@ -0,0 +1,21 @@ +# BytecodeApi.CommandLineParser + +Library for commandline parsing and handling. + +## Examples + +See: [Examples](https://github.com/bytecode77/bytecode-api/blob/master/BytecodeApi.CommandLineParser/README.md) + +## Changelog + +### 5.0.0 (15.02.2026) + +* **change:** Targeting .NET 10.0 + +### 4.0.0 (15.09.2025) + +* **change:** Targeting .NET 9.0 + +### 3.0.0 (08.09.2023) + +* Initial release \ No newline at end of file diff --git a/BytecodeApi.CommandLineParser/BytecodeApi.CommandLineParser.csproj b/BytecodeApi.CommandLineParser/BytecodeApi.CommandLineParser.csproj new file mode 100644 index 0000000..039c7ef --- /dev/null +++ b/BytecodeApi.CommandLineParser/BytecodeApi.CommandLineParser.csproj @@ -0,0 +1,40 @@ + + + net10.0 + enable + enable + True + True + + + 5.0.0 + 5.0.0 + 5.0.0 + + + BytecodeApi.CommandLineParser + BytecodeApi.CommandLineParser + Library for commandline parsing and handling. + bytecode77 + Martin Fischer + © bytecode77, 2026. + + + BytecodeApi.CommandLineParser + commandline cli parsing cmd + https://bytecode77.com/bytecode-api + git + https://github.com/bytecode77/bytecode-api + MIT + .nuget\README.md + .nuget\PackageIcon.png + ../$Build + + + + + + + + + \ No newline at end of file diff --git a/BytecodeApi.CommandLineParser/CommandLineParserError.cs b/BytecodeApi.CommandLineParser/CommandLineParserError.cs new file mode 100644 index 0000000..7a27a7e --- /dev/null +++ b/BytecodeApi.CommandLineParser/CommandLineParserError.cs @@ -0,0 +1,52 @@ +namespace BytecodeApi.CommandLineParser; + +/// +/// Specifies a validation source for a , if validated using the object. +/// +public enum CommandLineParserError +{ + /// + /// The exception is a general error that did not occur during validation using the object. + /// + None, + /// + /// The exception occurred in the method. + /// + OptionRequired, + /// + /// The exception occurred in the method. + /// + OptionNotDuplicate, + /// + /// The exception occurred in the method. + /// + ValueCount, + /// + /// The exception occurred in the method. + /// + MinimumValueCount, + /// + /// The exception occurred in the method. + /// + MaximumValueCount, + /// + /// The exception occurred in the method. + /// + Custom, + /// + /// The exception occurred in the method. + /// + Int32, + /// + /// The exception occurred in the method. + /// + FileExists, + /// + /// The exception occurred in the method. + /// + DirectoryExists, + /// + /// The exception occurred in the method. + /// + FileExtension +} \ No newline at end of file diff --git a/BytecodeApi.CommandLineParser/CommandLineParserException.cs b/BytecodeApi.CommandLineParser/CommandLineParserException.cs new file mode 100644 index 0000000..dfab8f8 --- /dev/null +++ b/BytecodeApi.CommandLineParser/CommandLineParserException.cs @@ -0,0 +1,29 @@ +namespace BytecodeApi.CommandLineParser; + +/// +/// The exception that is thrown when commandline parsing failed or was asserted using the object. +/// +public sealed class CommandLineParserException : Exception +{ + /// + /// Gets a value that indicates what validation took place using the object. For general exceptions, is returned. + /// + public CommandLineParserError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public CommandLineParserException(string? message) : this(CommandLineParserError.None, message) + { + } + /// + /// Initializes a new instance of the class. + /// + /// If validated using the object, indicates what validation took place. + /// The message that describes the error. + public CommandLineParserException(CommandLineParserError error, string? message) : base(message) + { + Error = error; + } +} \ No newline at end of file diff --git a/BytecodeApi.CommandLineParser/Option.cs b/BytecodeApi.CommandLineParser/Option.cs new file mode 100644 index 0000000..172dd6f --- /dev/null +++ b/BytecodeApi.CommandLineParser/Option.cs @@ -0,0 +1,120 @@ +using BytecodeApi.Extensions; +using System.Collections.ObjectModel; +using System.Diagnostics; + +namespace BytecodeApi.CommandLineParser; + +/// +/// Represents a commandline option, specified by possible arguments and alternatives. +/// Example: "-p 12345" and "--password 12345" +/// +[DebuggerDisplay($"{nameof(Option)}: Arguments = {{string.Join(\"|\", Arguments)}}, Alternatives = {{string.Join(\"|\", Alternatives)}}")] +public sealed class Option : IEquatable