using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace ClosedXML_Tests
{
///
/// Help methods for work with streams
///
public static class StreamHelper
{
///
/// Convert stream to byte array
///
/// Stream
/// Byte array
public static byte[] StreamToArray(Stream pStream)
{
long iLength = pStream.Length;
var bytes = new byte[iLength];
for (int i = 0; i < iLength; i++)
{
bytes[i] = (byte)pStream.ReadByte();
}
pStream.Close();
return bytes;
}
///
/// Convert byte array to stream
///
/// Byte array
/// Open stream
///
public static Stream ArrayToStreamAppend(byte[] pBynaryArray, Stream pStream)
{
#region Check params
if (ReferenceEquals(pBynaryArray, null))
{
throw new ArgumentNullException("pBynaryArray");
}
if (ReferenceEquals(pStream, null))
{
throw new ArgumentNullException("pStream");
}
if (!pStream.CanWrite)
{
throw new ArgumentException("Can't write to stream", "pStream");
}
#endregion Check params
foreach (byte b in pBynaryArray)
{
pStream.WriteByte(b);
}
return pStream;
}
public static void StreamToStreamAppend(Stream streamIn, Stream streamToWrite)
{
StreamToStreamAppend(streamIn, streamToWrite, 0);
}
public static void StreamToStreamAppend(Stream streamIn, Stream streamToWrite, long dataLength)
{
#region Check params
if (ReferenceEquals(streamIn, null))
{
throw new ArgumentNullException("streamIn");
}
if (ReferenceEquals(streamToWrite, null))
{
throw new ArgumentNullException("streamToWrite");
}
if (!streamIn.CanRead)
{
throw new ArgumentException("Can't read from stream", "streamIn");
}
if (!streamToWrite.CanWrite)
{
throw new ArgumentException("Can't write to stream", "streamToWrite");
}
#endregion Check params
var buf = new byte[512];
long length;
if (dataLength == 0)
{
length = streamIn.Length - streamIn.Position;
}
else
{
length = dataLength;
}
long rest = length;
while (rest > 0)
{
int len1 = streamIn.Read(buf, 0, rest >= 512 ? 512 : (int)rest);
streamToWrite.Write(buf, 0, len1);
rest -= len1;
}
}
///
/// Compare two streams by converting them to strings and comparing the strings
///
///
///
/// ///
///
public static bool Compare(Tuple tuple1, Tuple tuple2, bool stripColumnWidths)
{
#region Check
if (tuple1 == null || tuple1.Item1 == null || tuple1.Item2 == null)
{
throw new ArgumentNullException("one");
}
if (tuple2 == null || tuple2.Item1 == null || tuple2.Item2 == null)
{
throw new ArgumentNullException("other");
}
if (tuple1.Item2.Position != 0)
{
throw new ArgumentException("Must be in position 0", "one");
}
if (tuple2.Item2.Position != 0)
{
throw new ArgumentException("Must be in position 0", "other");
}
#endregion Check
var stringOne = new StreamReader(tuple1.Item2).ReadToEnd().RemoveIgnoredParts(tuple1.Item1, stripColumnWidths, ignoreGuids: true);
var stringOther = new StreamReader(tuple2.Item2).ReadToEnd().RemoveIgnoredParts(tuple2.Item1, stripColumnWidths, ignoreGuids: true);
return stringOne == stringOther;
}
private static string RemoveIgnoredParts(this string s, Uri uri, Boolean ignoreColumnWidths, Boolean ignoreGuids)
{
foreach (var pair in uriSpecificIgnores.Where(p => p.Key.Equals(uri.OriginalString)))
s = pair.Value.Replace(s, "");
// Collapse empty xml elements
s = emptyXmlElementRegex.Replace(s, "<$1 />");
if (ignoreColumnWidths)
s = RemoveColumnWidths(s);
if (ignoreGuids)
s = RemoveGuids(s);
return s;
}
private static IEnumerable> uriSpecificIgnores = new List>()
{
// Remove dcterms elements
new KeyValuePair("/docProps/core.xml", new Regex(@"", RegexOptions.Compiled))
};
private static Regex emptyXmlElementRegex = new Regex(@"<([\w:]+)><\/\1>", RegexOptions.Compiled);
private static Regex columnRegex = new Regex("", RegexOptions.Compiled);
private static Regex widthRegex = new Regex("width=\"\\d+(\\.\\d+)?\"\\s+", RegexOptions.Compiled);
private static String RemoveColumnWidths(String s)
{
var replacements = new Dictionary();
foreach (var m in columnRegex.Matches(s).OfType())
{
var original = m.Groups[0].Value;
var replacement = widthRegex.Replace(original, "");
replacements.Add(original, replacement);
}
foreach (var r in replacements)
{
s = s.Replace(r.Key, r.Value);
}
return s;
}
private static Regex guidRegex = new Regex(@"{[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}}", RegexOptions.Compiled | RegexOptions.Multiline);
private static String RemoveGuids(String s)
{
return guidRegex.Replace(s, delegate (Match m)
{
return string.Empty;
});
}
}
}