Exemple #1
0
/**  string FXMLElement::getValueFromPath(string path);
 *
 *   Added by cmicali
 *     Purpose: get the value of the node referenced by the dot-path notation
 *              example: 
 *
 *              <config>
 *                <general>
 *                   <size>50</size>
 *                <general>
 *              </config>
 * 
 *              FXMLElement *n = fxml.ParseFile("abovefile.xml");
 *              // n is now a pointer to root node "config"
 *              std::string s = n->getValueFromPath("general.size");
 *              // String s now is "50"
 */
std::string FXMLElement::getValueFromPath(std::string path) {
    int f = path.find(".",0);
    int o = 0;
    std::list<std::string> l;
    path = path + ".";
    while (f != std::string::npos) {
        std::string s = path.substr(o,f-o);
        if (s != "")
            l.push_back(s);
        o = f+1;
        f = path.find(".", o);;
    }
    std::list<std::string>::const_iterator iter;
    iter=l.begin();
    if (iter != l.end()) {
        std::string s = (*iter);
        FXMLElement *n = findChild(this, s);
        iter++;
        if (!n) return "";
        for (; iter != l.end(); iter++) {
            s = (*iter);
            n = findChild(n, s);
            if (!n) return "";
        }
        return n->Value();
    }
    return "";    
}
Exemple #2
0
FXMLElement* FXMLParser::ParseElement(std::string sCurInput, long* nLoc, long* nLineCount)
{
	int nMode = PARSE_MODE_NONE; //set the initial mode
	std::string sWord("");	//set the current word read
	char ch;	//current character read
	std::string sAttributeName; //attribute name to save
	int nSpecialMode; //if parsing comments, used to save old mode
	FXMLElement *fxInput = NULL;
	FXMLElement *fxChild = NULL;
	std::string sElementName; //element name, to be used for error checking

    //parse the line a char at a time
    for (long i = (*nLoc); i < sCurInput.length(); i++)
    {
        ch = sCurInput.at(i);
		if (ch == '<')
		{
			//parse the start of new elements
			if (nMode == PARSE_MODE_NONE)
			{
				//the beginning of an element
				nMode = PARSE_MODE_ELEMENT_PROVISIONAL;
				//create a new input element
				if (fxInput == NULL)
				{
					fxInput = new FXMLElement;
					fxInput->fxParent = NULL;
				}
			}
			else if ((nMode == PARSE_MODE_ELEMENT_DATA) || (nMode == PARSE_MODE_CDATA_END))
			{
			    nMode = PARSE_MODE_END_PROVISIONAL;
			    
			    //see if this is the last element or not
			    if (sCurInput.at(i + 1) == '/')
			    {
					//it is a last element, set mode
					fxInput->Value(sWord);
					nMode = PARSE_MODE_END;	
					sWord.erase();			
			    }
			    else
			    {
					//if not last element, perform recursive call
					if (fxInput->mChildren == NULL)
						fxInput->mChildren = new std::list<FXMLElement*>;
					fxChild = ParseElement(sCurInput, &i, nLineCount);				
					if (fxChild != NULL)
					{
						fxChild->fxParent = fxInput;
						//V 0.92 Elements now in order thanks to
						//Max Belugin - [email protected]  
						fxInput->mChildren->push_back(fxChild);
					}

					//set mode, initialize sWord with existing data
					nMode = PARSE_MODE_ELEMENT_DATA;
					
					//V0.93 removed - to be fixed later
					//sWord = fxInput->Value();
			    }
			    
			}
			else if (nMode == PARSE_MODE_CDATA)
			{
			    sWord.append(1, ch);
			}
		}
		else if ((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t'))
		{
			//if in element data, add it.  Else end state

			//also, do not add newlines or spaces to data
			if (nMode == PARSE_MODE_ELEMENT_DATA)
			{
				if (sWord.length() > 0) sWord.append(1,ch);
			}
			else if ((nMode == PARSE_MODE_CDATA) || (nMode == PARSE_MODE_ATTRIBUTE_VALUE))
				//V 0.92 Attribute values with spaces now valid thanks to Max Belugin - [email protected]  
				sWord.append(1, ch);
			else if (nMode == PARSE_MODE_ELEMENT_NAME)
			{
				//set the element name
				sElementName = sWord;
				fxInput->Name(sWord);
				sWord.erase();
				//now set to look for attributes
				nMode = PARSE_MODE_ATTRIBUTE_PROVISIONAL;
			}

			//increment line count if \n
			if (ch == '\n') (*nLineCount)++;
		}
		else if ((ch == '?') || (ch == '!'))
		{
			//its a comment or declaration.  For this version
			//of the parser, ignore them
			if (nMode == PARSE_MODE_ELEMENT_PROVISIONAL)
			{
			    //save the old mode
			    nSpecialMode = nMode;
			    nMode = PARSE_MODE_SPECIAL;
			}			    
		}
		else if (ch == '[')
		{
		    //look out for cdata tags
		    if (nMode == PARSE_MODE_SPECIAL)
		    {
			if (sCurInput.substr(i+1, 5).compare("CDATA") == 0)
			    nMode = PARSE_MODE_CDATA_PROVISIONAL;
		    }	
		    else if (nMode == PARSE_MODE_CDATA_PROVISIONAL)
		    {
				sWord.erase();
				nMode = PARSE_MODE_CDATA;
		    }
		    else
			sWord.append(1, ch);    
		}
		else if (ch == ']')
		{
		    //look for end of CDATA
		    if (nMode == PARSE_MODE_CDATA)
				nMode = PARSE_MODE_CDATA_END_PROVISIONAL;
		    else if (nMode == PARSE_MODE_CDATA_END_PROVISIONAL)
				nMode = PARSE_MODE_CDATA_END;
		    else
				sWord.append(1, ch);
		    
		}
		else if (ch == '>')
		{
			//end of element name
			if (nMode == PARSE_MODE_ELEMENT_NAME)
			{
				//set the element name
				sElementName = sWord;
				fxInput->Name(sWord);
				sWord.erase();
				//now set more to look for element data
				nMode = PARSE_MODE_ELEMENT_DATA;
			}
			else if (nMode == PARSE_MODE_ATTRIBUTE_PROVISIONAL)
			{
			    //attribute parsing over, prepare to parse element data
			    sWord.erase();
			    nMode = PARSE_MODE_ELEMENT_DATA;
			}
			else if (nMode == PARSE_MODE_END)
			{
			    //end of the element
				//only compare IF sWord.length > 0
				if (sWord.length() > 0)
				{
					if (sWord.compare(sElementName) != 0)
					{
						//parse error!!!
						//V0.93 handle parse errors nicely!
						char* cError = (char*)malloc(6);
						 sprintf(cError, "%d", (*nLineCount));
						sError = (std::string)"FXML reports parsing error.  Unmatched tag: Expecting " +
							sElementName + (std::string)" but encountered " + sWord + (std::string)" at line: " + cError;
						free(cError);
						delete fxInput;
						fxInput = NULL;
					}
				}
				//V0.93
				//do NOT skip ahead one if xml file stuffed together
				//handles <xml>blah</xml><more>data</more> correctly
				//parse element data
			    sWord.erase();
				if (sCurInput.length() > (i + 1))
				{
					if ((sCurInput.at(i + 1) =='\n') ||
						(sCurInput.at(i + 1) =='\r'))
					{
						(*nLoc) = i + 1;
					}
					else
						(*nLoc) = i;
				}
				else
					(*nLoc) = i;

			    return fxInput;
			}
			else if (nMode == PARSE_MODE_SPECIAL)
			{
			    //end of a special element, reset the mode
			    nMode = nSpecialMode;
			}
			else if (nMode == PARSE_MODE_CDATA)
			{
			    sWord.append(1, ch);
			}
		}
		else if (ch == '/')
		{
		    //handle elements such as <blah ..... />
		    if (nMode == PARSE_MODE_ATTRIBUTE_PROVISIONAL)
		    {
				nMode = PARSE_MODE_END;
		    }
		    else if ((nMode != PARSE_MODE_SPECIAL) && (nMode != PARSE_MODE_END))
				sWord.append(1, ch);
		    			
		}
		else if (ch == '=')
		{
			//parsing of attributes
			if (nMode == PARSE_MODE_ATTRIBUTE_NAME)
			{
				//set the attribute name	
				sAttributeName = sWord;
				sWord.erase();
				//set the mode
				nMode = PARSE_MODE_ATTRIBUTE_VALUE_PROVISIONAL;
			}
			else if (nMode != PARSE_MODE_SPECIAL)
				sWord.append(1, ch);

		}
		else if ((ch == '"') || (ch == '\''))
		{
			//parsing of attributes
			if (nMode == PARSE_MODE_ATTRIBUTE_VALUE_PROVISIONAL)
			{
				nMode = PARSE_MODE_ATTRIBUTE_VALUE;
			}
			else if (nMode == PARSE_MODE_ATTRIBUTE_VALUE)
			{
				//save the pair 
				fxInput->SetAttributePair(sAttributeName, sWord);
				//erase
				sWord.erase();	
				sAttributeName.erase();
				
				//set new mode
				nMode = PARSE_MODE_ATTRIBUTE_PROVISIONAL;
			}
			else if (nMode != PARSE_MODE_SPECIAL)
				sWord.append(1, ch);
	
			
		}
		else
		{
			//parsing of straight text/words
			if (nMode == PARSE_MODE_ELEMENT_PROVISIONAL)
				nMode = PARSE_MODE_ELEMENT_NAME;
			else if (nMode == PARSE_MODE_ATTRIBUTE_PROVISIONAL)
				nMode = PARSE_MODE_ATTRIBUTE_NAME;

			//ignore comments and special declarations
			if ((nMode != PARSE_MODE_SPECIAL) && (nMode != PARSE_MODE_CDATA_END))
				sWord.append(1, ch);
		}


	} 
	
	return NULL;
}
///////////////////////////////////////////////////////
//
//	Name: ReadAndWriteSocket
//	Params: sd - socket to read/write from
//	Returns: BOOLEAN success
//	Description: Reads XML query from socket, writes
//		XML result set
///////////////////////////////////////////////////////
bool ReadAndWriteSocket(SOCKET sd)
{
	// Read data from client
	char acReadBuffer[kBufferSize];
	int nReadBytes = 0; //number of bytes read
	std::string sRead, sTemp, sResult; //string to read, and result
	int nFind; //result var
	BOOL bAllDone = FALSE;//whether the transaction is finished or not

	//variables for setting up timeout
	fd_set read_fds; 
	struct timeval TimeOut; 
	FD_ZERO(&read_fds); 
	FD_SET(sd, &read_fds); 
	TimeOut.tv_sec = gnThreadTimeout; //use timeout of durartion gnThreadTimeout
	TimeOut.tv_usec = 0; 

	try
	{ 
		if (select(FD_SETSIZE, &read_fds, NULL, NULL, &TimeOut) != SOCKET_ERROR) 
		{ 
			if (FD_ISSET(sd, &read_fds)) 
			{ 
				do {
					nReadBytes = recv(sd, acReadBuffer, kBufferSize, 0);
					if (nReadBytes > 0) {
						LogEvent("ReadWriteSocket reports receiving client data", 1);

						//copy over inbound buffer
						sTemp = acReadBuffer;
						sRead.append(sTemp.substr(0,nReadBytes));
						sTemp.erase();

						//search for the end of XML.  If found, we have received
						//all data.  If not found, keep receiving data
						nFind = sRead.find("</request>");
						if (nFind > 0)
						{

							//parse out request
							FXMLParser fxParse; //xml parser
							FXMLElement *fxElem = NULL;
							
							try
							{
								fxElem = fxParse.ParseString(sRead.c_str()); //parse string
							}
							catch(...)
							{
								LogEvent("ReadAndWriteSocket reports fXML Parser exception.", 2);
								break;
							}

							FXMLElement *fxRet = NULL;
							std::string sConnectionString, sSQL;

							//if string is not XML  , exit
							if ((fxElem == NULL) || (fxParse.sError.length() > 0))
							{
								LogEvent("ReadWriteSocket reports receiving invalid XML string", 2);
								break;
							}

							//get connection string
							fxRet = FindChildByName("connectionstring", fxElem, fxElem->mChildren->begin());				
							if (fxRet != NULL) 
								sConnectionString = fxRet->Value();
							else
							{
								LogEvent("ReadWriteSocket reports no connection string found.",2);
								break;
							}

							fxRet = NULL;

							//get SQL
							fxRet =  FindChildByName("sql", fxElem, fxElem->mChildren->begin());				
							if (fxRet != NULL)
								sSQL = fxRet->Value();
							else
							{
								LogEvent("ReadWriteSocket reports no SQL string found.",2);
								break;
							}

							if ((sConnectionString.length() == 0) || (sSQL.length() == 0)) break;

							//now sub in > for &lt; , etc..
							sSQL = SubStrReplace(sSQL, "&lt;", "<" );
							sSQL = SubStrReplace(sSQL, "&gt;", ">");
							sSQL = SubStrReplace(sSQL, "&amp;", "&");

							LogEvent(((std::string)"ReadWriteSocket reports executing SQL:" + sSQL).c_str(), 1);

							//now execute SQL 
							sResult = ExecSQL(sConnectionString, sSQL);

							//now send back response
							nReadBytes = sResult.length();

							int nSentBytes = 0;
							while (nSentBytes < nReadBytes) {
								nSentBytes = send(sd, sResult.c_str() + nSentBytes,
										nReadBytes - nSentBytes, 0);
								if (nSentBytes <= 0)
								{
									//closed connection or something
									LogEvent("ReadWriteSocket reports no data to return", 1);
									break;
								}
							}//while
							bAllDone = TRUE;
							sRead = "";
						} //nfind > 0
						//look for termination request
					}//nreadbytes > 0
				} while ((nReadBytes > 0) && (!bAllDone));
			}//FD_ISSET
		}//select
		else if (nReadBytes == SOCKET_ERROR) {
			LogEvent("ReadWriteSocket reports socket error after data return.  Not necessarily a problem.", 1);
		}

		if (!bAllDone) LogEvent("ReadWriteSocket reports invalid data received, no SQL executed.", 2);
	}
	catch(...)
	{
		LogEvent("ReadAndWriteSocket reports fatal exception reading data.",2);
	}

	try
	{
		SOCKETMAP::iterator iSocket; //socket iterator

		if (ShutdownConnection(sd)) {
			LogEvent("ReadAndWriteSocket reports closing connection", 1);
		}
		else {
			LogEvent(WSAGetLastErrorMessage("shutdown connection"),2);
		}

		EnterCriticalSection(&gcsLock);

		try
		{
			iSocket = gmSockets.find(sd);
			gmSockets.erase(iSocket);
		}
		catch(...)
		{
		}

		LeaveCriticalSection(&gcsLock);
	}
	catch(...)
	{
		LogEvent("ReadAndWriteSocket reports fatal exception closing connection.",2);
	}

	
	return true;
}