mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-04-30 02:37:49 +02:00
Updates to Utilities
This commit is contained in:
parent
6cb61ca63e
commit
5508c749ce
13 changed files with 417 additions and 13 deletions
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -33,6 +32,35 @@ namespace Utilities
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] XOR(byte[] array1, byte[] array2)
|
||||||
|
{
|
||||||
|
if (array1.Length == array2.Length)
|
||||||
|
{
|
||||||
|
return XOR(array1, 0, array2, 0, array1.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Arrays must be of equal length");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] XOR(byte[] array1, int offset1, byte[] array2, int offset2, int length)
|
||||||
|
{
|
||||||
|
if (offset1 + length <= array1.Length && offset2 + length <= array2.Length)
|
||||||
|
{
|
||||||
|
byte[] result = new byte[length];
|
||||||
|
for (int index = 0; index < length; index++)
|
||||||
|
{
|
||||||
|
result[index] = (byte)(array1[offset1 + index] ^ array2[offset2 + index]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static long CopyStream(Stream input, Stream output)
|
public static long CopyStream(Stream input, Stream output)
|
||||||
{
|
{
|
||||||
// input may not support seeking, so don't use input.Position
|
// input may not support seeking, so don't use input.Position
|
||||||
|
@ -41,7 +69,7 @@ namespace Utilities
|
||||||
|
|
||||||
public static long CopyStream(Stream input, Stream output, long count)
|
public static long CopyStream(Stream input, Stream output, long count)
|
||||||
{
|
{
|
||||||
const int MaxBufferSize = 4194304; // 4 MB
|
const int MaxBufferSize = 1048576; // 1 MB
|
||||||
int bufferSize = (int)Math.Min(MaxBufferSize, count);
|
int bufferSize = (int)Math.Min(MaxBufferSize, count);
|
||||||
byte[] buffer = new byte[bufferSize];
|
byte[] buffer = new byte[bufferSize];
|
||||||
long totalBytesRead = 0;
|
long totalBytesRead = 0;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,41 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Utilities
|
namespace Utilities
|
||||||
{
|
{
|
||||||
public class LittleEndianReader
|
public class LittleEndianReader
|
||||||
{
|
{
|
||||||
|
public static short ReadInt16(byte[] buffer, ref int offset)
|
||||||
|
{
|
||||||
|
offset += 2;
|
||||||
|
return LittleEndianConverter.ToInt16(buffer, offset - 2);
|
||||||
|
}
|
||||||
|
|
||||||
public static ushort ReadUInt16(byte[] buffer, ref int offset)
|
public static ushort ReadUInt16(byte[] buffer, ref int offset)
|
||||||
{
|
{
|
||||||
offset += 2;
|
offset += 2;
|
||||||
return LittleEndianConverter.ToUInt16(buffer, offset - 2);
|
return LittleEndianConverter.ToUInt16(buffer, offset - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int ReadInt32(byte[] buffer, ref int offset)
|
||||||
|
{
|
||||||
|
offset += 4;
|
||||||
|
return LittleEndianConverter.ToInt32(buffer, offset - 4);
|
||||||
|
}
|
||||||
|
|
||||||
public static uint ReadUInt32(byte[] buffer, ref int offset)
|
public static uint ReadUInt32(byte[] buffer, ref int offset)
|
||||||
{
|
{
|
||||||
offset += 4;
|
offset += 4;
|
||||||
return LittleEndianConverter.ToUInt32(buffer, offset - 4);
|
return LittleEndianConverter.ToUInt32(buffer, offset - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long ReadInt64(byte[] buffer, ref int offset)
|
||||||
|
{
|
||||||
|
offset += 8;
|
||||||
|
return LittleEndianConverter.ToInt64(buffer, offset - 8);
|
||||||
|
}
|
||||||
|
|
||||||
public static ulong ReadUInt64(byte[] buffer, ref int offset)
|
public static ulong ReadUInt64(byte[] buffer, ref int offset)
|
||||||
{
|
{
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
@ -29,5 +47,54 @@ namespace Utilities
|
||||||
offset += 16;
|
offset += 16;
|
||||||
return LittleEndianConverter.ToGuid(buffer, offset - 16);
|
return LittleEndianConverter.ToGuid(buffer, offset - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static short ReadInt16(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[2];
|
||||||
|
stream.Read(buffer, 0, 2);
|
||||||
|
return LittleEndianConverter.ToInt16(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort ReadUInt16(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[2];
|
||||||
|
stream.Read(buffer, 0, 2);
|
||||||
|
return LittleEndianConverter.ToUInt16(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ReadInt32(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
stream.Read(buffer, 0, 4);
|
||||||
|
return LittleEndianConverter.ToInt32(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint ReadUInt32(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[4];
|
||||||
|
stream.Read(buffer, 0, 4);
|
||||||
|
return LittleEndianConverter.ToUInt32(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long ReadInt64(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
stream.Read(buffer, 0, 8);
|
||||||
|
return LittleEndianConverter.ToInt64(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ulong ReadUInt64(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[8];
|
||||||
|
stream.Read(buffer, 0, 8);
|
||||||
|
return LittleEndianConverter.ToUInt64(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Guid ReadGuidBytes(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[16];
|
||||||
|
stream.Read(buffer, 0, 16);
|
||||||
|
return LittleEndianConverter.ToGuid(buffer, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
85
Utilities/Generics/BlockingQueue.cs
Normal file
85
Utilities/Generics/BlockingQueue.cs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Utilities
|
||||||
|
{
|
||||||
|
public class BlockingQueue<T>
|
||||||
|
{
|
||||||
|
private Queue<T> m_queue = new Queue<T>();
|
||||||
|
private int m_count = 0;
|
||||||
|
private bool m_stopping;
|
||||||
|
|
||||||
|
public void Enqueue(T item)
|
||||||
|
{
|
||||||
|
lock (m_queue)
|
||||||
|
{
|
||||||
|
m_queue.Enqueue(item);
|
||||||
|
m_count++;
|
||||||
|
if (m_queue.Count == 1)
|
||||||
|
{
|
||||||
|
Monitor.Pulse(m_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enqueue(List<T> items)
|
||||||
|
{
|
||||||
|
if (items.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lock (m_queue)
|
||||||
|
{
|
||||||
|
foreach (T item in items)
|
||||||
|
{
|
||||||
|
m_queue.Enqueue(item);
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
if (m_queue.Count == items.Count)
|
||||||
|
{
|
||||||
|
Monitor.Pulse(m_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <returns>Will return false if the BlockingQueue is stopped</returns>
|
||||||
|
public bool TryDequeue(out T item)
|
||||||
|
{
|
||||||
|
lock (m_queue)
|
||||||
|
{
|
||||||
|
while (m_queue.Count == 0)
|
||||||
|
{
|
||||||
|
Monitor.Wait(m_queue);
|
||||||
|
if (m_stopping)
|
||||||
|
{
|
||||||
|
item = default(T);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item = m_queue.Dequeue();
|
||||||
|
m_count--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
lock (m_queue)
|
||||||
|
{
|
||||||
|
m_stopping = true;
|
||||||
|
Monitor.PulseAll(m_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,10 @@ namespace Utilities
|
||||||
{
|
{
|
||||||
public bool ContainsKey(TKey key)
|
public bool ContainsKey(TKey key)
|
||||||
{
|
{
|
||||||
return (this.IndexOf(key) != -1);
|
return (this.IndexOfKey(key) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int IndexOf(TKey key)
|
public int IndexOfKey(TKey key)
|
||||||
{
|
{
|
||||||
for (int index = 0; index < this.Count; index++)
|
for (int index = 0; index < this.Count; index++)
|
||||||
{
|
{
|
||||||
|
|
163
Utilities/Generics/SortedList.cs
Normal file
163
Utilities/Generics/SortedList.cs
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Utilities
|
||||||
|
{
|
||||||
|
public class SortedList<T> : ICollection<T>
|
||||||
|
{
|
||||||
|
private List<T> m_innerList;
|
||||||
|
private Comparer<T> m_comparer;
|
||||||
|
|
||||||
|
public SortedList() : this(Comparer<T>.Default)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedList(Comparer<T> comparer)
|
||||||
|
{
|
||||||
|
m_innerList = new List<T>();
|
||||||
|
m_comparer = comparer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(T item)
|
||||||
|
{
|
||||||
|
int insertIndex = FindIndexForSortedInsert(m_innerList, m_comparer, item);
|
||||||
|
m_innerList.Insert(insertIndex, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(T item)
|
||||||
|
{
|
||||||
|
return IndexOf(item) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Searches for the specified object and returns the zero-based index of the first occurrence within the entire SortedList<T>
|
||||||
|
/// </summary>
|
||||||
|
public int IndexOf(T item)
|
||||||
|
{
|
||||||
|
int insertIndex = FindIndexForSortedInsert(m_innerList, m_comparer, item);
|
||||||
|
if (insertIndex == m_innerList.Count)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (m_comparer.Compare(item, m_innerList[insertIndex]) == 0)
|
||||||
|
{
|
||||||
|
int index = insertIndex;
|
||||||
|
while (index > 0 && m_comparer.Compare(item, m_innerList[index - 1]) == 0)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(T item)
|
||||||
|
{
|
||||||
|
int index = IndexOf(item);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
m_innerList.RemoveAt(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
m_innerList.RemoveAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(T[] array)
|
||||||
|
{
|
||||||
|
m_innerList.CopyTo(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(T[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
m_innerList.CopyTo(array, arrayIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
m_innerList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_innerList[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
{
|
||||||
|
return m_innerList.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return m_innerList.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_innerList.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsReadOnly
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int FindIndexForSortedInsert(List<T> list, Comparer<T> comparer, T item)
|
||||||
|
{
|
||||||
|
if (list.Count == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lowerIndex = 0;
|
||||||
|
int upperIndex = list.Count - 1;
|
||||||
|
int comparisonResult;
|
||||||
|
while (lowerIndex < upperIndex)
|
||||||
|
{
|
||||||
|
int middleIndex = (lowerIndex + upperIndex) / 2;
|
||||||
|
T middle = list[middleIndex];
|
||||||
|
comparisonResult = comparer.Compare(middle, item);
|
||||||
|
if (comparisonResult == 0)
|
||||||
|
{
|
||||||
|
return middleIndex;
|
||||||
|
}
|
||||||
|
else if (comparisonResult > 0) // middle > item
|
||||||
|
{
|
||||||
|
upperIndex = middleIndex - 1;
|
||||||
|
}
|
||||||
|
else // middle < item
|
||||||
|
{
|
||||||
|
lowerIndex = middleIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point any entry following 'middle' is greater than 'item',
|
||||||
|
// and any entry preceding 'middle' is lesser than 'item'.
|
||||||
|
// So we either put 'item' before or after 'middle'.
|
||||||
|
comparisonResult = comparer.Compare(list[lowerIndex], item);
|
||||||
|
if (comparisonResult < 0) // middle < item
|
||||||
|
{
|
||||||
|
return lowerIndex + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return lowerIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,18 +96,30 @@ namespace Utilities
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> SplitIgnoreQuotedSeparators(string str, char separator)
|
public static List<string> SplitIgnoreQuotedSeparators(string str, char separator)
|
||||||
|
{
|
||||||
|
return SplitIgnoreQuotedSeparators(str, separator, StringSplitOptions.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> SplitIgnoreQuotedSeparators(string str, char separator, StringSplitOptions options)
|
||||||
{
|
{
|
||||||
List<string> result = new List<string>();
|
List<string> result = new List<string>();
|
||||||
int nextEntryIndex = 0;
|
int nextEntryIndex = 0;
|
||||||
int separatorIndex = IndexOfUnquotedChar(str, separator);
|
int separatorIndex = IndexOfUnquotedChar(str, separator);
|
||||||
while (separatorIndex >= nextEntryIndex)
|
while (separatorIndex >= nextEntryIndex)
|
||||||
{
|
{
|
||||||
result.Add(str.Substring(nextEntryIndex, separatorIndex - nextEntryIndex));
|
string entry = str.Substring(nextEntryIndex, separatorIndex - nextEntryIndex);
|
||||||
|
if (options != StringSplitOptions.RemoveEmptyEntries || entry != String.Empty)
|
||||||
|
{
|
||||||
|
result.Add(entry);
|
||||||
|
}
|
||||||
nextEntryIndex = separatorIndex + 1;
|
nextEntryIndex = separatorIndex + 1;
|
||||||
separatorIndex = IndexOfUnquotedChar(str, separator, nextEntryIndex);
|
separatorIndex = IndexOfUnquotedChar(str, separator, nextEntryIndex);
|
||||||
}
|
}
|
||||||
result.Add(str.Substring(nextEntryIndex));
|
string lastEntry = str.Substring(nextEntryIndex);
|
||||||
|
if (options != StringSplitOptions.RemoveEmptyEntries || lastEntry != String.Empty)
|
||||||
|
{
|
||||||
|
result.Add(lastEntry);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
51
Utilities/Threading/CountdownLatch.cs
Normal file
51
Utilities/Threading/CountdownLatch.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Utilities
|
||||||
|
{
|
||||||
|
public class CountdownLatch
|
||||||
|
{
|
||||||
|
private int m_count;
|
||||||
|
private EventWaitHandle m_waitHandle = new EventWaitHandle(true, EventResetMode.ManualReset);
|
||||||
|
|
||||||
|
public CountdownLatch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Increment()
|
||||||
|
{
|
||||||
|
int count = Interlocked.Increment(ref m_count);
|
||||||
|
if (count == 1)
|
||||||
|
{
|
||||||
|
m_waitHandle.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(int value)
|
||||||
|
{
|
||||||
|
int count = Interlocked.Add(ref m_count, value);
|
||||||
|
if (count == value)
|
||||||
|
{
|
||||||
|
m_waitHandle.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Decrement()
|
||||||
|
{
|
||||||
|
int count = Interlocked.Decrement(ref m_count);
|
||||||
|
if (m_count == 0)
|
||||||
|
{
|
||||||
|
m_waitHandle.Set();
|
||||||
|
}
|
||||||
|
else if (count < 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Count must be greater than or equal to 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WaitUntilZero()
|
||||||
|
{
|
||||||
|
m_waitHandle.WaitOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,13 +42,16 @@
|
||||||
<Compile Include="Conversion\Conversion.SimpleTypes.cs" />
|
<Compile Include="Conversion\Conversion.SimpleTypes.cs" />
|
||||||
<Compile Include="Conversion\LittleEndianConverter.cs" />
|
<Compile Include="Conversion\LittleEndianConverter.cs" />
|
||||||
<Compile Include="Cryptography\CRC32.cs" />
|
<Compile Include="Cryptography\CRC32.cs" />
|
||||||
|
<Compile Include="Generics\BlockingQueue.cs" />
|
||||||
<Compile Include="Generics\KeyValuePairList.cs" />
|
<Compile Include="Generics\KeyValuePairList.cs" />
|
||||||
<Compile Include="Generics\Map.cs" />
|
<Compile Include="Generics\Map.cs" />
|
||||||
|
<Compile Include="Generics\SortedList.cs" />
|
||||||
<Compile Include="IFileSystem\FileSystem.cs" />
|
<Compile Include="IFileSystem\FileSystem.cs" />
|
||||||
<Compile Include="IFileSystem\FileSystemEntry.cs" />
|
<Compile Include="IFileSystem\FileSystemEntry.cs" />
|
||||||
<Compile Include="IFileSystem\IFileSystem.cs" />
|
<Compile Include="IFileSystem\IFileSystem.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Strings\QuotedStringUtils.cs" />
|
<Compile Include="Strings\QuotedStringUtils.cs" />
|
||||||
|
<Compile Include="Threading\CountdownLatch.cs" />
|
||||||
<Compile Include="Threading\Parallel.cs" />
|
<Compile Include="Threading\Parallel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
|
Loading…
Add table
Reference in a new issue