forked from ahzf/CsQuery
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptParser.cs
More file actions
244 lines (199 loc) · 7.01 KB
/
Copy pathScriptParser.cs
File metadata and controls
244 lines (199 loc) · 7.01 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.Cryptography;
namespace CsQuery.Mvc.ClientScript
{
class ScriptParser: IDisposable
{
#region constructor
public ScriptParser(ScriptEnvironment scriptEnvironment,string fileName)
{
ScriptEnvironment = scriptEnvironment;
FileName = fileName;
}
#endregion
#region private properties
private ScriptEnvironment ScriptEnvironment;
private TextReader StreamReader;
private string _FileName;
/// <summary>
/// When true the parser is currently in a multilinecomment
/// </summary>
private bool InMultilineComment;
/// <summary>
/// Gets or sets a value indicating whether the last read line is a comment.
/// </summary>
///
/// <value>
/// false if there are embedded comments inside code in a line, or no comment, and true only when
/// the entire line is a commment.
/// </value>
public bool InComment;
#endregion
#region public properties
/// <summary>
/// When true, this script represents a physical file in the filesystem. If false, it is either
/// invalid, or resolved in another way.
/// </summary>
public bool IsPhysicalFile { get; protected set; }
/// <summary>
/// The full text of the file
/// </summary>
public string FileData {get; protected set;}
/// <summary>
/// SHA1 has for the file data
/// </summary>
public string FileHash
{
get
{
return GetMD5Hash(FileData);
}
}
public string FileName {
get {
return _FileName;
}
protected set {
string fileName = GetJustFilePath(value);
IsPhysicalFile = !ScriptEnvironment.IsUrl(fileName)
&& ScriptEnvironment.IsValidFileName(fileName)
&& File.Exists(ScriptEnvironment.MapPath(fileName));
if (IsPhysicalFile)
{
FilePath = ScriptEnvironment.MapPath(fileName);
}
_FileName = fileName;
if (IsPhysicalFile)
{
FileData = File.ReadAllText(FilePath);
StreamReader = new StringReader(FileData);
}
}
}
public string FilePath
{
get;
protected set;
}
/// <summary>
/// When true, indicates that non-whitespace, non-code lines have been parsed already.
/// </summary>
///
/// <value>
/// true if code has been found yet.
/// </value>
public bool AnyCodeYet { get; protected set; }
#endregion
#region public methods
/// <summary>
/// Reads the next line from the file, stripping out comment markers (instead, setting the "InComment" property)
/// and setting properties based on the contents of the line.
/// </summary>
///
/// <returns>
/// The line.
/// </returns>
public string ReadLine()
{
string line= StreamReader.ReadLine();
if (line != null)
{
if (InMultilineComment)
{
Match endComment = Patterns.EndComment.Match(line);
if (endComment.Success)
{
InMultilineComment = false;
InComment = false;
line = endComment.Groups["comment"].Value;
}
}
else
{
bool isFullLineComment = false;
Match singleLineComment = Patterns.FullLineComment.Match(line);
bool isSingleLineComment = singleLineComment.Success;
Match fullLineComment = null;
bool isStartComment = false;
Match startComment = null;
if (!InMultilineComment) {
if (!isSingleLineComment)
{
fullLineComment = Patterns.FullLineComment.Match(line);
isFullLineComment = fullLineComment.Success;
}
if (!isSingleLineComment && !isFullLineComment)
{
startComment = Patterns.StartComment.Match(line);
isStartComment = startComment.Success;
}
}
// set comment status flags
if (!isFullLineComment && isStartComment)
{
InMultilineComment = true;
InComment = true;
line = startComment.Groups["comment"].Value;
}
else if (isFullLineComment)
{
InComment = true;
line = fullLineComment.Groups["comment"].Value;
} else if (isSingleLineComment) {
InComment = true;
line = singleLineComment.Groups["comment"].Value;
}
else if (!AnyCodeYet && !Patterns.WhiteSpace.IsMatch(line))
{
AnyCodeYet = true;
}
}
}
return line;
}
#endregion
#region private methods
private string GetJustFilePath(string path)
{
int qPos = path.IndexOf("?");
return qPos < 0 ?
path :
path.Substring(0, qPos);
}
/// <summary>
/// Calculate an MD5 hash for the string
/// </summary>
///
/// <param name="input">
/// String to hash
/// </param>
///
/// <returns>
/// The hash
/// </returns>
private string GetMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
void IDisposable.Dispose()
{
StreamReader.Dispose();
}
#endregion
}
}