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