diff --git a/ArgumentReader.cs b/ArgumentReader.cs new file mode 100644 index 0000000..c290c50 --- /dev/null +++ b/ArgumentReader.cs @@ -0,0 +1,37 @@ +using System; +namespace sharp.extensions +{ + public class ArgumentReader + { + int current; + string[] arguments; + + public ArgumentReader(String[] arguments) + { + this.arguments = arguments; + this.current = 0; + } + + public String Current { get { return this.arguments[this.current]; } } + public String Next() { MoveNext(); return Current; } + + public bool MoveNext(){ + this.current++; + return this.current < this.arguments.Length; + } + + public string[] NextFollowing(int n) + { + string[] result = this.arguments.Segment(this.current + 1, n); + this.current += result.Length; + return result; + + return new string[0]; + } + + public string[] Reminder(){ + return this.arguments.Segment(this.current+1); + } + + } +} diff --git a/Array.cs b/Array.cs index 6a1b047..07c6374 100644 --- a/Array.cs +++ b/Array.cs @@ -1,4 +1,6 @@ using System; +using System.Runtime.CompilerServices; +using System.Collections.Generic; namespace sharp.extensions { public static class ArrayExtension @@ -46,6 +48,9 @@ namespace sharp.extensions } public static T[] Segment(this T[] source,int start,int len){ T[] temp = new T[len]; + if ((start + len) > source.Length){ + len = source.Length - start; + } Array.Copy(source,start,temp,0,len); return temp; } @@ -82,5 +87,20 @@ namespace sharp.extensions return Insert(a, insert, start, insert.Length); } + public static T[] Combine(this T[] a,T[] b){ + T[] r = new T[a.Length + b.Length]; + Array.Copy(a,r,a.Length); + Array.Copy(b,0,r,a.Length,b.Length); + return r; + } + + public static T[] Remove(this T[] a,T[] b){ + List rl = new List(a); + foreach (T element in b){ + rl.Remove(element); + } + return rl.ToArray(); + } + } } diff --git a/ConstructableObject.cs b/ConstructableObject.cs new file mode 100644 index 0000000..649571b --- /dev/null +++ b/ConstructableObject.cs @@ -0,0 +1,36 @@ +using System; +using System.Linq; +using System.Reflection; +namespace sharp.extensions +{ + public class ConstructableObject + { + public string AssemblyName; + public string TypeName; + public object[] ConstructorArguments; + + public ConstructableObject(){ + } + + public ConstructableObject(object o) + { + Type t = o.GetType(); + + TypeName = t.FullName; + AssemblyName = t.Assembly.FullName; + + if (t.GetInterfaces().Contains(typeof(IConstructorArguments))){ + this.ConstructorArguments = ((IConstructorArguments)o).getConstructorArguments(); + } else { + this.ConstructorArguments = new object[0]; + } + } + + public object Construct(){ + Assembly assy = Assembly.Load(AssemblyName); + Type t = assy.GetType(TypeName); + object o = Activator.CreateInstance(t, ConstructorArguments); + return o; + } + } +} diff --git a/DirectoryExtensions.cs b/DirectoryExtensions.cs new file mode 100644 index 0000000..4da32e3 --- /dev/null +++ b/DirectoryExtensions.cs @@ -0,0 +1,15 @@ +using System; +using System.IO; +namespace sharp.extensions +{ + public static class DirectoryExtensions + { + + public static void EnsureDirectoryExists(string path){ + if (!Directory.Exists(path)){ + Directory.CreateDirectory(path); + } + } + + } +} diff --git a/ExtendableThreadPool.cs b/ExtendableThreadPool.cs new file mode 100644 index 0000000..0078e13 --- /dev/null +++ b/ExtendableThreadPool.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System.Linq; +namespace sharp.extensions +{ + public delegate void TaskDelegate(); + + public class ExtendableThreadPool + { + Stack availableThreads = new Stack(); + List activeThreads = new List(); + + Queue queuedTasks = new Queue(); + + public static ThreadLocal CurrentExtendedThread { get; private set; } = new ThreadLocal(); + + public int MaximumConcurrentThreads { get; set; } = -1; + + public ExtendableThreadPool() + { + } + + public void QueueTask(TaskDelegate task){ + lock(this) + { + queuedTasks.Enqueue(task); + SignalQueue(); + } + } + + private void SignalQueue(){ + ExtendableThread st; + + lock (this){ + if (availableThreads.Count > 0){ + st = availableThreads.Pop(); + Monitor.Enter(st); + Monitor.Pulse(st); + Monitor.Exit(st); + } else { + st = new ExtendableThread(this); + } + } + } + + private TaskDelegate fetchTask(){ + lock (this){ + if (queuedTasks.Count == 0){ + return null; + } else { + return queuedTasks.Dequeue(); + } + } + } + + protected void InvokeTaskDelegate(TaskDelegate task) + { + try + { + task.Invoke(); + } + catch (Exception e) + { + Console.WriteLine("InvokeTaskDelegate:t Task threw exception: {0}", e.ToString()); + } + } + + public class ExtendableThread + { + Thread thread; + bool requestExit; + bool isReady; + + public ExtendableThreadPool Pool { get; private set; } + + public ExtendableThread(ExtendableThreadPool pool) + { + Pool = pool; + thread = new Thread(worker); + thread.Start(); + } + + public bool IsReady { + get + { + lock (this){ + return isReady; + } + } + } + + public bool ExitRequested { + get { lock(this) { return requestExit; } } + } + + protected void InvokeTaskDelegate(TaskDelegate task) + { + Pool.InvokeTaskDelegate(task); + } + + private void worker(){ + ExtendableThreadPool.CurrentExtendedThread.Value = this; + + bool taskAvailable = true; + + while (!ExitRequested){ + TaskDelegate t; + + while ((t = Pool.fetchTask()) != null) + { + if (t != null) + { + InvokeTaskDelegate(t); + } + } + + + lock(Pool) + { + Pool.activeThreads.Remove(this); + Pool.availableThreads.Push(this); + } + + + lock(this) + { + isReady = true; + + while (!Monitor.Wait(this, 250) && !ExitRequested) { } + + if (ExitRequested) + { + break; + } + } + lock (Pool) + { + Pool.activeThreads.Add(this); + } + + } + + lock(this){ + Monitor.Pulse(this); + isReady = false; + } + } + + public void Stop() + { + lock (this) + { + requestExit = true; + } + } + public void Stop(int timeoutms) + { + lock (this) + { + requestExit = true; + Monitor.Wait(this, timeoutms); + if (thread.IsAlive){ + thread.Abort(); + } + } + } + + } + + + } +} diff --git a/HexString.cs b/HexString.cs index 7261003..317e66a 100644 --- a/HexString.cs +++ b/HexString.cs @@ -5,6 +5,10 @@ namespace sharp.extensions { public class HexString { + public static byte[] toBytes(char[] hexstring){ + return toBytes(new String(hexstring)); + } + public static byte[] toBytes(string hexstring) { byte[] bytes = new byte[hexstring.Length >> 1]; diff --git a/IConstructorArguments.cs b/IConstructorArguments.cs new file mode 100644 index 0000000..ab16173 --- /dev/null +++ b/IConstructorArguments.cs @@ -0,0 +1,8 @@ +using System; +namespace sharp.extensions +{ + public interface IConstructorArguments + { + object[] getConstructorArguments(); + } +} diff --git a/LockFile.cs b/LockFile.cs new file mode 100644 index 0000000..16ddec8 --- /dev/null +++ b/LockFile.cs @@ -0,0 +1,78 @@ +using System; +using System.IO; +using System.Threading; +using System.Text; +using System.Diagnostics; +namespace sharp.extensions +{ + public class LockFile + { + public string LockFileName { get; private set; } + public bool IsLocked { get; private set; } + + public int LockCount { get; private set; } + + public LockFile(string filename) + { + this.LockFileName = filename; + this.LockCount = 0; + } + + public void Lock() + { + if (IsLocked){ + LockCount++; + return; + } + + int retries = 3; + + Console.WriteLine("wait on lock file {0}", LockFileName); + + for (; retries > 0; retries--) + { + while (File.Exists(LockFileName)) + { + Thread.Sleep(250); + } + try + { + FileStream ls = new FileStream(LockFileName, FileMode.CreateNew); + byte[] pid = Encoding.UTF8.GetBytes(Process.GetCurrentProcess().Id.ToString()); + ls.Write(pid, 0, pid.Length); + ls.Close(); + IsLocked = true; + LockCount = 1; + + Console.WriteLine("lock acquired"); + return; + } + catch (IOException ioe) + { + } + } + ThrowIfUnlocked(); + } + + public void Unlock() + { + if (IsLocked) + { + LockCount--; + + if (LockCount == 0) + { + File.Delete(LockFileName); + IsLocked = false; + } + } + } + + public void ThrowIfUnlocked(){ + if (!IsLocked){ + throw new Exception("Lockfile is not locked"); + } + } + + } +} diff --git a/ObjectExtensions.cs b/ObjectExtensions.cs new file mode 100644 index 0000000..6acf6c2 --- /dev/null +++ b/ObjectExtensions.cs @@ -0,0 +1,10 @@ +using System; +namespace sharp.extensions +{ + public static class ObjectExtensions + { + public static bool IsNull(this object o){ + return (o == null); + } + } +} diff --git a/Pair.cs b/Pair.cs new file mode 100644 index 0000000..424523d --- /dev/null +++ b/Pair.cs @@ -0,0 +1,21 @@ +using System; +namespace sharp.extensions +{ + public class Pair + { + public T Item1 { get; set; } + public T Item2 { get; set; } + + public Pair(T i1,T i2) + { + Item1 = i1; + Item2 = i2; + } + + public override string ToString() + { + return string.Format("[Pair: Item1={0}, Item2={1}]", Item1, Item2); + } + + } +} diff --git a/StreamExtensions.cs b/StreamExtensions.cs new file mode 100644 index 0000000..f8ad3ca --- /dev/null +++ b/StreamExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Text; + +namespace sharp.extensions +{ + public static class StreamExtensions + { + static ASCIIEncoding ascii = new ASCIIEncoding(); + + public static string ReadLine(this Stream stream){ + MemoryStream m = new MemoryStream(); + int by; + + while ((by = stream.ReadByte()) != 0x0a){ + if (by != 0x0d){ + m.WriteByte((byte)by); + } + } + + return ascii.GetString(m.GetBuffer(),0,(int)m.Length); + } + + } +} diff --git a/sharp.extensions.csproj b/sharp.extensions.csproj index 8de292c..da07a2d 100644 --- a/sharp.extensions.csproj +++ b/sharp.extensions.csproj @@ -7,7 +7,7 @@ Library sharp.extensions sharp.extensions - v4.5 + v4.7 true @@ -18,6 +18,7 @@ prompt 4 false + x64 true @@ -40,6 +41,15 @@ + + + + + + + + + - \ No newline at end of file +