master
Harald Wolff 2017-11-23 13:06:39 +01:00
parent f2ea0ed0b6
commit f07cc5b906
12 changed files with 440 additions and 2 deletions

37
ArgumentReader.cs 100644
View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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();
}
}
}
}
}
}

View File

@ -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];

View File

@ -0,0 +1,8 @@
using System;
namespace sharp.extensions
{
public interface IConstructorArguments
{
object[] getConstructorArguments();
}
}

78
LockFile.cs 100644
View File

@ -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");
}
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace sharp.extensions
{
public static class ObjectExtensions
{
public static bool IsNull(this object o){
return (o == null);
}
}
}

21
Pair.cs 100644
View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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>