-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cs
162 lines (132 loc) · 4.37 KB
/
main.cs
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
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
namespace Bakera.RedFace{
public class App{
private EventLevel myEventLevel = EventLevel.Information;
private EventLevel EventLevel{
get{return myEventLevel;}
set{myEventLevel = value;}
}
private NameValueCollection myArgs = new NameValueCollection();
private string myTargetPath = null;
public static int Main(string[] args){
try{
App app = new App();
app.ParseArgs(args);
return app.Execute(args);
} catch(Exception e){
Console.WriteLine(e);
return 1;
}
}
private int ParseFromUri(string uri){
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AllowAutoRedirect = false;
request.UserAgent = "RedFace/0.1";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
RedFaceParser p = new RedFaceParser();
p.ParserEventRaised += WriteEvent;
string charsetName = EncodingSniffer.ExtractEncodingNameFromMetaElement(response.ContentType);
if(!string.IsNullOrEmpty(charsetName)){
Console.WriteLine("HTTP応答ヘッダで文字符号化方式が指定されています。: {0}", charsetName);
p.SetForceEncoding(charsetName);
}
using(Stream data = response.GetResponseStream()){
p.Parse(data);
}
PrintResult(p);
return 0;
}
private int ParseFromFile(string path){
FileInfo file = new FileInfo(path);
if(file.Exists){
return ParseFromFile(file);
}
DirectoryInfo dir = new DirectoryInfo(path);
if(dir.Exists){
return ParseFromDirectory(dir);
}
Console.WriteLine("指定されたファイルがみつかりませんでした: {0}", file.FullName);
return 1;
}
private int ParseFromFile(FileInfo file){
Console.WriteLine("ファイル: <{0}> をパースします。", file.FullName);
RedFaceParser p = new RedFaceParser();
p.ParserEventRaised += WriteEvent;
using(FileStream fs = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)){
p.Parse(fs);
}
PrintResult(p);
return 0;
}
private int ParseFromDirectory(DirectoryInfo dir){
foreach(DirectoryInfo subdir in dir.GetDirectories()){
ParseFromDirectory(subdir);
}
foreach(FileInfo file in dir.GetFiles()){
ParseFromFile(file);
}
return 0;
}
private int Execute(string[] args){
if(myTargetPath == null){
Console.WriteLine("対象のファイル名もしくはURLを指定してください。");
return 1;
}
if(myTargetPath.StartsWith("http://") || myTargetPath.StartsWith("https://")){
return ParseFromUri(myTargetPath);
} else {
return ParseFromFile(myTargetPath);
}
}
private void PrintResult(RedFaceParser p){
var logs = p.GetLogs();
foreach(ParserLog log in logs){
Console.WriteLine("{0}行{1}文字: {2}", log.Line.Number, log.ColumnNumber, log.Message);
Console.WriteLine(" {0}", log.Line.Data);
}
Console.WriteLine("パース開始: {0}", p.StartTime);
Console.WriteLine("パース終了: {0}", p.EndTime);
Console.WriteLine("パース時間: {0}", p.EndTime - p.StartTime);
Console.WriteLine();
Console.WriteLine("========");
// Console.WriteLine(p.Document.OuterXml);
}
public void WriteEvent(Object sender, ParserEventArgs e){
if(e.Level >= myEventLevel){
Console.Write("[{0}] ", e.Level);
Console.Write("({0}) ", e.Message.GetType().Name);
if(!string.IsNullOrEmpty(e.Message.Message)) Console.WriteLine(e.Message.Message);
if(sender is RedFaceParser && e.Level > EventLevel.Information){
if(e.OriginalSender != null){
Console.WriteLine(" {0}:", e.OriginalSender.GetType().Name);
}
RedFaceParser parser = (RedFaceParser)sender;
Console.Write(" {0}", parser.InputStream.GetRecentString(40));
string allstr = parser.InputStream.GetAllString();
string[] lines = allstr.Split('\n');
Console.Write(" ({0}行目", lines.Length);
Console.Write(" {0}文字目)", lines[lines.Length-1].Length);
Console.WriteLine();
}
}
}
// コマンドライン引数を解析してNameValueCollectionに格納します。
private void ParseArgs(string[] args){
for(int i=0; i < args.Length; i++){
string argName = args[i];
if(argName.StartsWith("-")){
if(argName == "-v"){
this.EventLevel = EventLevel.Verbose;
}
} else {
myTargetPath = argName;
}
}
}
}
}