1
0
Fork 0

Compare commits

...

7 Commits

Author SHA1 Message Date
sheychen b46e11e2c6 Logger Add Outputs 2017-01-20 14:58:41 +01:00
sheychen f7880dd6e0 Logger Colors Unification 2017-01-19 12:48:20 +01:00
sheychen f4480b684a Add LinkTable.GetEnumerator 2017-01-19 12:06:54 +01:00
sheychen 1c991d37b2 Add LinkTable and ConsoleIO System.Console support 2017-01-19 10:26:11 +01:00
sheychen aaca034ba8 Add XmlManager 2016-12-13 16:12:14 +01:00
sheychen ffde82e6db Logger Console error 2016-12-12 19:44:38 +01:00
sheychen 5fa4c85f2e Add Binary, ConsoleIO, Logger and Strings 2016-12-11 10:41:40 +01:00
15 changed files with 879 additions and 11 deletions

0
.gitattributes vendored Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

0
License.md Normal file → Executable file
View File

0
MyCommon.sln Normal file → Executable file
View File

175
MyCommon/Binary.cs Executable file
View File

@ -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;
}
///<remarks>1 byte</remarks>
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;
}
///<remarks>len(in bytes) + string</remarks>
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;
}
///<remarks>4 bytes</remarks>
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;
}
}
}
}

140
MyCommon/ConsoleIO.cs Executable file
View File

@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
namespace MyCommon
{
/// <summary>
/// Manager Console with Async I/O
/// </summary>
/// <remarks>No Mono Proof</remarks>
public class ConsoleIO
{
private static string inputBuffer = "";
private static List<ColorStrings> outputBuffer = new List<ColorStrings>();
public static string Title { get { return Console.Title; } set { Console.Title = value; } }
private static object locker = new object();
/// <summary>
/// Write a Colored text
/// </summary>
/// <remarks>as System.Console.WriteLine()</remarks>
public static void Write(ColorStrings Text)
{
outputBuffer.Add(Text);
while (outputBuffer.Count > Console.WindowHeight - 2) { outputBuffer.RemoveAt(0); }
Update();
}
/// <summary>
/// Read the next characters line
/// </summary>
/// <remarks>as System.Console.ReadLine()</remarks>
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));
}
/// <summary>
/// Clear buffer during ConsoleIO.Read()
/// </summary>
public static void ClearInput()
{
inputBuffer = ""; Update();
}
/// <summary>
/// Clear Console lines
/// </summary>
/// <remarks>as System.Console.Clear()</remarks>
public static void ClearOutput()
{
outputBuffer.Clear(); Update();
}
}
/// <summary>
/// Multiple Colors Text
/// </summary>
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();
}
}
/// <summary>
/// Single Color Text
/// </summary>
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;
}
}
}

View File

@ -0,0 +1,132 @@
using System.Collections.Generic;
namespace MyCommon.Generic
{
/// <summary>
/// Two way dictionary
/// </summary>
public class LinkTable<TMain, TSecond>
{
private Dictionary<TMain, TSecond> mainTable;
private Dictionary<TSecond, TMain> secondTable;
public Dictionary<TMain, TSecond> Main { get { return mainTable; } }
public Dictionary<TSecond, TMain> Second { get { return secondTable; } }
public int Count { get { return mainTable.Count; } }
public LinkTable()
{
mainTable = new Dictionary<TMain, TSecond>();
secondTable = new Dictionary<TSecond, TMain>();
}
public void Add(TMain main, TSecond second)
{
mainTable.Add(main, second);
secondTable.Add(second, main);
}
public bool TryAdd(TMain main, TSecond second)
{
try
{
Add(main, second);
return true;
}
catch
{
return false;
}
}
public void Clear()
{
mainTable.Clear();
secondTable.Clear();
}
public bool ContainsMain(TMain main)
{
return mainTable.ContainsKey(main);
}
public bool ContainsSecond(TSecond second)
{
return secondTable.ContainsKey(second);
}
public TMain GetMain(TSecond second)
{
return secondTable[second];
}
public TSecond GetSecond(TMain main)
{
return mainTable[main];
}
public bool TryGetMain(TSecond second, out TMain main)
{
return secondTable.TryGetValue(second, out main);
}
public bool TryGetSecond(TMain main, out TSecond second)
{
return mainTable.TryGetValue(main, out second);
}
public void RemoveMain(TMain main)
{
secondTable.Remove(mainTable[main]);
mainTable.Remove(main);
}
public void RemoveSecond(TSecond second)
{
mainTable.Remove(secondTable[second]);
secondTable.Remove(second);
}
public bool TryRemoveMain(TMain main)
{
if (!mainTable.ContainsKey(main))
return false;
if (!secondTable.ContainsKey(mainTable[main]))
return false;
try
{
RemoveMain(main);
return true;
}
catch
{
return false;
}
}
public bool TryRemoveSecond(TSecond second)
{
if (!secondTable.ContainsKey(second))
return false;
if (!mainTable.ContainsKey(secondTable[second]))
return false;
try
{
RemoveSecond(second);
return true;
}
catch
{
return false;
}
}
public Dictionary<TMain, TSecond>.Enumerator GetEnumerator()
{
return mainTable.GetEnumerator();
}
}
}

0
MyCommon/Lang.csv Normal file → Executable file
View File

237
MyCommon/Logger.cs Executable file
View File

@ -0,0 +1,237 @@
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 = 0, debug, info, warm, error, fatal }
public enum logDisplay { normal, show, hide }
public struct Log
{
public string text;
public logType type;
public logDisplay display;
public Log(string p1, logType p2, logDisplay p3 = logDisplay.normal)
{
text = p1;
type = p2;
display = p3;
}
}
List<Log> toWriteLogs = new List<Log>();
string logPath;
ConsoleColor[] logBackColor;
ConsoleColor[] logForeColor;
Thread Updater;
logType logLevel = logType.info;
bool _run = true;
public bool run { get { return _run; } }
static bool _debug = false;
static bool _dev = false;
List<string> _outList;
public List<string> outList { get { return _outList; } }
string _outText;
public string outText { get { return _outText; } }
public struct Outputs
{
public bool File;
public bool Console;
public bool ConsoleIO;
public bool List;
public bool Text;
public Outputs(bool file = true, bool console = false, bool consoleIO = true, bool stringList = false, bool text = false )
{
File = file;
Console = console;
ConsoleIO = consoleIO;
List = stringList;
Text = text;
}
}
Outputs outputs;
/// <summary>
/// Create log file and start logger thread
/// </summary>
/// <param name="LogPath">Absolute path to logs directory</param>
public void Initialise(string LogPath, ConsoleColor[] backColor, ConsoleColor[] foreColor, logType LogLevel = logType.info, bool debug = false, bool dev = false, Outputs output = new Outputs())
{
outputs = output;
logPath = LogPath;
logBackColor = backColor;
logForeColor = foreColor;
logLevel = LogLevel;
_debug = debug;
_dev = dev;
if (outputs.File)
{
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);
}
if (outputs.Console || outputs.ConsoleIO)
{
Console.BackgroundColor = logBackColor[0];
Console.ForegroundColor = logForeColor[0];
Console.Clear();
}
if (outputs.Text)
{
_outText = "";
}
if (outputs.List)
{
_outList = new List<string>();
}
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, logType.info, logDisplay.show);
}
/// <summary>
/// Add log to log pile
/// </summary>
/// <param name="text">Log text</param>
/// <param name="type">Log status</param>
/// <param name="console">Server display modifier</param>
public void Write(string text, logType type, logDisplay console = logDisplay.normal)
{
Write(new Log(text, type, console));
}
/// <summary>
/// Add log to log pile
/// </summary>
/// <param name="log">Log struct</param>
void Write(Log log)
{
if (_debug || _dev)
{
//Add Source Method
log.text = "[" + new StackTrace().GetFrame(2).GetMethod().Name + "]: " + log.text;
}
toWriteLogs.Add(log);
}
/// <summary>
/// Write log pile to logfile and console
/// </summary>
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 || log.display == logDisplay.show)
{
string datetime = DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture);
string text = datetime + " [" + log.type.ToString().ToUpper() + "]: " + log.text;
string textfull = datetime + ": " + log.text;
if (outputs.File && log.type >= logLevel)
{
File.AppendAllText(logPath, textfull + Environment.NewLine);
}
if (outputs.Console)
{
Console.ResetColor();
Console.ForegroundColor = logForeColor[(int)log.type];
Console.BackgroundColor = logBackColor[(int)log.type];
Console.WriteLine(text);
}
if (outputs.ConsoleIO)
{
ConsoleIO.Write(new ColorStrings(new ColorString(text, logForeColor[(int)log.type], logBackColor[(int)log.type])));
}
if (outputs.List)
{
_outList.Add(textfull);
}
if (outputs.Text)
{
_outText += textfull + Environment.NewLine;
}
}
toWriteLogs.Remove(log);
}
}
}
}
}

7
MyCommon/MultiLang.cs Normal file → Executable file
View File

@ -11,7 +11,7 @@ namespace MyCommon
{
private Dictionary<string, List<string>> multiDictionary = new Dictionary<string, List<string>>(); //List of phrases by key
private List<string> langs = new List<string>(); //Readable langs list
public int langsCount { get { return langs.Count; } }
/// <summary>
@ -40,7 +40,7 @@ namespace MyCommon
/// </summary>
public string IDToLang(int lang)
{
if(lang < langs.Count)
if (lang < langs.Count)
{
return langs[lang];
}
@ -55,7 +55,7 @@ namespace MyCommon
/// </summary>
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<string> GetWords(string key)
{
if (!multiDictionary.ContainsKey(key))

View File

@ -41,12 +41,21 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Binary.cs" />
<Compile Include="ConsoleIO.cs" />
<Compile Include="Logger.cs" />
<Compile Include="MultiLang.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Strings.cs" />
<Compile Include="XmlManager.cs" />
<Compile Include="Generic\LinkTable.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Lang.csv" />
</ItemGroup>
<ItemGroup>
<Folder Include="Generic\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

14
MyCommon/Properties/AssemblyInfo.cs Normal file → Executable file
View File

@ -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.2.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]

48
MyCommon/Strings.cs Executable file
View File

@ -0,0 +1,48 @@
using System;
using System.Linq;
namespace MyCommon
{
public static class Strings
{
/// <summary>
/// Simpler string array creation
/// </summary>
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();
}
}
}

122
MyCommon/XmlManager.cs Executable file
View File

@ -0,0 +1,122 @@
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace MyCommon
{
public static class XmlManager
{
public enum LoadMode { ReadOnly, ReadOrCreate, ReadCreateOrReplace };
/// <summary>
/// Load class from xml file
/// </summary>
/// <param name="filepath">Path to xml file</param>
/// <param name="schema">null disable Correct check (unsafe)</param>
/// <returns>Loaded class</returns>
/// <remarks>App.config is too easy</remarks>
public static T Load<T>(string filepath, LoadMode mode, XmlReader schema, Logger logger = null) where T : new()
{
T file = new T();
if (logger != null) { logger.Write("Loading " + file.GetType().Name, Logger.logType.info); }
if (File.Exists(filepath))
{
bool correct = false;
if(schema != null)
{
correct = Correct<T>(file, filepath, schema, logger);
}
else
{
correct = true;
}
if (correct)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StreamReader re = new StreamReader(filepath))
{
file = (T)xs.Deserialize(re);
};
}
else
{
if (mode == LoadMode.ReadCreateOrReplace)
{
if (logger != null) { logger.Write("Old " + file.GetType().Name + " in .old", Logger.logType.warm); }
File.Delete(filepath + ".old");
File.Move(filepath, filepath + ".old");
Save<T>(file, filepath, logger);
}
}
}
else
{
if (logger != null) { logger.Write("Any config file", Logger.logType.error); }
if (mode != LoadMode.ReadOnly)
{
Save<T>(file, filepath, logger);
}
}
if (logger != null) { logger.Write(file.GetType().Name + " loaded", Logger.logType.debug); }
return file;
}
/// <summary>
/// Write class in xml file
/// </summary>
public static void Save<T>(T file, string path, Logger logger = null)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StreamWriter st = new StreamWriter(path))
{
xs.Serialize(st, file);
};
if (logger != null) { logger.Write(file.GetType().Name + " saved", Logger.logType.debug); }
}
/// <summary>
/// Check file format using Schema
/// </summary>
public static bool Correct<T>(T file, string filepath, XmlReader schema, Logger logger = null)
{
bool isCorrect = false;
using (Stream fs = new FileStream(filepath, FileMode.Open))
{
XmlReader re = new XmlTextReader(fs);
XmlSerializer xs = new XmlSerializer(typeof(T));
try
{
isCorrect = xs.CanDeserialize(re);
}
catch (XmlException e)
{
isCorrect = false;
if (logger != null) { logger.Write("Format check error: " + e.Message, Logger.logType.error); }
}
}
if (isCorrect)
{
try
{
XmlDocument d = new XmlDocument();
d.Load(filepath);
d.Schemas.Add("", schema);
d.Validate((o, e) =>
{
if (logger != null) { logger.Write("Format check error: " + e.Message, Logger.logType.error); }
isCorrect = false;
});
}
catch (XmlException e)
{
isCorrect = false;
if (logger != null) { logger.Write("Format check error: " + e.Message, Logger.logType.error); }
}
}
return isCorrect;
}
}
}

6
Readme.md Normal file → Executable file
View File

@ -2,6 +2,12 @@
MyCommon is a collection of usefull Classes
* MultiLang - 10/12/2016
* ConsoleIO - 11/12/2016 <sup>(from MyConsole)<sup/>
* Binary
* Logger
* Strings
* XmlMananger - 13/12/2016
* LinkTable - 19/001/2017
### Prerequisities