3 * wxbDataParser, class that receives and analyses data
5 * Nicolas Boichat, April-July 2004
10 Copyright (C) 2004-2006 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.
28 #include "wxbmainframe.h"
32 #include "wxbtableparser.h"
34 /* A macro named Yield is defined under MinGW */
37 bool wxbUtils::inited = false;
39 wxString wxbUtils::ConvertToPrintable(wxString& str) {
40 /* FIXME : Unicode support should be added to fix this problem */
41 #if (wxUSE_UNICODE == 0) && __WXGTK20__
43 /* Convert the string to something printable without unicode */
44 for (unsigned int i = 0; i < strnew.Length(); i++) {
45 /* If the character is not ASCII, print a ? */
46 if (((unsigned char)strnew[i] > (unsigned char)127)) {
56 /* Sleeps during milliseconds (wrapper for wxUsleep (2.4) or wxMilliSleep (2.6)) */
57 void wxbUtils::MilliSleep(unsigned long milliseconds) {
58 #if wxCHECK_VERSION(2, 6, 0)
59 ::wxMilliSleep(milliseconds);
61 ::wxUsleep(milliseconds);
66 void wxbUtils::Init() {
71 void wxbUtils::Reset() {
75 /* Parse a table in tableParser */
76 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
77 wxbTableParser* tableParser = new wxbTableParser();
79 wxbMainFrame::GetInstance()->Send(cmd);
81 //time_t base = wxDateTime::Now().GetTicks();
82 while (!tableParser->hasFinished()) {
83 //innerThread->Yield();
84 wxTheApp->Yield(true);
85 wxbUtils::MilliSleep(100);
86 //if (base+15 < wxDateTime::Now().GetTicks()) break;
91 /* Run a command, and waits until prompt result is fully received,
92 * if keepresults is true, returns a valid pointer to a wxbPromptParser
93 * containing the data. */
94 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
95 wxbPromptParser* promptParser = new wxbPromptParser();
97 wxbMainFrame::GetInstance()->Send(cmd);
99 //time_t base = wxDateTime::Now().GetTicks();
100 while (!promptParser->hasFinished()) {
101 //innerThread->Yield();
102 wxTheApp->Yield(true);
103 wxbUtils::MilliSleep(100);
104 //if (base+15 < wxDateTime::Now().GetTicks()) break;
116 /* Run a command, and waits until result is fully received. */
117 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
118 wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
120 wxbMainFrame::GetInstance()->Send(cmd);
122 //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
124 //time_t base = wxDateTime::Now().GetTicks();
125 while (!datatokenizer->hasFinished()) {
126 //innerThread->Yield();
127 wxTheApp->Yield(true);
128 wxbUtils::MilliSleep(100);
129 //if (base+15 < wxDateTime::Now().GetTicks()) break;
132 //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
135 return datatokenizer;
138 delete datatokenizer;
144 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
145 wxbDataParser::wxbDataParser(bool lineanalysis) {
146 wxbMainFrame::GetInstance()->Register(this);
147 this->lineanalysis = lineanalysis;
151 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
152 wxbDataParser::~wxbDataParser() {
153 wxbMainFrame::GetInstance()->Unregister(this);
157 * Receives director information, forwarded by wxbMainFrame, and sends it
158 * line by line to the virtual function Analyse.
160 bool wxbDataParser::Print(wxString str, int status) {
163 bool allnewline = true;
164 for (unsigned int i = 0; i < str.Length(); i++) {
165 if (!(allnewline = (str.GetChar(i) == '\n')))
170 ret = Analyse(buffer << wxT("\n"), CS_DATA);
172 for (unsigned int i = 1; i < str.Length(); i++) {
173 ret = Analyse(wxT("\n"), status);
177 wxStringTokenizer tkz(str, wxT("\n"),
178 (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
180 while ( tkz.HasMoreTokens() ) {
181 buffer << tkz.GetNextToken();
182 if (buffer.Length() != 0) {
183 if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
184 (buffer.GetChar(buffer.Length()-1) == '\r')) {
185 ret = Analyse(buffer, status);
192 if (buffer == wxT("$ ")) { // Restore console
193 ret = Analyse(buffer, status);
197 if (status != CS_DATA) {
198 if (buffer.Length() != 0) {
199 ret = Analyse(buffer, CS_DATA);
202 ret = Analyse(wxT(""), status);
206 ret = Analyse(wxString(str), status);
211 /* Creates a new wxbDataTokenizer */
212 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
216 /* Destroy a wxbDataTokenizer */
217 wxbDataTokenizer::~wxbDataTokenizer() {
222 * Receives director information, forwarded by wxbMainFrame.
224 bool wxbDataTokenizer::Analyse(wxString str, int status) {
225 finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
227 if (str != wxT("")) {
233 /* Returns true if the last signal received was an end signal,
234 * indicating that no more data is available */
235 bool wxbDataTokenizer::hasFinished() {
239 /* Creates a new wxbDataTokenizer */
240 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
246 questionStr = wxT("");
249 /* Destroy a wxbDataTokenizer */
250 wxbPromptParser::~wxbPromptParser() {
257 * Receives director information, forwarded by wxbMainFrame.
259 bool wxbPromptParser::Analyse(wxString str, int status) {
260 if (status == CS_DATA) {
261 if (finished || prompt) { /* New question */
269 questionStr = wxT("");
275 if (((i = str.Find(wxT(": "))) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
277 choices = new wxArrayString();
278 choices->Add(wxT("")); /* index 0 is never used by multiple choice questions */
282 if ((long)choices->GetCount() != num) { /* new choice has begun */
284 choices = new wxArrayString();
285 choices->Add(wxT(""), num); /* fill until this number */
289 choices->Add(str.Mid(i+2).RemoveLast());
291 else if (!choices) { /* Introduction, no list received yet */
292 introStr << questionStr;
293 questionStr = wxString(str);
295 else { /* List receveived, get the question now */
296 introStr << questionStr;
297 questionStr = wxString(str);
301 finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
302 if (prompt = ((status == CS_PROMPT) && (questionStr != wxT("$ ")))) { // && (str.Find(": ") == str.Length())
303 if (introStr.Last() == '\n') {
304 introStr.RemoveLast();
306 if ((introStr != wxT("")) && (questionStr == wxT(""))) {
307 questionStr = introStr;
311 if ((!choices) && (questionStr.Find(wxT("(yes/mod/no)")) > -1)) {
312 choices = new wxArrayString();
313 choices->Add(wxT("yes"));
314 choices->Add(wxT("mod"));
315 choices->Add(wxT("no"));
321 else { /* ended or (dis)connected */
327 questionStr = wxT("");
334 /* Returns true if the last signal received was an prompt signal,
335 * indicating that the answer must be sent */
336 bool wxbPromptParser::hasFinished() {
340 /* Returns true if the last message received is a prompt message */
341 bool wxbPromptParser::isPrompt() {
345 /* Returns multiple choice question's introduction */
346 wxString wxbPromptParser::getIntroString() {
350 /* Returns question string */
351 wxString wxbPromptParser::getQuestionString() {
355 /* Returns a wxArrayString containing the indexed choices we have
356 * to answer the question, or NULL if this question is not a multiple
358 wxArrayString* wxbPromptParser::getChoices() {
362 /* Returns true if the expected answer to the choice list is a number,
363 * false if it is a string (for example yes/mod/no). */
364 bool wxbPromptParser::isNumericalChoice() {