]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/wxbutils.cpp
various updates/fixes.
[bacula/bacula] / bacula / src / wx-console / wxbutils.cpp
1 /*
2  *
3  *   wxbDataParser, class that receives and analyses data
4  *
5  *    Nicolas Boichat, April 2004
6  *
7  */
8 /*
9    Copyright (C) 2004 Kern Sibbald and John Walker
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    as published by the Free Software Foundation; either version 2
14    of the License, or (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25  
26 #include "wxbutils.h"
27
28 #include "wxbmainframe.h"
29
30 #include "csprint.h"
31
32 #include "wxbtableparser.h"
33
34 /* A macro named Yield is defined under MinGW */
35 #undef Yield
36
37 bool wxbUtils::inited = false;
38
39 /* Initialization */
40 void wxbUtils::Init() {
41    inited = true;
42 }
43
44 /* Reset state */
45 void wxbUtils::Reset() {
46    inited = false;
47 }
48
49 /* Parse a table in tableParser */
50 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
51    wxbTableParser* tableParser = new wxbTableParser();
52
53    wxbMainFrame::GetInstance()->Send(cmd);
54
55    //time_t base = wxDateTime::Now().GetTicks();
56    while (!tableParser->hasFinished()) {
57       //innerThread->Yield();
58       wxTheApp->Yield(true);
59       ::wxUsleep(100);
60       //if (base+15 < wxDateTime::Now().GetTicks()) break;
61    }
62    return tableParser;
63 }
64
65 /* Run a command, and waits until prompt result is fully received,
66  * if keepresults is true, returns a valid pointer to a wxbPromptParser
67  * containing the data. */
68 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
69    wxbPromptParser* promptParser = new wxbPromptParser();
70    
71    wxbMainFrame::GetInstance()->Send(cmd);
72     
73    //time_t base = wxDateTime::Now().GetTicks();
74    while (!promptParser->hasFinished()) {
75       //innerThread->Yield();
76       wxTheApp->Yield(true);
77       ::wxUsleep(100);
78       //if (base+15 < wxDateTime::Now().GetTicks()) break;
79    }
80      
81    if (keepresults) {
82       return promptParser;
83    }
84    else {
85       delete promptParser;
86       return NULL;
87    }  
88 }
89
90 /* Run a command, and waits until result is fully received. */
91 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
92    wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
93
94    wxbMainFrame::GetInstance()->Send(cmd);
95    
96    //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
97    
98    //time_t base = wxDateTime::Now().GetTicks();
99    while (!datatokenizer->hasFinished()) {
100       //innerThread->Yield();
101       wxTheApp->Yield(true);
102       ::wxUsleep(100);
103       //if (base+15 < wxDateTime::Now().GetTicks()) break;
104    }
105    
106    //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
107    
108    if (keepresults) {
109       return datatokenizer;
110    }
111    else {
112       delete datatokenizer;
113       return NULL;
114    }
115 }
116
117
118 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
119 wxbDataParser::wxbDataParser(bool lineanalysis) {
120    wxbMainFrame::GetInstance()->Register(this);
121    this->lineanalysis = lineanalysis;
122 //   buffer = "";
123 }
124
125 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
126 wxbDataParser::~wxbDataParser() {
127    wxbMainFrame::GetInstance()->Unregister(this);
128 }
129
130 /*
131  * Receives director information, forwarded by wxbMainFrame, and sends it
132  * line by line to the virtual function Analyse.
133  */
134 bool wxbDataParser::Print(wxString str, int status) {
135    bool ret = false;
136    if (lineanalysis) {
137       bool allnewline = true;
138       for (unsigned int i = 0; i < str.Length(); i++) {
139          if (!(allnewline = (str.GetChar(i) == '\n')))
140             break;
141       }
142    
143       if (allnewline) {
144          ret = Analyse(buffer << "\n", CS_DATA);
145          buffer = "";
146          for (unsigned int i = 1; i < str.Length(); i++) {
147             ret = Analyse("\n", status);
148          }
149       }
150       else {
151          wxStringTokenizer tkz(str, "\n", 
152             (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
153    
154          while ( tkz.HasMoreTokens() ) {
155             buffer << tkz.GetNextToken();
156             if (buffer.Length() != 0) {
157                if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
158                   (buffer.GetChar(buffer.Length()-1) == '\r')) {
159                   ret = Analyse(buffer, status);
160                   buffer = "";
161                }
162             }
163          }
164       }
165    
166       if (buffer == "$ ") { // Restore console
167          ret = Analyse(buffer, status);
168          buffer = "";
169       }
170    
171       if (status != CS_DATA) {
172          if (buffer.Length() != 0) {
173             ret = Analyse(buffer, CS_DATA);
174          }
175          buffer = "";
176          ret = Analyse("", status);
177       }
178    }
179    else {
180       ret = Analyse(wxString(str), status);
181    }
182    return ret;
183 }
184
185 /* Creates a new wxbDataTokenizer */
186 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
187    finished = false;
188 }
189
190 /* Destroy a wxbDataTokenizer */
191 wxbDataTokenizer::~wxbDataTokenizer() {
192
193 }
194
195 /*
196  *   Receives director information, forwarded by wxbMainFrame.
197  */
198 bool wxbDataTokenizer::Analyse(wxString str, int status) {
199    finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
200
201    if (str != "") {
202       Add(str);
203    }
204    return false;
205 }
206
207 /* Returns true if the last signal received was an end signal, 
208  * indicating that no more data is available */
209 bool wxbDataTokenizer::hasFinished() {
210    return finished;
211 }
212
213 /* Creates a new wxbDataTokenizer */
214 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
215    finished = false;
216    prompt = false;
217    introStr = "";
218    choices = NULL;
219    questionStr = "";
220 }
221
222 /* Destroy a wxbDataTokenizer */
223 wxbPromptParser::~wxbPromptParser() {
224    if (choices) {
225       delete choices;
226    }
227 }
228
229 /*
230  *   Receives director information, forwarded by wxbMainFrame.
231  */
232 bool wxbPromptParser::Analyse(wxString str, int status) {
233    if (status == CS_DATA) {
234       if (finished || prompt) { /* New question */
235          finished = false;
236          prompt = false;
237          if (choices) {
238             delete choices;
239             choices = NULL;
240          }
241          questionStr = "";
242          introStr = "";
243       }
244       int i;
245       long num;
246       
247       if (((i = str.Find(": ")) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
248          if (!choices) {
249             choices = new wxArrayString();
250             choices->Add(""); /* index 0 is never used by multiple choice questions */
251          }
252          
253          if ((long)choices->GetCount() != num) { /* new choice has begun */
254             delete choices;
255             choices = new wxArrayString(num);
256             choices->Add("", num); /* fill until this number */
257          }
258          
259          choices->Add(str.Mid(i+2).RemoveLast());
260       }
261       else if (!choices) { /* Introduction, no list received yet */
262          introStr << questionStr;
263          questionStr = wxString(str);
264       }
265       else { /* List receveived, get the question now */
266          introStr << questionStr;
267          questionStr = wxString(str);
268       }
269    }
270    else {
271       finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
272       if (prompt = ((status == CS_PROMPT) && (questionStr != "$ "))) { // && (str.Find(": ") == str.Length())
273          if ((introStr != "") && (questionStr == "")) {
274             questionStr = introStr;
275             introStr = "";
276          }
277          if (introStr.Last() == '\n') {
278             introStr.RemoveLast();
279          }
280          return true;
281       }
282       else { /* ended or (dis)connected */
283          if (choices) {
284             delete choices;
285             choices = NULL;
286          }
287          questionStr = "";
288          introStr = "";
289       }
290    }
291    return false;
292 }
293
294 /* Returns true if the last signal received was an prompt signal, 
295  * indicating that the answer must be sent */
296 bool wxbPromptParser::hasFinished() {
297    return finished;
298 }
299
300 /* Returns true if the last message received is a prompt message */
301 bool wxbPromptParser::isPrompt() {
302    return prompt;
303 }
304
305 /* Returns multiple choice question's introduction */
306 wxString wxbPromptParser::getIntroString() {
307    return introStr;
308 }
309
310 /* Returns question string */
311 wxString wxbPromptParser::getQuestionString() {
312    return questionStr;
313 }
314
315 /* Return a wxArrayString containing the indexed choices we have
316  * to answer the question, or NULL if this question is not a multiple
317  * choice one. */
318 wxArrayString* wxbPromptParser::getChoices() {
319    return choices;
320 }