diff --git a/src/Mime-Detective/Extensions/ByteArrayExtensions.cs b/src/Mime-Detective/Extensions/ByteArrayExtensions.cs
index a76227f..5553404 100644
--- a/src/Mime-Detective/Extensions/ByteArrayExtensions.cs
+++ b/src/Mime-Detective/Extensions/ByteArrayExtensions.cs
@@ -10,15 +10,15 @@ public static class ByteArrayExtensions
///
/// Read header of bytes and depending on the information in the header
/// return object FileType.
- /// Return null in case when the file type is not identified.
+ /// Return null in case when the file type is not identified.
/// Throws Application exception if the file can not be read or does not exist
///
///
/// A temp file is written to get a FileInfo from the given bytes.
- /// If this is not intended use
- ///
- /// GetFileType(() => bytes);
- ///
+ /// If this is not intended use
+ ///
+ /// GetFileType(() => bytes);
+ ///
///
/// The FileInfo object.
/// FileType or null not identified
@@ -26,6 +26,5 @@ public static FileType GetFileType(this byte[] bytes)
{
return MimeTypes.GetFileType(() => MimeTypes.ReadHeaderFromByteArray(bytes, MimeTypes.MaxHeaderSize), null, bytes);
}
-
}
}
diff --git a/src/Mime-Detective/Extensions/StreamExtensions.cs b/src/Mime-Detective/Extensions/StreamExtensions.cs
index 01e7bda..0438a90 100644
--- a/src/Mime-Detective/Extensions/StreamExtensions.cs
+++ b/src/Mime-Detective/Extensions/StreamExtensions.cs
@@ -14,7 +14,7 @@ public static class StreamExtensions
///
/// Read header of a stream and depending on the information in the header
/// return object FileType.
- /// Return null in case when the file type is not identified.
+ /// Return null in case when the file type is not identified.
/// Throws Application exception if the file can not be read or does not exist
///
/// The FileInfo object.
@@ -28,7 +28,7 @@ public static FileType GetFileType(this Stream stream)
///
/// Read header of a stream and depending on the information in the header
/// return object FileType.
- /// Return null in case when the file type is not identified.
+ /// Return null in case when the file type is not identified.
/// Throws Application exception if the file can not be read or does not exist
///
/// The FileInfo object.
@@ -42,7 +42,7 @@ public static Task GetFileTypeAsync(this Stream stream)
///
/// Read header of a stream and depending on the information in the header
/// return object FileType.
- /// Return null in case when the file type is not identified.
+ /// Return null in case when the file type is not identified.
/// Throws Application exception if the file can not be read or does not exist
///
/// The FileInfo object.
diff --git a/src/Mime-Detective/FileType.cs b/src/Mime-Detective/FileType.cs
index bad19b6..73a3a3a 100644
--- a/src/Mime-Detective/FileType.cs
+++ b/src/Mime-Detective/FileType.cs
@@ -2,28 +2,12 @@
namespace MimeDetective
{
- /*
- public struct FileDetectionResult
- {
- public readonly FileType FileType;
-
- public readonly bool WasFileTypeDetected;
-
- public FileDetectionResult(bool wasFileTypeDetected, FileType fileType)
- {
- FileType = fileType;
-
- WasFileTypeDetected = wasFileTypeDetected;
- }
- }
- */
-
///
/// Little data structure to hold information about file types.
/// Holds information about binary header at the start of the file
/// these are mostly static they can be structs
///
- public struct FileType
+ public class FileType
{
public byte?[] Header { get; }
public ushort HeaderOffset { get; }
@@ -42,7 +26,7 @@ public FileType(byte?[] header, string extension, string mime, ushort offset = 0
{
//header cannot be null, file type normal operation requires the data
if (header == null)
- throw new ArgumentNullException(nameof(header), "cannot be null file type needs file header data");
+ throw new ArgumentNullException(nameof(header), "cannot be null, FileType needs file header data");
Header = header;
HeaderOffset = offset;
diff --git a/src/Mime-Detective/MimeDetective.cs b/src/Mime-Detective/MimeDetective.cs
index 6586979..f83fccc 100644
--- a/src/Mime-Detective/MimeDetective.cs
+++ b/src/Mime-Detective/MimeDetective.cs
@@ -43,7 +43,7 @@ public static FileType LearnMimeType(FileInfo file, string mimeType, int headerS
return new FileType(data, file.Extension, mimeType, offset);
}
- public static FileType? LearnMimeType(FileInfo first, FileInfo second, string mimeType, int maxHeaderSize = 12, int minMatches = 2, int maxNonMatch = 3)
+ public static FileType LearnMimeType(FileInfo first, FileInfo second, string mimeType, int maxHeaderSize = 12, int minMatches = 2, int maxNonMatch = 3)
{
byte?[] header = null;
diff --git a/src/Mime-Detective/MimeTypes.cs b/src/Mime-Detective/MimeTypes.cs
index c2a0ca6..7d30e12 100644
--- a/src/Mime-Detective/MimeTypes.cs
+++ b/src/Mime-Detective/MimeTypes.cs
@@ -209,7 +209,6 @@ EML is also used by Outlook Express and QuickMail.
#region Main Methods
- /*
public static void SaveToXmlFile(string path)
{
using (FileStream file = File.OpenWrite(path))
@@ -226,15 +225,8 @@ public static FileType[] LoadFromXmlFile(string path)
var serializer = new System.Xml.Serialization.XmlSerializer(Types.GetType());
return (FileType[])serializer.Deserialize(file);
-
- //int typeOrgLenth = Types.Length;
-
- //Array.Resize(ref Types, Types.Length + tmpTypes.Length);
-
- //Array.Copy(tmpTypes, 0, Types, typeOrgLenth, tmpTypes.Length);
}
}
- */
/*
public static FileType GetFileType(FileInfo file)
@@ -247,7 +239,6 @@ public static FileType GetFileType(FileInfo file)
/// Read header of a file and depending on the information in the header
/// return object FileType.
/// Return null in case when the file type is not identified.
- /// Throws Application exception if the file can not be read or does not exist
///
/// A function which returns the bytes found
/// If given and file typ is a zip file, a check for docx and xlsx is done
@@ -294,13 +285,13 @@ private static FileType getFileType(IReadOnlyList fileHeader, Stream strea
var officeXml = CheckForDocxAndXlsxStream(zipData);
if (officeXml != null)
- return officeXml.Value;
+ return officeXml;
//check for open office formats
var openOffice = CheckForOdtAndOds(zipData);
if (openOffice != null)
- return openOffice.Value;
+ return openOffice;
}
}
}
@@ -311,7 +302,8 @@ private static FileType getFileType(IReadOnlyList fileHeader, Stream strea
}
}
- throw new Exception("No file type match found");
+ //no match return null
+ return null;
}
///
@@ -333,7 +325,7 @@ public static List GetFileTypesByExtensions(string CSV)
return result;
}
- private static FileType? CheckForDocxAndXlsxStream(ZipArchive zipData)
+ private static FileType CheckForDocxAndXlsxStream(ZipArchive zipData)
{
if (zipData.Entries.Any(e => e.FullName.StartsWith("word/")))
return WORDX;
@@ -365,7 +357,7 @@ private static FileType CheckForDocxAndXlsx(FileType type, FileInfo fileInfo)
*/
//check for open doc formats
- private static FileType? CheckForOdtAndOds(ZipArchive zipFile)
+ private static FileType CheckForOdtAndOds(ZipArchive zipFile)
{
var ooMimeType = zipFile.Entries.FirstOrDefault(e => e.FullName == "mimetype");
@@ -431,7 +423,7 @@ internal static IReadOnlyList ReadFileHeader(FileInfo file, ushort MaxHead
}
catch (Exception e) // file could not be found/read
{
- throw new Exception($"Could not read file: {e.Message}");
+ throw new System.IO.IOException($"Could not read {nameof(file)}", e);
}
return header;
@@ -454,7 +446,7 @@ internal static async Task> ReadFileHeaderAsync(FileInfo fil
}
catch (Exception e) // file could not be found/read
{
- throw new System.IO.FileLoadException($"Could not read file: {e.Message}", file.FullName, e);
+ throw new System.IO.IOException($"Could not read {nameof(file)}", e);
}
return header;
@@ -470,8 +462,6 @@ internal static IReadOnlyList ReadHeaderFromStream(Stream stream, ushort M
{
byte[] header = new byte[MaxHeaderSize];
- try // read stream
- {
if (!stream.CanRead)
throw new System.IO.IOException("Could not read from Stream");
@@ -479,11 +469,6 @@ internal static IReadOnlyList ReadHeaderFromStream(Stream stream, ushort M
stream.Seek(0, SeekOrigin.Begin);
stream.Read(header, 0, MaxHeaderSize);
- }
- catch (Exception e) // file could not be found/read
- {
- throw new Exception("Could not read Stream : " + e.Message);
- }
return header;
}
@@ -498,32 +483,29 @@ internal static async Task> ReadHeaderFromStreamAsync(Stream
{
byte[] header = new byte[MaxHeaderSize];
- try // read stream
- {
if (!stream.CanRead)
- throw new System.IO.IOException("Could not read from Stream");
+ throw new IOException($"Could not read from {nameof(stream)}");
if (stream.Position > 0)
stream.Seek(0, SeekOrigin.Begin);
await stream.ReadAsync(header, 0, MaxHeaderSize);
- }
- catch (Exception e) // file could not be found/read
- {
- throw new Exception("Could not read Stream : " + e.Message);
- }
return header;
}
- internal static IReadOnlyList ReadHeaderFromByteArray(byte[] byteArray, ushort MaxHeaderSize)
+ internal static IReadOnlyList ReadHeaderFromByteArray(IReadOnlyList byteArray, ushort MaxHeaderSize)
{
- if (byteArray.Length < MaxHeaderSize)
- throw new ArgumentException($"{nameof(byteArray)}:{byteArray} Is smaller than {nameof(MaxHeaderSize)}:{MaxHeaderSize}", nameof(byteArray));
+ if (byteArray.Count < MaxHeaderSize)
+ throw new ArgumentException($"{nameof(byteArray)}:{byteArray.Count} Is smaller than {nameof(MaxHeaderSize)}:{MaxHeaderSize}", nameof(byteArray));
byte[] header = new byte[MaxHeaderSize];
- Array.Copy(byteArray, header, MaxHeaderSize);
+ //Array.Copy(byteArray, header, MaxHeaderSize);
+ for (int i = 0; i < MaxHeaderSize; i++)
+ {
+ header[i] = byteArray[i];
+ }
return header;
}
diff --git a/test/Mime-Detective.Tests/Data/empty.jpg b/test/Mime-Detective.Tests/Data/empty.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/test/Mime-Detective.Tests/Tests/Documents/DocumentsTests.cs b/test/Mime-Detective.Tests/Tests/Documents/MsOfficeFormats.cs
similarity index 95%
rename from test/Mime-Detective.Tests/Tests/Documents/DocumentsTests.cs
rename to test/Mime-Detective.Tests/Tests/Documents/MsOfficeFormats.cs
index 8cf6124..a6d2862 100644
--- a/test/Mime-Detective.Tests/Tests/Documents/DocumentsTests.cs
+++ b/test/Mime-Detective.Tests/Tests/Documents/MsOfficeFormats.cs
@@ -9,7 +9,7 @@
namespace MimeDetective.Tests.Documents
{
- public class DocumentsTests
+ public class MsOfficeFormats
{
public const string DocsPath = "./Data/Documents/test.";
@@ -18,7 +18,7 @@ public async Task FileInfoDocx()
{
var info = new FileInfo(DocsPath + "docx");
- var a = System.IO.Directory.GetCurrentDirectory();
+ var a = Directory.GetCurrentDirectory();
var fileInfo = await info.GetFileTypeAsync();
diff --git a/test/Mime-Detective.Tests/Tests/FileType.cs b/test/Mime-Detective.Tests/Tests/FileType.cs
index 4b58f90..e95f4e7 100644
--- a/test/Mime-Detective.Tests/Tests/FileType.cs
+++ b/test/Mime-Detective.Tests/Tests/FileType.cs
@@ -6,14 +6,14 @@
namespace MimeDetective.Tests
{
- public class FileTypeTests
+ public class FileType
{
[Fact]
public void Constructors()
{
- var info = new FileType(new byte?[] { 0x12, 0x14, 0x13, 0x15, 0x16 }, "png", "image/png", 4);
+ var info = new global::MimeDetective.FileType(new byte?[] { 0x12, 0x14, 0x13, 0x15, 0x16 }, "png", "image/png", 4);
- Assert.Throws(typeof(ArgumentNullException), () => { var a = new FileType(null, "png", "image/png", 4); });
+ Assert.Throws(typeof(ArgumentNullException), () => { var a = new global::MimeDetective.FileType(null, "png", "image/png", 4); });
}
[Fact]
diff --git a/test/Mime-Detective.Tests/Tests/Images/IsFile.cs b/test/Mime-Detective.Tests/Tests/Images/CommonFormats.cs
similarity index 97%
rename from test/Mime-Detective.Tests/Tests/Images/IsFile.cs
rename to test/Mime-Detective.Tests/Tests/Images/CommonFormats.cs
index 7814371..a8394d1 100644
--- a/test/Mime-Detective.Tests/Tests/Images/IsFile.cs
+++ b/test/Mime-Detective.Tests/Tests/Images/CommonFormats.cs
@@ -11,9 +11,9 @@ namespace MimeDetective.Tests.Images
{
// This project can output the Class library as a NuGet Package.
// To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
- public class IsFile
+ public class CommonFormats
{
- public IsFile()
+ public CommonFormats()
{
}
diff --git a/test/Mime-Detective.Tests/Tests/Text/TextTests.cs b/test/Mime-Detective.Tests/Tests/Text/CommonFormats.cs
similarity index 100%
rename from test/Mime-Detective.Tests/Tests/Text/TextTests.cs
rename to test/Mime-Detective.Tests/Tests/Text/CommonFormats.cs
diff --git a/test/Mime-Detective.Tests/Tests/TypeExtensions.cs b/test/Mime-Detective.Tests/Tests/TypeExtensions.cs
new file mode 100644
index 0000000..4db977c
--- /dev/null
+++ b/test/Mime-Detective.Tests/Tests/TypeExtensions.cs
@@ -0,0 +1,142 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using MimeDetective.Extensions;
+using MimeDetective;
+using Xunit;
+
+namespace MimeDetective.Tests
+{
+ public class TypeExtensions
+ {
+ const string GoodFile = "./data/images/test.jpg";
+
+ const string BadFile = "./data/empty.jpg";
+
+ const string NonexistentFile = "./data/nonexistent.jpg";
+
+ //load from fileinfo
+ //attempt to load from real file
+ //attempt to load from nonexistent file /badfile
+ [Fact]
+ public async Task FromFile()
+ {
+ var fileInfo = new FileInfo(GoodFile);
+
+ var fileType = await fileInfo.GetFileTypeAsync();
+
+ Assert.True(fileType == MimeTypes.JPEG);
+ }
+
+ [Fact]
+ public void FromFileSync()
+ {
+ var fileInfo = new FileInfo(GoodFile);
+
+ Assert.True(fileInfo.IsJpeg());
+ }
+
+ //test shouldn't fail, an empty file can be valid input
+ [Fact]
+ public async Task FromEmptyFile()
+ {
+ var fileInfo = new FileInfo(BadFile);
+
+ var type = await fileInfo.GetFileTypeAsync();
+
+ //no match so return type is null
+ Assert.Null(type);
+ }
+
+ [Fact]
+ public async Task FromNonExistentFile()
+ {
+ var fileInfo = new FileInfo(NonexistentFile);
+
+ await Assert.ThrowsAnyAsync(() => fileInfo.GetFileTypeAsync());
+ }
+
+ //load from stream
+ //attempt to load from good stream
+ //attempt to load from empty stream
+
+ [Fact]
+ public async Task FromStream()
+ {
+ var fileInfo = new FileInfo(GoodFile);
+
+ using (var fileStream = fileInfo.OpenRead())
+ {
+ var fileType = await fileStream.GetFileTypeAsync();
+
+ Assert.NotNull(fileType);
+
+ Assert.Equal(MimeTypes.JPEG, fileType);
+ }
+ }
+
+ [Fact]
+ public void FromStreamSync()
+ {
+ var fileInfo = new FileInfo(GoodFile);
+
+ using (var fileStream = fileInfo.OpenRead())
+ {
+ var fileType = fileStream.GetFileType();
+
+ Assert.NotNull(fileType);
+
+ Assert.Equal(MimeTypes.JPEG, fileType);
+ }
+ }
+
+ [Fact]
+ public async Task FromEmptyStream()
+ {
+ var emptyStream = System.IO.Stream.Null;
+
+ var nullReturn = await emptyStream.GetFileTypeAsync();
+
+ Assert.Null(nullReturn);
+ }
+
+ //load from byte array
+ //load from good byte array
+ //attempt to load from empty byte array
+ [Fact]
+ public async Task FromByteArray()
+ {
+ var fileInfo = new FileInfo(GoodFile);
+
+ //560 is the max file header size
+ byte[] byteArray = new byte[560];
+
+ using (var fileStream = fileInfo.OpenRead())
+ {
+ await fileStream.ReadAsync(byteArray, 0, 560);
+ }
+
+ var mimeType = byteArray.GetFileType();
+
+ Assert.NotNull(mimeType);
+
+ Assert.Equal(MimeTypes.JPEG, mimeType);
+ }
+
+ [Fact]
+ public void FromEmptyByteArray()
+ {
+ var zerodByteArray = new byte[560];
+
+ var zerodResult = zerodByteArray.GetFileType();
+
+ Assert.Null(zerodResult);
+
+ var emptyBtyeArray = new byte[0];
+
+ Assert.ThrowsAny(() => emptyBtyeArray.GetFileType());
+ }
+ }
+}
diff --git a/test/Mime-Detective.Tests/Utilities/TypeComparisions.cs b/test/Mime-Detective.Tests/Utilities/TypeComparisions.cs
index 01a09e2..e7e4eff 100644
--- a/test/Mime-Detective.Tests/Utilities/TypeComparisions.cs
+++ b/test/Mime-Detective.Tests/Utilities/TypeComparisions.cs
@@ -1,4 +1,5 @@
using MimeDetective;
+using System;
using System.IO;
using System.Threading.Tasks;
using Xunit;
@@ -20,4 +21,15 @@ public static async Task AssertIsType(FileInfo info, FileType type)
Assert.False(info.GetFileType() != type);
}
}
+
+ /*
+ public class MyClass
+ {
+ [Fact]
+ public void test()
+ {
+ Assert.ThrowsAny(() => { TypeComparisions.AssertIsType(null, MimeTypes.AES).Wait(); });
+ }
+ }
+ */
}
\ No newline at end of file