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.Runtime.CompilerServices;
|
||||
using System.Collections.Generic;
|
||||
namespace sharp.extensions
|
||||
{
|
||||
public static class ArrayExtension
|
||||
|
@ -46,6 +48,9 @@ namespace sharp.extensions
|
|||
}
|
||||
public static T[] Segment<T>(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<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 static byte[] toBytes(char[] hexstring){
|
||||
return toBytes(new String(hexstring));
|
||||
}
|
||||
|
||||
public static byte[] toBytes(string hexstring)
|
||||
{
|
||||
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>
|
||||
<RootNamespace>sharp.extensions</RootNamespace>
|
||||
<AssemblyName>sharp.extensions</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -18,6 +18,7 @@
|
|||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
|
@ -40,6 +41,15 @@
|
|||
<Compile Include="Tripple.cs" />
|
||||
<Compile Include="Tuple.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>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue