-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathTextFileSignature.cs
More file actions
107 lines (67 loc) · 3.29 KB
/
TextFileSignature.cs
File metadata and controls
107 lines (67 loc) · 3.29 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
using System;
using System.IO;
using System.Linq;
using System.Text;
namespace Gsemac.IO {
public sealed class TextFileSignature :
FileSignature {
// Public members
public TextFileSignature(string signature) :
this(signature, FileSignatureOptions.Default) {
}
public TextFileSignature(string signature, FileSignatureOptions options) :
this(signature, DefaultEncoding, options) {
}
public TextFileSignature(string signature, Encoding encoding) :
this(signature, encoding, FileSignatureOptions.Default) {
}
public TextFileSignature(string signature, Encoding encoding, FileSignatureOptions options) :
base(GetSignatureBytes(signature, encoding, options)) {
if (encoding is null)
throw new ArgumentNullException(nameof(encoding));
this.signature = signature;
this.encoding = encoding;
this.options = options;
}
public override bool IsMatch(Stream stream) {
// Skip all whitespace in the stream before attempting to find a match.
// TODO: Detect UTF8 encoding from BOM
using (TextReader reader = new UnbufferedStreamReader(stream, encoding)) {
int nextChar;
do {
nextChar = reader.Read();
if (nextChar != -1 && (!options.HasFlag(FileSignatureOptions.IgnoreLeadingWhiteSpace) || !char.IsWhiteSpace((char)nextChar))) {
// We've detected a non-whitespace character, so begin the comparison.
foreach (char signatureChar in signature) {
if (nextChar < 0)
return false;
if (options.HasFlag(FileSignatureOptions.CaseInsensitive))
nextChar = char.ToLowerInvariant((char)nextChar);
if (signatureChar != nextChar)
return false;
nextChar = stream.ReadByte();
}
// If we got here, we reached the end of the signature and found a match.
return true;
}
} while (nextChar != -1);
// If we get here, we reached the end of the stream and found nothing but whitespace.
return false;
}
}
// Private members
private readonly string signature;
private readonly Encoding encoding = DefaultEncoding;
private readonly FileSignatureOptions options = FileSignatureOptions.Default;
private static readonly Encoding DefaultEncoding = Encoding.UTF8;
private static byte?[] GetSignatureBytes(string signature, Encoding encoding, FileSignatureOptions options) {
if (encoding is null)
throw new ArgumentNullException(nameof(encoding));
if (string.IsNullOrEmpty(signature))
return Enumerable.Empty<byte?>().ToArray();
if (options.HasFlag(FileSignatureOptions.CaseInsensitive))
signature = signature.ToLowerInvariant();
return encoding.GetBytes(signature).Cast<byte?>().ToArray();
}
}
}