From 5fa4c85f2ec58a8c8cc047edc4c248e639085293 Mon Sep 17 00:00:00 2001 From: sheychen Date: Sun, 11 Dec 2016 10:41:40 +0100 Subject: [PATCH] Add Binary, ConsoleIO, Logger and Strings --- MyCommon/Binary.cs | 175 +++++++++++++++++++++++++++ MyCommon/ConsoleIO.cs | 139 ++++++++++++++++++++++ MyCommon/Logger.cs | 176 ++++++++++++++++++++++++++++ MyCommon/MultiLang.cs | 7 +- MyCommon/MyCommon.csproj | 4 + MyCommon/Properties/AssemblyInfo.cs | 14 +-- MyCommon/Strings.cs | 48 ++++++++ Readme.md | 4 + 8 files changed, 556 insertions(+), 11 deletions(-) create mode 100644 MyCommon/Binary.cs create mode 100644 MyCommon/ConsoleIO.cs create mode 100644 MyCommon/Logger.cs create mode 100644 MyCommon/Strings.cs diff --git a/MyCommon/Binary.cs b/MyCommon/Binary.cs new file mode 100644 index 0000000..5c007bd --- /dev/null +++ b/MyCommon/Binary.cs @@ -0,0 +1,175 @@ +using System; +using System.Linq; +using System.Text; + +namespace MyCommon +{ + public static class Binary + { + public static bool TryToBool(ref byte[] bytes, out bool res) + { + if (bytes.Length < 1) + { + res = false; + return false; + } + + byte[] data = new byte[1]; + data = bytes.Take(1).ToArray(); + RemoveFirst(ref bytes, 1); + if (data[1] == 1) + { + res = true; + } + else + { + if (data[1] == 0) + { + res = false; + } + else + { + res = false; + return false; + } + } + return true; + } + + ///1 byte + public static byte[] FromBool(bool x) + { + return x ? new byte[1] { 1 } : new byte[1] { 0 }; + } + + public static bool TryToString(ref byte[] bytes, out string res) + { + res = null; + int len; + if (!TryToInt(ref bytes, out len)) + return false; + + if (bytes.Length < len) + return false; + + res = Encoding.ASCII.GetString(bytes.Take(len).ToArray()); + RemoveFirst(ref bytes, len); + return res != null; + } + + ///len(in bytes) + string + public static byte[] FromString(string text) + { + byte[] data = Encoding.ASCII.GetBytes(text); + return AddBytes(FromInt(data.Length), data); + } + + public static bool TryToInt(ref byte[] bytes, out int res) + { + res = int.MinValue; + + if (bytes.Length < 4) + return false; + + byte[] data = new byte[4]; + data = bytes.Take(4).ToArray(); + data.Reverse(); + res = BitConverter.ToInt32(data, 0); + RemoveFirst(ref bytes, 4); + return res != int.MinValue; + } + + ///4 bytes + public static byte[] FromInt(int x) + { + byte[] data = new byte[4]; + data = BitConverter.GetBytes(x); + return data; + } + + public static bool TryToStringArray(ref byte[] bytes, out string[] data) + { + data = null; + + int len; + if (!TryToInt(ref bytes, out len)) + return false; + + if (len < 1 || len > 10000) + return false; + + data = new string[len]; + for (int i = 0; i < len; i++) + { + if (!TryToString(ref bytes, out data[i])) + return false; + } + return data != null; + } + + public static byte[] FromStringArray(string[] array) + { + if (array == null) + return new byte[0]; + + byte[] data = FromInt(array.Length); + for (int i = 0; i < array.Length; i++) + { + data = AddBytes(data, FromString(array[i])); + } + return data; + } + + public static bool TryToIntArray(ref byte[] bytes, out int[] res) + { + res = null; + int len; + if (!TryToInt(ref bytes, out len)) + return false; + + res = new int[len]; + for (int i = 0; i < len; i++) + { + if (!TryToInt(ref bytes, out res[i])) + return false; + } + return res != null; + } + + public static byte[] FromIntArray(int[] array) + { + byte[] data = FromInt(array.Length); + for (int i = 0; i < array.Length; i++) + { + data = AddBytes(data, FromInt(array[i])); + } + return data; + } + + public static byte[] AddBytes(params byte[][] arguments) + { + byte[] res = new byte[arguments.Sum(a => a.Length)]; + int offset = 0; + for (int i = 0; i < arguments.Length; i++) + { + Buffer.BlockCopy(arguments[i], 0, res, offset, arguments[i].Length); + offset += arguments[i].Length; + } + return res; + } + + public static void RemoveFirst(ref byte[] bytes, int count) + { + if (bytes.Length - count < 0) + { + bytes = new byte[0] { }; + } + else + { + byte[] newbytes = new byte[bytes.Length - count]; + newbytes = bytes.Skip(count).ToArray(); + bytes = newbytes; + } + } + } +} \ No newline at end of file diff --git a/MyCommon/ConsoleIO.cs b/MyCommon/ConsoleIO.cs new file mode 100644 index 0000000..4f41e1a --- /dev/null +++ b/MyCommon/ConsoleIO.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; + +namespace MyCommon +{ + /// + /// Manager Console with Async I/O + /// + public class ConsoleIO + { + private static string inputBuffer = ""; + private static List outputBuffer = new List(); + public static string Title { get { return Console.Title; } set { Console.Title = value; } } + private static object locker = new object(); + + /// + /// Write a Colored text + /// + /// as System.Console.WriteLine() + public static void Write(ColorStrings Text) + { + outputBuffer.Add(Text); + while (outputBuffer.Count > Console.WindowHeight - 2) { outputBuffer.RemoveAt(0); } + Update(); + } + + /// + /// Read the next characters line + /// + /// as System.Console.ReadLine() + public static string Read() + { + ConsoleKeyInfo key = Console.ReadKey(); + while (key.Key != ConsoleKey.Enter) + { + switch (key.Key) + { + case ConsoleKey.Backspace: + if (inputBuffer.Length == 0) { SetInputPos(); } + if (inputBuffer.Length == 1) { inputBuffer = ""; } + if (inputBuffer.Length > 1) { inputBuffer = inputBuffer.Substring(0, inputBuffer.Length - 1); } + break; + + default: + inputBuffer += key.KeyChar; + break; + } + Update(); + key = Console.ReadKey(); + } + Console.WriteLine(); + string res = inputBuffer; + inputBuffer = ""; + return res; + } + + private static void Update() + { + lock (locker) + { + Console.Clear(); + Console.SetCursorPosition(0, 0); + foreach (ColorStrings output in outputBuffer) { output.Write(); } + SetInputPos(); + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Black; + Console.Write("> " + inputBuffer); + } + } + + private static void SetInputPos() + { + Console.SetCursorPosition(0, Math.Max(Console.WindowHeight - 1, Console.CursorTop + 1)); + } + + /// + /// Clear buffer during ConsoleIO.Read() + /// + public static void ClearInput() + { + inputBuffer = ""; Update(); + } + + /// + /// Clear Console lines + /// + /// as System.Console.Clear() + public static void ClearOutput() + { + outputBuffer.Clear(); Update(); + } + } + + /// + /// Multiple Colors Text + /// + public class ColorStrings + { + public ColorString[] Text; + + public ColorStrings(params ColorString[] strings) + { + Text = strings; + } + + public ColorStrings(string text) + { + Text = new ColorString[1] { new ColorString(text) }; + } + + public void Write() + { + foreach (ColorString cstring in Text) + { + Console.BackgroundColor = cstring.Back; + Console.ForegroundColor = cstring.Fore; + Console.Write(cstring.Text); + } + Console.WriteLine(); + } + } + + /// + /// Single Color Text + /// + public class ColorString + { + public string Text; + public ConsoleColor Fore; + public ConsoleColor Back; + + public ColorString(string text, ConsoleColor fore = ConsoleColor.White, ConsoleColor back = ConsoleColor.Black) + { + Text = text; + Fore = fore; + Back = back; + } + } +} \ No newline at end of file diff --git a/MyCommon/Logger.cs b/MyCommon/Logger.cs new file mode 100644 index 0000000..54428fb --- /dev/null +++ b/MyCommon/Logger.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading; + +namespace MyCommon +{ + public class Logger + { + public enum logType { dev, debug, info, warm, error, fatal } + + public enum logConsole { normal, show, hide } + + public struct Log + { + public string text; + public logType type; + public logConsole console; + + public Log(string p1, logType p2, logConsole p3 = logConsole.normal) + { + text = p1; + type = p2; + console = p3; + } + } + + private List toWriteLogs = new List(); + private string logPath; + private ConsoleColor[] logBackColor; + private ConsoleColor[] logForeColor; + private Thread Updater; + private logType logLevel = logType.info; + private bool _run = true; + public bool run { get { return _run; } } + private static bool _debug = false; + private static bool _dev = false; + private bool haveConsole = false; + + /// + /// Create log file and start logger thread + /// + /// Absolute path to logs directory + public void Initialise(string LogPath, ConsoleColor[] backColor, ConsoleColor[] foreColor, logType LogLevel, bool debug, bool dev, bool haveconsole = true) + { + haveConsole = haveconsole; + logPath = LogPath; + logBackColor = backColor; + logForeColor = foreColor; + logLevel = LogLevel; + _debug = debug; + _dev = dev; + if (!Directory.Exists(logPath)) + { + Directory.CreateDirectory(logPath); + Write("Log Directory Created", logType.info); + } + else + { + //Sort old logs + string[] files = Directory.GetFiles(logPath); + + foreach (string file in files) + { + if (Path.GetExtension(file) == ".log") + { + string name = Path.GetFileName(file); + name = name.Substring(0, Math.Min(name.Length, 10)); + if (name.Length == 10) + { + if (name != DateTime.UtcNow.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)) + { + int y; + int m; + int d; + + if (int.TryParse(new string(name.Take(4).ToArray()), out y) && int.TryParse(new string(name.Skip(5).Take(2).ToArray()), out m) && int.TryParse(new string(name.Skip(8).Take(2).ToArray()), out d)) + { + if (!Directory.Exists(logPath + "/" + y + "/" + m + "/" + d)) + { + Directory.CreateDirectory(logPath + "/" + y + "/" + m + "/" + d); + } + File.Move(file, logPath + "/" + y + "/" + m + "/" + d + "/" + Path.GetFileName(file)); + } + } + } + } + } + } + + int i = 0; + while (File.Exists(logPath + "/" + DateTime.UtcNow.ToString("yyyy-MM-dd-", CultureInfo.InvariantCulture) + i + ".log")) { i++; } + logPath = logPath + "/" + DateTime.UtcNow.ToString("yyyy-MM-dd-", CultureInfo.InvariantCulture) + i + ".log"; + Write("Log path:" + logPath, logType.debug); + Updater = new Thread(new ThreadStart(UpdaterLoop)); + Updater.Start(); + } + + public void Join() + { + _run = false; + Updater.Join(); + } + + public void ChangeLevel(logType level) + { + logLevel = level; + Write("Change to " + logLevel.ToString(), logType.info, logConsole.show); + } + + /// + /// Add log to log pile + /// + /// Log text + /// Log status + /// Server display modifier + public void Write(string text, logType type, logConsole console = logConsole.normal) + { + Write(new Log(text, type, console)); + } + + /// + /// Add log to log pile + /// + /// Log struct + private void Write(Log log) + { + if (_debug || _dev) + { + //Add Source Method + log.text = "[" + new StackTrace().GetFrame(2).GetMethod().Name + "]: " + log.text; + } + toWriteLogs.Add(log); + } + + /// + /// Write log pile to logfile and console + /// + public void UpdaterLoop() + { + while (_run || toWriteLogs.Count > 0) + { + while (toWriteLogs.Count > 0) + { + Log log = toWriteLogs[0]; //Saved log -> any lock need + + if (log.type >= logLevel) + { + File.AppendAllText(logPath, DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + " [" + log.type.ToString().ToUpper() + "]: " + log.text + Environment.NewLine); + if (log.console != logConsole.hide) + { + ConsoleWrite(log); + } + } + else + { + if (log.console == logConsole.show) + { + ConsoleWrite(log); + } + } + toWriteLogs.Remove(log); + } + } + } + + private void ConsoleWrite(Log log) + { + if (haveConsole) + Console.Write(new ColorStrings(new ColorString(DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + ": " + log.text, logForeColor[(int)log.type], logBackColor[(int)log.type]))); + } + } +} \ No newline at end of file diff --git a/MyCommon/MultiLang.cs b/MyCommon/MultiLang.cs index 8b159b4..2ba7a96 100644 --- a/MyCommon/MultiLang.cs +++ b/MyCommon/MultiLang.cs @@ -11,7 +11,7 @@ namespace MyCommon { private Dictionary> multiDictionary = new Dictionary>(); //List of phrases by key private List langs = new List(); //Readable langs list - + public int langsCount { get { return langs.Count; } } /// @@ -40,7 +40,7 @@ namespace MyCommon /// public string IDToLang(int lang) { - if(lang < langs.Count) + if (lang < langs.Count) { return langs[lang]; } @@ -55,7 +55,7 @@ namespace MyCommon /// public bool TryLangToID(string lang, out int ID) { - for(int i = 0; i < langs.Count; i++) + for (int i = 0; i < langs.Count; i++) { if (lang == langs[i]) { @@ -67,7 +67,6 @@ namespace MyCommon return false; } - public List GetWords(string key) { if (!multiDictionary.ContainsKey(key)) diff --git a/MyCommon/MyCommon.csproj b/MyCommon/MyCommon.csproj index c99bbf3..3aa25e8 100644 --- a/MyCommon/MyCommon.csproj +++ b/MyCommon/MyCommon.csproj @@ -41,8 +41,12 @@ + + + + diff --git a/MyCommon/Properties/AssemblyInfo.cs b/MyCommon/Properties/AssemblyInfo.cs index aa01b6c..d52f5d9 100644 --- a/MyCommon/Properties/AssemblyInfo.cs +++ b/MyCommon/Properties/AssemblyInfo.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.InteropServices; -// Les informations générales relatives à un assembly dépendent de +// Les informations générales relatives à un assembly dépendent de // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations // associées à un assembly. [assembly: AssemblyTitle("MyCommon")] @@ -13,8 +13,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly -// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de // COM, affectez la valeur true à l'attribut ComVisible sur ce type. [assembly: ComVisible(false)] @@ -24,12 +24,12 @@ using System.Runtime.InteropServices; // Les informations de version pour un assembly se composent des quatre valeurs suivantes : // // Version principale -// Version secondaire +// Version secondaire // Numéro de build // Révision // -// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut // en utilisant '*', comme indiqué ci-dessous : // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] \ No newline at end of file diff --git a/MyCommon/Strings.cs b/MyCommon/Strings.cs new file mode 100644 index 0000000..3d07371 --- /dev/null +++ b/MyCommon/Strings.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; + +namespace MyCommon +{ + public static class Strings + { + /// + /// Simpler string array creation + /// + public static string[] ArrayFromStrings(params string[] args) + { + return args; + } + + public static string ArrayToString(string[] array) + { + string text = ""; + if (array != null) + { + foreach (string str in array) + { + text += ((text == "" ? "" : Environment.NewLine) + str); + } + } + return text; + } + + public static string ArrayToString(int[] array) + { + string text = ""; + foreach (int i in array) + { + text += ((text == "" ? "" : Environment.NewLine) + i.ToString()); + } + return text; + } + + public static string[] SplitArgs(string text) + { + return text.Split('"') + .Select((element, index) => index % 2 == 0 + ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + : new string[] { element }) + .SelectMany(element => element).ToArray(); + } + } +} \ No newline at end of file diff --git a/Readme.md b/Readme.md index adc0527..536c685 100644 --- a/Readme.md +++ b/Readme.md @@ -2,6 +2,10 @@ MyCommon is a collection of usefull Classes * MultiLang - 10/12/2016 +* ConsoleIO - 11/12/2016 (from MyConsole) +* Binary +* Logger +* Strings ### Prerequisities