diff --git a/FCS.Lib.Utility.csproj b/FCS.Lib.Utility.csproj index 21c150d..960a025 100644 --- a/FCS.Lib.Utility.csproj +++ b/FCS.Lib.Utility.csproj @@ -24,6 +24,7 @@ DEBUG;TRACE prompt 4 + bin\Debug\FCS.Lib.Utility.xml pdbonly diff --git a/Generators.cs b/Generators.cs index f103b2f..23b986f 100644 --- a/Generators.cs +++ b/Generators.cs @@ -31,18 +31,25 @@ using System.Security.Cryptography; namespace FCS.Lib.Utility { + /// + /// Generators + /// public static class Generators { + /// + /// Generate 6 character shortUrl + /// + /// of 6 characters public static string ShortUrlGenerator() { return ShortUrlGenerator(6); } /// - /// Randoms the string. + /// Generate shortUrl with length /// - /// The lengt h. - /// System.String. + /// The length. + /// /// derived from https://sourceforge.net/projects/shorturl-dotnet/ public static string ShortUrlGenerator(int length) { @@ -160,10 +167,11 @@ namespace FCS.Lib.Utility } /// - /// Generates the username. + /// Username generator /// /// The options. - /// System.String. + /// + /// public static string GenerateUsername(StringOptions options = null) { options ??= new StringOptions @@ -180,10 +188,11 @@ namespace FCS.Lib.Utility } /// - /// Generates the password. + /// Password generator /// /// The options. - /// System.String. + /// + /// public static string GeneratePassword(StringOptions options = null) { options ??= new StringOptions @@ -200,10 +209,10 @@ namespace FCS.Lib.Utility } /// - /// Generates the random text. + /// Random string generator with length /// /// The length. - /// System.String. + /// public static string GenerateRandomText(int length) { const string consonants = "bcdfghjklmnprstvxzBDFGHJKLMNPRSTVXZ"; @@ -223,10 +232,10 @@ namespace FCS.Lib.Utility } /// - /// Generates the random password. + /// Random string generator - string options /// /// The options. - /// System.String. + /// public static string GenerateRandomString(StringOptions options = null) { options ??= new StringOptions @@ -281,15 +290,16 @@ namespace FCS.Lib.Utility } /// - /// Randoms the seed. + /// Randomize random using RNGCrypto /// - /// Random. + /// /// derived from https://sourceforge.net/projects/shorturl-dotnet/ + /// public static Random RandomSeed() { - // As the default randomizer is based on the current time + // As the default Random is based on the current time // so it produces the same "random" number within a second - // Use a crypto randomizer to create the seed value + // Use a crypto service to create the seed value // 4-byte array to fill with random bytes var randomBytes = new byte[4]; diff --git a/GuidGenerator.cs b/GuidGenerator.cs index 28e16f6..85a7bbf 100644 --- a/GuidGenerator.cs +++ b/GuidGenerator.cs @@ -9,17 +9,40 @@ namespace FCS.Lib.Utility /// RFC 4122 - A Universally Unique IDentifier (UUID) URN Namespace public static class GuidGenerator { - // number of bytes in guid + + /// + /// number of bytes in guid + /// public const int ByteArraySize = 16; - // multiplex variant info + /// + /// multiplex variant info - variant byte + /// public const int VariantByte = 8; + + /// + /// multiplex variant info - variant byte mask + /// public const int VariantByteMask = 0x3f; + + /// + /// multiplex variant info - variant byte shift + /// public const int VariantByteShift = 0x80; - // multiplex version info + /// + /// multiplex version info - version byte + /// public const int VersionByte = 7; + + /// + /// multiplex version info - version byte mask + /// public const int VersionByteMask = 0x0f; + + /// + /// multiplex version info version byte shift + /// public const int VersionByteShift = 4; // indexes within the uuid array for certain boundaries @@ -30,8 +53,14 @@ namespace FCS.Lib.Utility // offset to move from 1/1/0001, which is 0-time for .NET, to gregorian 0-time of 10/15/1582 private static readonly DateTimeOffset GregorianCalendarStart = new(1582, 10, 15, 0, 0, 0, TimeSpan.Zero); - // random clock sequence and node + + /// + /// Default clock sequence + /// public static byte[] DefaultClockSequence { get; set; } + /// + /// Default node + /// public static byte[] DefaultNode { get; set; } static GuidGenerator() @@ -44,18 +73,33 @@ namespace FCS.Lib.Utility random.NextBytes(DefaultNode); } + /// + /// Set default node + /// + /// public static void SetDefaultNode(string nodeName) { var x = nodeName.GetHashCode(); var node = $"{x:X}"; DefaultNode = Encoding.UTF8.GetBytes(node.ToCharArray(), 0, 6); } + + /// + /// Get version + /// + /// + /// public static GuidVersion GetVersion(this Guid guid) { var bytes = guid.ToByteArray(); return (GuidVersion)((bytes[VersionByte] & 0xFF) >> VersionByteShift); } + /// + /// Get date time offset from guid + /// + /// + /// public static DateTimeOffset GetDateTimeOffset(Guid guid) { var bytes = guid.ToByteArray(); @@ -73,26 +117,50 @@ namespace FCS.Lib.Utility return new DateTimeOffset(ticks, TimeSpan.Zero); } + /// + /// get date time from guid + /// + /// + /// public static DateTime GetDateTime(Guid guid) { return GetDateTimeOffset(guid).DateTime; } + /// + /// get local date time from guid + /// + /// + /// public static DateTime GetLocalDateTime(Guid guid) { return GetDateTimeOffset(guid).LocalDateTime; } + /// + /// get utc date time from guid + /// + /// + /// public static DateTime GetUtcDateTime(Guid guid) { return GetDateTimeOffset(guid).UtcDateTime; } + /// + /// Generate time based guid + /// + /// public static Guid GenerateTimeBasedGuid() { return GenerateTimeBasedGuid(DateTimeOffset.UtcNow, DefaultClockSequence, DefaultNode); } + /// + /// Generate time based guid providing a NodeName string + /// + /// + /// public static Guid GenerateTimeBasedGuid(string nodeName) { var x = nodeName.GetHashCode(); @@ -101,21 +169,47 @@ namespace FCS.Lib.Utility return GenerateTimeBasedGuid(DateTimeOffset.UtcNow, DefaultClockSequence, defaultNode); } + /// + /// Generate time based guid providing a valid DateTime object + /// + /// + /// public static Guid GenerateTimeBasedGuid(DateTime dateTime) { return GenerateTimeBasedGuid(dateTime, DefaultClockSequence, DefaultNode); } + /// + /// Generate time base guid providing a valid DateTimeOffset object + /// + /// + /// public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime) { return GenerateTimeBasedGuid(dateTime, DefaultClockSequence, DefaultNode); } + /// + /// Generate time based guid providing a date time, byte array for clock sequence and node + /// + /// + /// + /// + /// public static Guid GenerateTimeBasedGuid(DateTime dateTime, byte[] clockSequence, byte[] node) { return GenerateTimeBasedGuid(new DateTimeOffset(dateTime), clockSequence, node); } + /// + /// Generate time based guid providing a valid DateTimeOffset Object and byte arrays for clock sequence and node + /// + /// + /// + /// + /// + /// + /// public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime, byte[] clockSequence, byte[] node) { if (clockSequence == null) diff --git a/GuidVersion.cs b/GuidVersion.cs index d3f058d..b08869e 100644 --- a/GuidVersion.cs +++ b/GuidVersion.cs @@ -1,11 +1,25 @@ namespace FCS.Lib.Utility { - // guid version types + /// + /// Guid Version Enum + /// public enum GuidVersion { + /// + /// Time + /// TimeBased = 0x01, + /// + /// Reserved + /// Reserved = 0x02, + /// + /// Name + /// NameBased = 0x03, + /// + /// Random + /// Random = 0x04 } } \ No newline at end of file diff --git a/Mogrify.cs b/Mogrify.cs index a888490..e5bbec2 100644 --- a/Mogrify.cs +++ b/Mogrify.cs @@ -35,18 +35,37 @@ using System.Text.RegularExpressions; namespace FCS.Lib.Utility { + /// + /// Mogrify between units + /// public static class Mogrify { + /// + /// Get month from timestamp + /// + /// + /// integer public static int MonthFromTimestamp(long timeStamp) { return TimeStampToDateTime(timeStamp).Month; } + /// + /// validate if timestamp occurs in month + /// + /// + /// + /// boolean public static bool TimestampInMonth(long timestamp, int month) { return TimeStampToDateTime(timestamp).Month == month; } + /// + /// Get timestamp range for given datetime + /// + /// + /// dictionary public static Dictionary DateToTimestampRange(DateTime dateTime) { var dt1 = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day,0,0,0); @@ -57,6 +76,11 @@ namespace FCS.Lib.Utility }; } + /// + /// ISO date to timestamp + /// + /// + /// long public static long IsoDateToTimestamp(string isoDateString) { var result = DateTime.TryParse(isoDateString, out var test); @@ -65,78 +89,116 @@ namespace FCS.Lib.Utility return $"{test:yyyy-MM-dd}" == isoDateString ? DateTimeToTimeStamp(test) : 0; } + /// + /// ISO date from timestamp + /// + /// + /// string yyyy-MM-dd public static string TimestampToIsoDate(long timestamp) { return $"{TimeStampToDateTime(timestamp):yyyy-MM-dd}"; } + /// + /// reverse boolean + /// + /// + /// bool public static bool BoolReverse(bool value) { return !value; } + /// + /// number from bool + /// + /// + /// integer public static int BoolToInt(bool value) { return value ? 1 : 0; } + /// + /// string from bool + /// + /// + /// string true/false public static string BoolToString(bool value) { return value ? "true" : "false"; } + /// + /// get bool from integer + /// + /// + /// + public static bool IntToBool(int value) + { + return value is > 0 or < 0; + } + + /// + /// get the number value from enum + /// + /// + /// int public static int EnumToInt(object enumeration) { return Convert.ToInt32(enumeration, CultureInfo.InvariantCulture); } + /// + /// get string from enum + /// + /// + /// string - name of the enum public static string EnumToString(Enum value) { return value == null ? string.Empty : value.ToString(); } + /// + /// get list of enum of type T + /// + /// + /// list of enum public static IEnumerable GetEnumList() { return (T[])Enum.GetValues(typeof(T)); } - public static bool IntToBool(int value) - { - return value > 0 || value < 0; - } + /// + /// get enum from integer of type T + /// + /// + /// + /// public static T IntToEnum(int value) { return (T) Enum.ToObject(typeof(T), value); } - public static string IntToLetter(int value) - { - var empty = string.Empty; - var num = 97; - var str = ""; - var num1 = 0; - var num2 = 97; - for (var i = 0; i <= value; i++) - { - num1++; - empty = string.Concat(str, Convert.ToString(Convert.ToChar(num), CultureInfo.InvariantCulture)); - num++; - if (num1 != 26) continue; - num1 = 0; - str = Convert.ToChar(num2).ToString(CultureInfo.InvariantCulture); - num2++; - num = 97; - } - - return empty; - } - + /// + /// get string from list using semicolon separator + /// + /// + /// + /// public static string ListToString(List list) { return ListToString(list, ";"); } + /// + /// get string from list using delimiter + /// + /// + /// + /// + /// public static string ListToString(List list, string delimiter) { var empty = string.Empty; @@ -149,12 +211,22 @@ namespace FCS.Lib.Utility return empty; } + /// + /// get lowercase dash separated string from Pascal case + /// + /// + /// public static string PascalToLower(string value) { var result = string.Join("-", Regex.Split(value, @"(? + /// get bool from string + /// + /// + /// public static bool StringToBool(string value) { if (string.IsNullOrEmpty(value)) @@ -176,6 +248,11 @@ namespace FCS.Lib.Utility return flag; } + /// + /// get decimal from string + /// + /// + /// public static decimal? StringToDecimal(string inString) { if (string.IsNullOrEmpty(inString)) return 0; @@ -186,16 +263,36 @@ namespace FCS.Lib.Utility : decimal.Divide(num, new decimal((long) 100)); } + /// + /// get enum of type T from string + /// + /// + /// + /// public static T StringToEnum(string value) { return (T)Enum.Parse(typeof(T), value, true); } + /// + /// get list from string using semicolon + /// + /// + /// + /// public static List StringToList(string value) { return StringToList(value, ";"); } + /// + /// get list from string using delimiter + /// + /// + /// + /// + /// + /// public static List StringToList(string value, string delimiter) { if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value)); @@ -225,32 +322,42 @@ namespace FCS.Lib.Utility return ts; } + + /// + /// get string from stream (default encoding) + /// + /// + /// public static Stream StringToStream(string value) { return StringToStream(value, Encoding.Default); } + + /// + /// get stream from string (using encoding) + /// + /// + /// + /// public static Stream StringToStream(string value, Encoding encoding) { return encoding == null ? null : new MemoryStream(encoding.GetBytes(value ?? "")); } + + /// + /// get timestamp from current date time + /// + /// public static long CurrentDateTimeToTimeStamp() { return Convert.ToUInt32(DateTimeToTimeStamp(DateTime.Now)); } - public static string CurrentDateTimeToAlpha() - { - var dt = DateTime.UtcNow.ToString("yy MM dd HH MM ss"); - var sb = new StringBuilder(); - var dts = dt.Split(' '); - sb.Append((char) int.Parse(dts[0]) + 65); - sb.Append((char) int.Parse(dts[1]) + 65); - sb.Append((char) int.Parse(dts[2]) + 97); - sb.Append((char) int.Parse(dts[3]) + 65); - sb.Append((char) int.Parse(dts[4]) + 97); - sb.Append((char) int.Parse(dts[5]) + 97); - return sb.ToString(); - } - + + /// + /// get timestamp from date time + /// + /// + /// public static long DateTimeToTimeStamp(DateTime dateTime) { var bigDate = new DateTime(2038, 1, 19, 0, 0, 0, 0); @@ -263,25 +370,89 @@ namespace FCS.Lib.Utility return Convert.ToInt64((dateTime - nixDate).TotalSeconds); } + /// + /// get date time from timestamp + /// + /// + /// public static DateTime TimeStampToDateTime(long timeStamp) { var nixDate = new DateTime(1970, 1, 1, 0, 0, 0, 0); return nixDate.AddSeconds(timeStamp); } + /// + /// get seconds from timespan + /// + /// + /// public static long TimeSpanToSeconds(TimeSpan timespan) { return Convert.ToUInt32(timespan.Ticks / 10000000L); } + /// + /// get timespan from seconds + /// + /// + /// public static TimeSpan SecondsToTimeSpan(long seconds) { return TimeSpan.FromTicks(10000000L * seconds); } + /// + /// get minutes from timespan + /// + /// + /// public static long TimespanToMinutes(TimeSpan timespan) { return Convert.ToUInt32(timespan.Ticks / 10000000L) / 60; } + + ///// + ///// get string from date time + ///// + ///// + //public static string CurrentDateTimeToAlpha() + //{ + // var dt = DateTime.UtcNow.ToString("yy MM dd HH MM ss"); + // var sb = new StringBuilder(); + // var dts = dt.Split(' '); + // sb.Append((char) int.Parse(dts[0]) + 65); + // sb.Append((char) int.Parse(dts[1]) + 65); + // sb.Append((char) int.Parse(dts[2]) + 97); + // sb.Append((char) int.Parse(dts[3]) + 65); + // sb.Append((char) int.Parse(dts[4]) + 97); + // sb.Append((char) int.Parse(dts[5]) + 97); + // return sb.ToString(); + //} + + ///// + ///// integer to letter + ///// + ///// + ///// string + //public static string IntToLetter(int value) + //{ + // var empty = string.Empty; + // var num = 97; + // var str = ""; + // var num1 = 0; + // var num2 = 97; + // for (var i = 0; i <= value; i++) + // { + // num1++; + // empty = string.Concat(str, Convert.ToString(Convert.ToChar(num), CultureInfo.InvariantCulture)); + // num++; + // if (num1 != 26) continue; + // num1 = 0; + // str = Convert.ToChar(num2).ToString(CultureInfo.InvariantCulture); + // num2++; + // num = 97; + // } + // return empty; + //} } } \ No newline at end of file diff --git a/QueryHelper.cs b/QueryHelper.cs index f1e317d..d47362a 100644 --- a/QueryHelper.cs +++ b/QueryHelper.cs @@ -38,37 +38,60 @@ namespace FCS.Lib.Utility { // https://stackoverflow.com/a/45761590 - public static IQueryable OrderBy - (this IQueryable q, string name, bool desc) + /// + /// OrderBy + /// + /// + /// + /// + /// + /// + public static IQueryable OrderBy (this IQueryable q, string name, bool desc) { var entityType = typeof(TModel); var p = entityType.GetProperty(name); var m = typeof(QueryHelper) .GetMethod("OrderByProperty") ?.MakeGenericMethod(entityType, p.PropertyType); - return(IQueryable) m.Invoke(null, new object[] { - q, p , desc }); + + return(IQueryable) m.Invoke(null, new object[] { q, p , desc }); } - public static IQueryable ThenBy - (this IQueryable q, string name, bool desc) + /// + /// ThenBy + /// + /// + /// + /// + /// + /// + public static IQueryable ThenBy (this IQueryable q, string name, bool desc) { var entityType = typeof(TModel); var p = entityType.GetProperty(name); var m = typeof(QueryHelper) .GetMethod("OrderByProperty") ?.MakeGenericMethod(entityType, p.PropertyType); - return(IQueryable) m.Invoke(null, new object[] { - q, p , desc }); + + return(IQueryable) m.Invoke(null, new object[] { q, p , desc }); } - public static IQueryable OrderByProperty - (IQueryable q, PropertyInfo p, bool desc) + /// + /// OrderByProperty + /// + /// + /// + /// + /// + /// + /// + public static IQueryable OrderByProperty(IQueryable q, PropertyInfo p, bool desc) { var pe = Expression.Parameter(typeof(TModel)); Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object)); var exp = Expression.Lambda>(se, pe); + return desc ? q.OrderByDescending(exp) : q.OrderBy(exp); } diff --git a/StringOptions.cs b/StringOptions.cs index eb0be0e..15fb09f 100644 --- a/StringOptions.cs +++ b/StringOptions.cs @@ -32,43 +32,43 @@ namespace FCS.Lib.Utility public class StringOptions { /// - /// Gets or sets the length of the required. + /// Gets or sets the required length of a string /// /// The length of the required. public int RequiredLength { get; set; } /// - /// Gets or sets a value indicating whether [require non letter or digit]. + /// Gets or sets a value indicating whether to [require non letter or digit]. /// /// true if [require non letter or digit]; otherwise, false. public bool RequireNonLetterOrDigit { get; set; } /// - /// Gets or sets a value indicating whether [require digit]. + /// Gets or sets a value indicating whether to [require digit]. /// /// true if [require digit]; otherwise, false. public bool RequireDigit { get; set; } /// - /// Gets or sets a value indicating whether [require lowercase]. + /// Gets or sets a value indicating whether to [require lowercase]. /// /// true if [require lowercase]; otherwise, false. public bool RequireLowercase { get; set; } /// - /// Gets or sets a value indicating whether [require uppercase]. + /// Gets or sets a value indicating whether to [require uppercase]. /// /// true if [require uppercase]; otherwise, false. public bool RequireUppercase { get; set; } /// - /// Gets or sets the required unique chars. + /// Gets or sets the required unique chars. /// /// The required unique chars. public int RequiredUniqueChars { get; set; } /// - /// Gets or sets a value indicating whether [require non alphanumeric]. + /// Gets or sets a value indicating whether to [require non alphanumeric]. /// /// true if [require non alphanumeric]; otherwise, false. public bool RequireNonAlphanumeric { get; set; } diff --git a/VatFormatValidator.cs b/VatFormatValidator.cs index 1e6fb96..7222edf 100644 --- a/VatFormatValidator.cs +++ b/VatFormatValidator.cs @@ -27,11 +27,20 @@ using System.Linq; namespace FCS.Lib.Utility { + /// + /// Vat format validator + /// public static class VatFormatValidator { // https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11 // https://ec.europa.eu/taxation_customs/vies/ + /// + /// Check vat number format + /// + /// + /// + /// bool indicating if the vat number conform to country specification public static bool CheckVat(string countryCode, string vatNumber) { return countryCode.ToUpperInvariant() switch @@ -43,6 +52,24 @@ namespace FCS.Lib.Utility }; } + /// + /// sanitize vat number + /// + /// + /// sanitized string + public static string SanitizeVatNumber(string vatNumber) + { + vatNumber = vatNumber.ToUpperInvariant(); + return vatNumber + .Replace(" ", "") + .Replace("-", "") + .Replace("_", "") + .Replace("DK", "") + .Replace("NO", "") + .Replace("SE","") + .Replace("MVA", ""); + } + private static bool ValidateFormatDk(string vatNumber) { // https://wiki.scn.sap.com/wiki/display/CRM/Denmark @@ -119,18 +146,6 @@ namespace FCS.Lib.Utility } - public static string SanitizeVatNumber(string vatNumber) - { - vatNumber = vatNumber.ToUpperInvariant(); - return vatNumber - .Replace(" ", "") - .Replace("-", "") - .Replace("DK", "") - .Replace("NO", "") - .Replace("SE","") - .Replace("MVA", ""); - } - //private static bool ValidateMod10(string number) //{ // if (long.Parse(number) == 0)