OSDN Git Service

5eb79520bf58d47600528a330af1232da8a24f8f
[handbrake-jp/handbrake-jp-git.git] / win / C# / Parsing / Parser.cs
1 /*  Parser.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake.Parsing\r
7 {\r
8     using System;\r
9     using System.Globalization;\r
10     using System.IO;\r
11     using System.Text;\r
12     using System.Text.RegularExpressions;\r
13 \r
14     /// <summary>\r
15     /// A delegate to handle custom events regarding data being parsed from the buffer\r
16     /// </summary>\r
17     /// <param name="sender">The object which raised this delegate</param>\r
18     /// <param name="data">The data parsed from the stream</param>\r
19     public delegate void DataReadEventHandler(object sender, string data);\r
20 \r
21     /// <summary>\r
22     /// A delegate to handle events regarding progress during DVD scanning\r
23     /// </summary>\r
24     /// <param name="sender">The object who's raising the event</param>\r
25     /// <param name="currentTitle">The title number currently being processed</param>\r
26     /// <param name="titleCount">The total number of titiles to be processed</param>\r
27     public delegate void ScanProgressEventHandler(object sender, int currentTitle, int titleCount);\r
28 \r
29     /// <summary>\r
30     /// A delegate to handle encode progress updates // EXPERIMENTAL\r
31     /// </summary>\r
32     /// <param name="sender">The object which raised the event</param>\r
33     /// <param name="currentTask">The current task being processed from the queue</param>\r
34     /// <param name="taskCount">The total number of tasks in queue</param>\r
35     /// <param name="percentComplete">The percentage this task is complete</param>\r
36     /// <param name="currentFps">The current encoding fps</param>\r
37     /// <param name="averageFps">The average encoding fps for this task</param>\r
38     /// <param name="timeRemaining">The estimated time remaining for this task to complete</param>\r
39     public delegate void EncodeProgressEventHandler(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float averageFps, TimeSpan timeRemaining);\r
40 \r
41     /// <summary>\r
42     /// A simple wrapper around a StreamReader to keep track of the entire output from a cli process\r
43     /// </summary>\r
44     internal class Parser : StreamReader\r
45     {\r
46         /// <summary>\r
47         /// The Buffer StringBuilder\r
48         /// </summary>\r
49         private readonly StringBuilder buffer = new StringBuilder(string.Empty);\r
50 \r
51         /// <summary>\r
52         /// Initializes a new instance of the <see cref="Parser"/> class. \r
53         /// Default constructor for this object\r
54         /// </summary>\r
55         /// <param name="baseStream">\r
56         /// The stream to parse from\r
57         /// </param>\r
58         public Parser(Stream baseStream) : base(baseStream)\r
59         {\r
60         }\r
61 \r
62         /// <summary>\r
63         /// Raised upon a new line being read from stdout/stderr\r
64         /// </summary>\r
65         public event DataReadEventHandler OnReadLine;\r
66 \r
67         /// <summary>\r
68         /// Raised upon the entire stdout/stderr stream being read in a single call\r
69         /// </summary>\r
70         public event DataReadEventHandler OnReadToEnd;\r
71 \r
72         /// <summary>\r
73         /// Raised upon the catching of a "Scanning title # of #..." in the stream\r
74         /// </summary>\r
75         public event ScanProgressEventHandler OnScanProgress;\r
76 \r
77         /// <summary>\r
78         /// Raised upon the catching of a "Scanning title # of #..." in the stream\r
79         /// </summary>\r
80         public event EncodeProgressEventHandler OnEncodeProgress;\r
81 \r
82         /// <summary>\r
83         /// Gets the buffer of data that came from the CLI standard input/error\r
84         /// </summary>\r
85         public StringBuilder Buffer\r
86         {\r
87             get { return buffer; }\r
88         }\r
89 \r
90         /// <summary>\r
91         /// Read a line from standard in/err\r
92         /// </summary>\r
93         /// <returns>\r
94         /// The read line\r
95         /// </returns>\r
96         public override string ReadLine()\r
97         {\r
98             string tmp = base.ReadLine();\r
99 \r
100             buffer.Append(tmp + Environment.NewLine);\r
101 \r
102             Match m = null;\r
103             if (tmp.Contains("Scanning title"))\r
104                 m = Regex.Match(tmp, "^Scanning title ([0-9]*) of ([0-9]*)");\r
105 \r
106             if (OnReadLine != null)\r
107                 OnReadLine(this, tmp);\r
108 \r
109             if (m != null)\r
110                 if (m.Success && OnScanProgress != null)\r
111                     OnScanProgress(this, int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
112 \r
113             return tmp;\r
114         }\r
115 \r
116         /// <summary>\r
117         /// Read to the end of the input stream\r
118         /// </summary>\r
119         /// <returns>\r
120         /// A string of the input data\r
121         /// </returns>\r
122         public override string ReadToEnd()\r
123         {\r
124             string tmp = base.ReadToEnd();\r
125 \r
126             buffer.Append(tmp + Environment.NewLine);\r
127 \r
128             if (OnReadToEnd != null)\r
129                 OnReadToEnd(this, tmp);\r
130 \r
131             return tmp;\r
132         }\r
133 \r
134         /// <summary>\r
135         /// Pase the CLI status output (from standard output)\r
136         /// </summary>\r
137         public void ReadEncodeStatus()\r
138         {\r
139             CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");\r
140             string tmp = base.ReadLine();\r
141 \r
142             Match m = Regex.Match(tmp, @"^Encoding: task ([0-9]*) of ([0-9]*), ([0-9]*\.[0-9]*) %( \(([0-9]*\.[0-9]*) fps, avg ([0-9]*\.[0-9]*) fps, ETA ([0-9]{2})h([0-9]{2})m([0-9]{2})s\))?");\r
143             if (m.Success && OnEncodeProgress != null)\r
144             {\r
145                 int currentTask = int.Parse(m.Groups[1].Value);\r
146                 int totalTasks = int.Parse(m.Groups[2].Value);\r
147                 float percent = float.Parse(m.Groups[3].Value, culture);\r
148                 float currentFps = m.Groups[5].Value == string.Empty ? 0.0F : float.Parse(m.Groups[5].Value, culture);\r
149                 float avgFps = m.Groups[6].Value == string.Empty ? 0.0F : float.Parse(m.Groups[6].Value, culture);\r
150                 TimeSpan remaining = TimeSpan.Zero;\r
151                 if (m.Groups[7].Value != string.Empty)\r
152                 {\r
153                     remaining = TimeSpan.Parse(m.Groups[7].Value + ":" + m.Groups[8].Value + ":" + m.Groups[9].Value);\r
154                 }\r
155                 OnEncodeProgress(this, currentTask, totalTasks, percent, currentFps, avgFps, remaining);\r
156             }\r
157         }\r
158     }\r
159 }