-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathFileFormatFactoryExtensions.cs
More file actions
116 lines (67 loc) · 3.73 KB
/
FileFormatFactoryExtensions.cs
File metadata and controls
116 lines (67 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.IO;
namespace Gsemac.IO {
public static class FileFormatFactoryExtensions {
// Public members
public static IFileFormat FromFile(this IFileFormatFactory fileFormatFactory, string filePath) {
if (fileFormatFactory is null)
throw new ArgumentNullException(nameof(fileFormatFactory));
if (File.Exists(filePath)) {
using (Stream stream = File.OpenRead(filePath))
return fileFormatFactory.FromStream(stream) ?? fileFormatFactory.FromFileExtension(filePath);
}
else {
return fileFormatFactory.FromFileExtension(filePath);
}
}
public static IFileFormat FromMimeType(this IFileFormatFactory fileFormatFactory, string mimeType) {
if (fileFormatFactory is null)
throw new ArgumentNullException(nameof(fileFormatFactory));
return fileFormatFactory.FromMimeType(new MimeType(mimeType));
}
public static IFileFormat FromStream(this IFileFormatFactory fileFormatFactory, Stream stream) {
if (fileFormatFactory is null)
throw new ArgumentNullException(nameof(fileFormatFactory));
if (stream is null)
throw new ArgumentNullException(nameof(stream));
return fileFormatFactory.FromStream(stream, FileFormatFactory.DefaultReadBufferSize);
}
public static Stream FromStream(this IFileFormatFactory fileFormatFactory, Stream stream, out IFileFormat fileFormat) {
if (fileFormatFactory is null)
throw new ArgumentNullException(nameof(fileFormatFactory));
if (stream is null)
throw new ArgumentNullException(nameof(stream));
return fileFormatFactory.FromStream(stream, bufferSize: FileFormatFactory.DefaultReadBufferSize, out fileFormat);
}
public static Stream FromStream(this IFileFormatFactory fileFormatFactory, Stream stream, int bufferSize, out IFileFormat fileFormat) {
if (fileFormatFactory is null)
throw new ArgumentNullException(nameof(fileFormatFactory));
if (stream is null)
throw new ArgumentNullException(nameof(stream));
if (stream.CanSeek) {
// If the stream is seekable, we can read directly from the stream and then seek back.
long initialPosition = stream.Position;
fileFormat = fileFormatFactory.FromStream(stream);
stream.Seek(initialPosition, SeekOrigin.Begin);
return stream;
}
else {
// Read the file signature from the stream into a buffer, which is then concatenated with the original stream.
// This allows us to read the file signature from streams that don't support seeking.
MemoryStream fileSignatureBuffer = new MemoryStream(new byte[bufferSize], 0, count: bufferSize, writable: true, publiclyVisible: true);
try {
int bytesRead = stream.Read(fileSignatureBuffer.GetBuffer(), 0, FileFormatFactory.DefaultReadBufferSize);
fileSignatureBuffer.SetLength(bytesRead);
fileFormat = fileFormatFactory.FromStream(fileSignatureBuffer);
fileSignatureBuffer.Seek(0, SeekOrigin.Begin);
return new ConcatStream(fileSignatureBuffer, stream);
}
catch (Exception) {
// The buffer is ONLY disposed if we fail to return a ConcatStream instance.
fileSignatureBuffer.Dispose();
throw;
}
}
}
}
}