WIP
parent
f2ea0ed0b6
commit
f07cc5b906
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
20
Array.cs
20
Array.cs
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Collections.Generic;
|
||||||
namespace sharp.extensions
|
namespace sharp.extensions
|
||||||
{
|
{
|
||||||
public static class ArrayExtension
|
public static class ArrayExtension
|
||||||
|
@ -46,6 +48,9 @@ namespace sharp.extensions
|
||||||
}
|
}
|
||||||
public static T[] Segment<T>(this T[] source,int start,int len){
|
public static T[] Segment<T>(this T[] source,int start,int len){
|
||||||
T[] temp = new T[len];
|
T[] temp = new T[len];
|
||||||
|
if ((start + len) > source.Length){
|
||||||
|
len = source.Length - start;
|
||||||
|
}
|
||||||
Array.Copy(source,start,temp,0,len);
|
Array.Copy(source,start,temp,0,len);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
@ -82,5 +87,20 @@ namespace sharp.extensions
|
||||||
return Insert(a, insert, start, insert.Length);
|
return Insert(a, insert, start, insert.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T[] Combine<T>(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<T>(this T[] a,T[] b){
|
||||||
|
List<T> rl = new List<T>(a);
|
||||||
|
foreach (T element in b){
|
||||||
|
rl.Remove(element);
|
||||||
|
}
|
||||||
|
return rl.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ExtendableThread> availableThreads = new Stack<ExtendableThread>();
|
||||||
|
List<ExtendableThread> activeThreads = new List<ExtendableThread>();
|
||||||
|
|
||||||
|
Queue<TaskDelegate> queuedTasks = new Queue<TaskDelegate>();
|
||||||
|
|
||||||
|
public static ThreadLocal<ExtendableThread> CurrentExtendedThread { get; private set; } = new ThreadLocal<ExtendableThread>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,10 @@ namespace sharp.extensions
|
||||||
{
|
{
|
||||||
public class HexString
|
public class HexString
|
||||||
{
|
{
|
||||||
|
public static byte[] toBytes(char[] hexstring){
|
||||||
|
return toBytes(new String(hexstring));
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] toBytes(string hexstring)
|
public static byte[] toBytes(string hexstring)
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[hexstring.Length >> 1];
|
byte[] bytes = new byte[hexstring.Length >> 1];
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
using System;
|
||||||
|
namespace sharp.extensions
|
||||||
|
{
|
||||||
|
public interface IConstructorArguments
|
||||||
|
{
|
||||||
|
object[] getConstructorArguments();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
namespace sharp.extensions
|
||||||
|
{
|
||||||
|
public static class ObjectExtensions
|
||||||
|
{
|
||||||
|
public static bool IsNull(this object o){
|
||||||
|
return (o == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
namespace sharp.extensions
|
||||||
|
{
|
||||||
|
public class Pair<T>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>sharp.extensions</RootNamespace>
|
<RootNamespace>sharp.extensions</RootNamespace>
|
||||||
<AssemblyName>sharp.extensions</AssemblyName>
|
<AssemblyName>sharp.extensions</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<ConsolePause>false</ConsolePause>
|
<ConsolePause>false</ConsolePause>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
|
@ -40,6 +41,15 @@
|
||||||
<Compile Include="Tripple.cs" />
|
<Compile Include="Tripple.cs" />
|
||||||
<Compile Include="Tuple.cs" />
|
<Compile Include="Tuple.cs" />
|
||||||
<Compile Include="CharExtensions.cs" />
|
<Compile Include="CharExtensions.cs" />
|
||||||
|
<Compile Include="Pair.cs" />
|
||||||
|
<Compile Include="StreamExtensions.cs" />
|
||||||
|
<Compile Include="LockFile.cs" />
|
||||||
|
<Compile Include="DirectoryExtensions.cs" />
|
||||||
|
<Compile Include="IConstructorArguments.cs" />
|
||||||
|
<Compile Include="ConstructableObject.cs" />
|
||||||
|
<Compile Include="ExtendableThreadPool.cs" />
|
||||||
|
<Compile Include="ArgumentReader.cs" />
|
||||||
|
<Compile Include="ObjectExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in New Issue