3 * wxbDataParser, class that receives and analyses data
5 * Nicolas Boichat, April-July 2004
10 Copyright (C) 2004-2005 Kern Sibbald
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.
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.
26 #include "wxbmainframe.h"
30 #include "wxbtableparser.h"
32 /* A macro named Yield is defined under MinGW */
35 bool wxbUtils::inited = false;
37 wxString wxbUtils::ConvertToPrintable(wxString& str) {
38 /* FIXME : Unicode support should be added to fix this problem */
39 #if (wxUSE_UNICODE == 0) && __WXGTK20__
41 /* Convert the string to something printable without unicode */
42 for (unsigned int i = 0; i < strnew.Length(); i++) {
43 /* If the character is not ASCII, print a ? */
44 if (((unsigned char)strnew[i] > (unsigned char)127)) {
54 /* Sleeps during milliseconds (wrapper for wxUsleep (2.4) or wxMilliSleep (2.6)) */
55 void wxbUtils::MilliSleep(unsigned long milliseconds) {
56 #if wxCHECK_VERSION(2, 6, 0)
57 ::wxMilliSleep(milliseconds);
59 ::wxUsleep(milliseconds);
64 void wxbUtils::Init() {
69 void wxbUtils::Reset() {
73 /* Parse a table in tableParser */
74 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
75 wxbTableParser* tableParser = new wxbTableParser();
77 wxbMainFrame::GetInstance()->Send(cmd);
79 //time_t base = wxDateTime::Now().GetTicks();
80 while (!tableParser->hasFinished()) {
81 //innerThread->Yield();
82 wxTheApp->Yield(true);
83 wxbUtils::MilliSleep(100);
84 //if (base+15 < wxDateTime::Now().GetTicks()) break;
89 /* Run a command, and waits until prompt result is fully received,
90 * if keepresults is true, returns a valid pointer to a wxbPromptParser
91 * containing the data. */
92 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
93 wxbPromptParser* promptParser = new wxbPromptParser();
95 wxbMainFrame::GetInstance()->Send(cmd);
97 //time_t base = wxDateTime::Now().GetTicks();
98 while (!promptParser->hasFinished()) {
99 //innerThread->Yield();
100 wxTheApp->Yield(true);
101 wxbUtils::MilliSleep(100);
102 //if (base+15 < wxDateTime::Now().GetTicks()) break;
114 /* Run a command, and waits until result is fully received. */
115 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
116 wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
118 wxbMainFrame::GetInstance()->Send(cmd);
120 //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
122 //time_t base = wxDateTime::Now().GetTicks();
123 while (!datatokenizer->hasFinished()) {
124 //innerThread->Yield();
125 wxTheApp->Yield(true);
126 wxbUtils::MilliSleep(100);
127 //if (base+15 < wxDateTime::Now().GetTicks()) break;
130 //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
133 return datatokenizer;
136 delete datatokenizer;
142 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
143 wxbDataParser::wxbDataParser(bool lineanalysis) {
144 wxbMainFrame::GetInstance()->Register(this);
145 this->lineanalysis = lineanalysis;
149 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
150 wxbDataParser::~wxbDataParser() {
151 wxbMainFrame::GetInstance()->Unregister(this);
155 * Receives director information, forwarded by wxbMainFrame, and sends it
156 * line by line to the virtual function Analyse.
158 bool wxbDataParser::Print(wxString str, int status) {
161 bool allnewline = true;
162 for (unsigned int i = 0; i < str.Length(); i++) {
163 if (!(allnewline = (str.GetChar(i) == '\n')))
168 ret = Analyse(buffer << wxT("\n"), CS_DATA);
170 for (unsigned int i = 1; i < str.Length(); i++) {
171 ret = Analyse(wxT("\n"), status);
175 wxStringTokenizer tkz(str, wxT("\n"),
176 (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
178 while ( tkz.HasMoreTokens() ) {
179 buffer << tkz.GetNextToken();
180 if (buffer.Length() != 0) {
181 if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
182 (buffer.GetChar(buffer.Length()-1) == '\r')) {
183 ret = Analyse(buffer, status);
190 if (buffer == wxT("$ ")) { // Restore console
191 ret = Analyse(buffer, status);
195 if (status != CS_DATA) {
196 if (buffer.Length() != 0) {
197 ret = Analyse(buffer, CS_DATA);
200 ret = Analyse(wxT(""), status);
204 ret = Analyse(wxString(str), status);
209 /* Creates a new wxbDataTokenizer */
210 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
214 /* Destroy a wxbDataTokenizer */
215 wxbDataTokenizer::~wxbDataTokenizer() {
220 * Receives director information, forwarded by wxbMainFrame.
222 bool wxbDataTokenizer::Analyse(wxString str, int status) {
223 finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
225 if (str != wxT("")) {
231 /* Returns true if the last signal received was an end signal,
232 * indicating that no more data is available */
233 bool wxbDataTokenizer::hasFinished() {
237 /* Creates a new wxbDataTokenizer */
238 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
244 questionStr = wxT("");
247 /* Destroy a wxbDataTokenizer */
248 wxbPromptParser::~wxbPromptParser() {
255 * Receives director information, forwarded by wxbMainFrame.
257 bool wxbPromptParser::Analyse(wxString str, int status) {
258 if (status == CS_DATA) {
259 if (finished || prompt) { /* New question */
267 questionStr = wxT("");
273 if (((i = str.Find(wxT(": "))) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
275 choices = new wxArrayString();
276 choices->Add(wxT("")); /* index 0 is never used by multiple choice questions */
280 if ((long)choices->GetCount() != num) { /* new choice has begun */
282 choices = new wxArrayString();
283 choices->Add(wxT(""), num); /* fill until this number */
287 choices->Add(str.Mid(i+2).RemoveLast());
289 else if (!choices) { /* Introduction, no list received yet */
290 introStr << questionStr;
291 questionStr = wxString(str);
293 else { /* List receveived, get the question now */
294 introStr << questionStr;
295 questionStr = wxString(str);
299 finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
300 if (prompt = ((status == CS_PROMPT) && (questionStr != wxT("$ ")))) { // && (str.Find(": ") == str.Length())
301 if (introStr.Last() == '\n') {
302 introStr.RemoveLast();
304 if ((introStr != wxT("")) && (questionStr == wxT(""))) {
305 questionStr = introStr;
309 if ((!choices) && (questionStr.Find(wxT("(yes/mod/no)")) > -1)) {
310 choices = new wxArrayString();
311 choices->Add(wxT("yes"));
312 choices->Add(wxT("mod"));
313 choices->Add(wxT("no"));
319 else { /* ended or (dis)connected */
325 questionStr = wxT("");
332 /* Returns true if the last signal received was an prompt signal,
333 * indicating that the answer must be sent */
334 bool wxbPromptParser::hasFinished() {
338 /* Returns true if the last message received is a prompt message */
339 bool wxbPromptParser::isPrompt() {
343 /* Returns multiple choice question's introduction */
344 wxString wxbPromptParser::getIntroString() {
348 /* Returns question string */
349 wxString wxbPromptParser::getQuestionString() {
353 /* Returns a wxArrayString containing the indexed choices we have
354 * to answer the question, or NULL if this question is not a multiple
356 wxArrayString* wxbPromptParser::getChoices() {
360 /* Returns true if the expected answer to the choice list is a number,
361 * false if it is a string (for example yes/mod/no). */
362 bool wxbPromptParser::isNumericalChoice() {