void cgicc::Cgicc::parseMIME(const std::string& data) { // Find the header std::string end = "\r\n\r\n"; std::string::size_type headLimit = data.find(end, 0); // Detect error if(std::string::npos == headLimit) throw std::runtime_error("Malformed input"); // Extract the value - there is still a trailing CR/LF to be subtracted off std::string::size_type valueStart = headLimit + end.length(); std::string value = data.substr(valueStart, data.length() - valueStart - 2); // Parse the header - pass trailing CR/LF x 2 to parseHeader MultipartHeader head = parseHeader(data.substr(0, valueStart)); if(head.getFilename().empty()) fFormData.push_back(FormEntry(head.getName(), value)); else fFormFiles.push_back(FormFile(head.getName(), head.getFilename(), head.getContentType(), value)); }
MainWindow::MainWindow(QApplication &app, ElementDatabase& db) : QMainWindow(), Ui::MainWindow(), mApp(&app), mCompleter(NULL), mLangPath(":/lang"), mInputData(db), mDB(&db), mDataVisualizer(this, db) { mApp->installTranslator(&mTranslator); #ifdef DEBUG if ( ! mLangPath.exists() ) std::cerr << "Unable to determine language directory !" << std::endl; #endif setupUi(this); mFormulaDefaultPalette = ntrFormula->palette(); tblResult->setModel(&mModel); // action setup (menu bar) menuFile = new QMenu(menubar); menuTools = new QMenu(menubar); menuLang = new QMenu(menubar); menuHelp = new QMenu(menubar); addActions(); connect(actionQuit, SIGNAL(triggered()), &app, SLOT(quit())); connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); connect(actionAbout_Qt, SIGNAL(triggered()), &app, SLOT(aboutQt())); connect(actionAbout, SIGNAL(triggered()), this, SLOT(about())); connect(actionVisualizeData, SIGNAL(triggered()), &mDataVisualizer, SLOT(show())); connect(actionUseSystemLocale, SIGNAL(triggered()), this, SLOT(useSystemLocaleTriggered())); selectDefaultLang(); actionUseSystemLocale->trigger(); // action setup result table connect(actionExpandAll, SIGNAL(triggered()), this, SLOT(expandAll())); connect(actionCollapseAll, SIGNAL(triggered()), this, SLOT(collapseAll())); connect(actionSelectAll, SIGNAL(triggered()), tblResult, SLOT(selectAll())); connect(actionCopySelection, SIGNAL(triggered()), this, SLOT(copyResultTableSelection())); connect(tblResult, SIGNAL(expanded(const QModelIndex&)), this, SLOT(expandItem(const QModelIndex&))); connect(tblResult, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(expandItem(const QModelIndex&))); // populate list of all known GUI input fields mFormEntries.append(FormEntry(ntrFormula, "currentText", lblFormula)); mFormEntries.append(FormEntry(ntrDensity, "value", lblDensity)); mFormEntries.append(FormEntry(ntrXrayEn, "value", lblXrayEn)); mFormEntries.append(FormEntry(ntrNeutronWl, "value", lblNeutronWl)); saveInitialInput(); // button connectors connect(btnClear, SIGNAL(clicked()), this, SLOT(resetInput())); connect(btnAddAlias, SIGNAL(clicked()), this, SLOT(addAlias())); connect(btnCalc, SIGNAL(clicked()), this, SLOT(doCalc())); if (ntrFormula->lineEdit()) { mCompleter = new FormulaCompleter(db, ntrFormula->lineEdit(), btnCalc); connect(ntrFormula->lineEdit(), SIGNAL(returnPressed()), btnCalc, SLOT(animateClick())); } connect(ntrDensity, SIGNAL(editingFinished()), btnCalc, SLOT(animateClick())); connect(ntrXrayEn, SIGNAL(editingFinished()), btnCalc, SLOT(animateClick())); connect(ntrNeutronWl, SIGNAL(editingFinished()), btnCalc, SLOT(animateClick())); connect(lblFormattedFormula, SIGNAL(linkActivated(const QString&)), this, SLOT(showElementData(const QString&))); connect(&mDataVisualizer, SIGNAL(elementLinkActivated(const QString&)), this, SLOT(showElementData(const QString&))); }
void cgicc::Cgicc::parseFormInput(const std::string& data, const std::string &content_type) { std::string standard_type = "application/x-www-form-urlencoded"; std::string multipart_type = "multipart/form-data"; // Don't waste time on empty input if(true == data.empty()) return; // Standard content type = application/x-www-form-urlencoded // It may not be explicitly specified if(true == content_type.empty() || stringsAreEqual(content_type, standard_type,standard_type.length())) { std::string name, value; std::string::size_type pos; std::string::size_type oldPos = 0; // Parse the data in one fell swoop for efficiency while(true) { // Find the '=' separating the name from its value, also have to check for '&' as its a common misplaced delimiter but is a delimiter none the less pos = data.find_first_of( "&=", oldPos); // If no '=', we're finished if(std::string::npos == pos) break; // Decode the name // pos == '&', that means whatever is in name is the only name/value if( data.at( pos ) == '&' ) { const char * pszData = data.c_str() + oldPos; while( *pszData == '&' ) // eat up extraneous '&' { ++pszData; ++oldPos; } if( oldPos >= pos ) { // its all &'s oldPos = ++pos; continue; } // this becomes an name with an empty value name = form_urldecode(data.substr(oldPos, pos - oldPos)); fFormData.push_back(FormEntry(name, "" ) ); oldPos = ++pos; continue; } name = form_urldecode(data.substr(oldPos, pos - oldPos)); oldPos = ++pos; // Find the '&' or ';' separating subsequent name/value pairs pos = data.find_first_of(";&", oldPos); // Even if an '&' wasn't found the rest of the string is a value value = form_urldecode(data.substr(oldPos, pos - oldPos)); // Store the pair fFormData.push_back(FormEntry(name, value)); if(std::string::npos == pos) break; // Update parse position oldPos = ++pos; } } // File upload type = multipart/form-data else if(stringsAreEqual(multipart_type, content_type, multipart_type.length())){ // Find out what the separator is std::string bType = "boundary="; std::string::size_type pos = content_type.find(bType); // Remove next sentence std::string commatek=";"; // generate the separators std::string sep1 = content_type.substr(pos + bType.length()); if (sep1.find(";")!=std::string::npos) sep1=sep1.substr(0,sep1.find(";")); sep1.append("\r\n"); sep1.insert(0, "--"); std::string sep2 = content_type.substr(pos + bType.length()); if (sep2.find(";")!=std::string::npos) sep2=sep2.substr(0,sep2.find(";")); sep2.append("--\r\n"); sep2.insert(0, "--"); // Find the data between the separators std::string::size_type start = data.find(sep1); std::string::size_type sepLen = sep1.length(); std::string::size_type oldPos = start + sepLen; while(true) { pos = data.find(sep1, oldPos); // If sep1 wasn't found, the rest of the data is an item if(std::string::npos == pos) break; // parse the data parseMIME(data.substr(oldPos, pos - oldPos)); // update position oldPos = pos + sepLen; } // The data is terminated by sep2 pos = data.find(sep2, oldPos); // parse the data, if found if(std::string::npos != pos) { parseMIME(data.substr(oldPos, pos - oldPos)); } } }