www.pudn.com > ICE_1.4.zip > q_xml.cpp
// Class automatically generated by Dev-C++ New Class wizard
#include "q_xml.h" // class's header file
// class constructor
q_XML::q_XML(const char*filename, eQXML_MODES mode)
{
std::string open_mode;
m_mode = mode;
switch(mode) {
case QXML_READ: open_mode = "r"; break;
case QXML_WRITE: open_mode = "a"; break;
case QXML_NUKEWRITE: open_mode = "w"; break;
}
m_fptr = fopen(filename, open_mode.c_str() );
//(mode == QXML_READ) ? (mode == QXML_NUKEWRITE) ? "w" : "a" : "r" );
if( m_fptr != NULL ) {
m_parse = QXMLP_VOID;
currTag = "";
currName = "";
currType = "";
currVal = "";
m_err = false;
if(mode == QXML_READ) {
nextNode();
if( m_parse == QXMLP_ERROR || currTag != "node" || currName != "root" || currType != "qXML" ) {
QXML_DEBUG( printf("q_XML: malformed qXML file, read failed\n"); );
fclose(m_fptr);
return;
}
QXML_DEBUG( printf("q_XML: qXML node parsed correctly...\n"); );
nextAttr();
if( currTag != "attr" || currName != "version" || currVal != q_XML_VERSION ) {
QXML_DEBUG( printf("q_XML: mismatched qXML version, found [%s] expected [%s], read failed\n", currVal.c_str(), q_XML_VERSION); );
fclose(m_fptr);
return;
}
QXML_DEBUG( printf("q_XML: correct qXML version found [%s]...\n", q_XML_VERSION); );
nextNode();
if( m_parse == QXMLP_ERROR || currTag != "node" || currName != "data" || currType != "userdata" ) {
QXML_DEBUG( printf("q_XML: malformed qXML file, couldnt find data node, read failed\n"); );
fclose(m_fptr);
return;
}
QXML_DEBUG( printf("q_XML: qXML data node found-- userdata can now be read\n"); );
}else if(m_mode == QXML_NUKEWRITE) {
//format new root node
QXML_DEBUG( printf("q_XML: NUKEWRITE - creating new header\n"); );
createNewNode("root", "qXML");
QXML_DEBUG( printf("q_XML: NUKEWRITE - writing qXML version\n"); );
addAttrStr("version", q_XML_VERSION);
QXML_DEBUG( printf("q_XML: NUKEWRITE - starting data node\n"); );
createNewNode("data", "userdata");
QXML_DEBUG( printf("q_XML: NUKEWRITE - ready for writing\n"); );
}
m_err = false;
}else {
QXML_DEBUG( printf("q_XML: failed to open file %s\n", filename); );
m_err = true;
return;
}
}
// class destructor
q_XML::~q_XML()
{
QXML_DEBUG( printf("q_XML: destroying self \n"); );
if( m_fptr ) {
//make sure to close all tags
if( m_mode != QXML_READ && m_tokenStack.size() > 0)
endNode("");
QXML_DEBUG( printf("q_XML: closed file\n"); );
fclose(m_fptr);
}
}
//writing function
// creates a new XML node
void q_XML::createNewNode(const char*nodeName, const char*nodeType) {
//error checking
if(m_fptr == NULL) { //|| m_mode == QXML_READ || m_err) {
QXML_DEBUG( printf("q_XML: failed to createNewNode -- NULL fptr\n"); );
m_err = true;
return;
}
if(m_mode == QXML_READ) { /// || m_err) {
QXML_DEBUG( printf("q_XML: failed to createNewNode --- IN READ MODE\n"); );
m_err = true;
return;
}
if(m_err) {
QXML_DEBUG( printf("q_XML: failed to createNewNode -- M_ERR = T\n"); );
m_err = true;
return;
}
if(m_fptr == NULL || m_mode == QXML_READ || m_err) {
QXML_DEBUG( printf("q_XML: failed to createNewNode\n"); );
m_err = true;
return;
}
std::string name = std::string(nodeName);
std::string type = std::string(nodeType);
//store new token level
m_tokenStack.push_back(name);
std::string out = "< node=\"" + name + "\" type=\"" + nodeType + "\" >\n";
for(int x=0; x<(int)m_tokenStack.size()-1; x++) fprintf(m_fptr, "\t");
fwrite(out.c_str(), sizeof(out[0]), out.length(), m_fptr );
QXML_DEBUG( printf("writing: [%s]\n", out.c_str()); );
}
//writing function
void q_XML::addAttribute(const char*attrType, const char*attrName, const char*attrVal) {
if(m_fptr == NULL || m_mode == QXML_READ || m_err) {
QXML_DEBUG( printf("q_XML: failed to addAttribute\n"); );
m_err = true;
return;
}
std::string name = std::string(attrName);
std::string type = std::string(attrType);
std::string val = std::string(attrVal);
std::string out = "< attr=\"" + name + "\" type=\"" + type + "\" value=\""+ val + "\" >\n";
for(int x=0; x<(int)m_tokenStack.size(); x++) fprintf(m_fptr, "\t");
fwrite(out.c_str(), sizeof(out[0]), out.length(), m_fptr );
QXML_DEBUG( printf("writing: [%s]\n", out.c_str()); );
}
//writing function
void q_XML::endCurrNode() {
if(m_fptr == NULL || m_mode == QXML_READ || m_err || m_parse != QXMLP_VOID) {
QXML_DEBUG( printf("q_XML: failed to endCurrNode\n"); );
m_err = true;
return;
}
std::string name = m_tokenStack.back();
std::string out = " close=\"" + name + "\" >\n";
m_tokenStack.pop_back();
for(int x=0; x<(int)m_tokenStack.size(); x++) fprintf(m_fptr, "\t");
fwrite(out.c_str(), sizeof(out[0]), out.length(), m_fptr );
QXML_DEBUG( printf("writing: [%s]\n", out.c_str()); );
}
//writing function
// if node name does not exist, this will end all of the current nodes
void q_XML::endNode(const char*nodeName) {
if(m_fptr == NULL || m_mode == QXML_READ || m_err || m_parse != QXMLP_VOID) {
QXML_DEBUG( printf("q_XML: failed to endNode\n"); );
m_err = true;
return;
}
int stackSize = (int)m_tokenStack.size();
while(1) {
std::string name = m_tokenStack.back();
endCurrNode();
if( name == std::string(nodeName) || m_tokenStack.size() == 0 ) return;
}
}
//writing function
void q_XML::addAttrInt(const char*attrName, int attrVal) {
char buffer[64];
sprintf(buffer, "%d", attrVal);
addAttribute("int", attrName, buffer );
}
//writing function
void q_XML::addAttrFloat(const char*attrName, float attrVal) {
char buffer[64];
sprintf(buffer, "%.4f", attrVal);
addAttribute("float", attrName, buffer );
}
//writing function
void q_XML::addAttrStr(const char*attrName, const char* attrVal) {
addAttribute("string", attrName, attrVal );
}
//writing function
void q_XML::addAttrBool(const char*attrName, bool attrVal) {
addAttribute("bool", attrName, attrVal ? "T" : "F" );
}
//reading function
// moves to the next qXML node
// returns "" if no more nodes or EOF
std::string q_XML::nextNode() {
if(m_fptr == 0 || m_mode != QXML_READ || m_parse != QXMLP_VOID) {
QXML_DEBUG( printf("q_XML: nextNode() failed\n"); );
dump();
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
READNODE:
// move to first node
if(! nextTag() ) {
QXML_DEBUG( printf("q_XML: nextNode() could not find next tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
if(! readTag() ) {
QXML_DEBUG( printf("q_XML: nextNode() could not read tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
if(currTag != "node") {
QXML_DEBUG( printf("q_XML: nextNode() found a non-node, skipping\n"); );
goto READNODE;
}
//TODO: if skipped, repeat until found node
return currName;
}
//reading function
// moves to the next qXML attr (or node if at end of curr attrs)
// returns "" if no more attrs or EOF
std::string q_XML::nextAttr() {
//TODO
if(m_fptr == 0 || m_mode != QXML_READ || m_parse != QXMLP_VOID) {
QXML_DEBUG( printf("q_XML: nextAttr() failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");;
}
// move to first node
if(! nextTag() ) {
QXML_DEBUG( printf("q_XML: nextAttr() could not find next tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
if(! readTag() ) {
QXML_DEBUG( printf("q_XML: nextAttr() could not read tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
if(currTag != "attr") {
QXML_DEBUG( printf("q_XML: nextAttr() found a non-attr, ... stopping ??? \n"); );
return std::string("");
}
//TODO: if not attr-- stop?
return currName;
}
//advance thru VOID (whitespace) to next tag "<"
bool q_XML::nextTag() {
if(m_fptr == 0 || m_mode != QXML_READ || m_parse != QXMLP_VOID) {
QXML_DEBUG( printf("q_XML: nextTag() failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
char ch = (char)fgetc(m_fptr);
while(ch != '<' ) {
ch = (char)fgetc(m_fptr);
if( ch == EOF ) {
QXML_DEBUG( printf("q_XML: nextNode() reached unexpected EOF\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
}
m_parse = QXMLP_TAG_START;
QXML_DEBUG( printf("q_XML: nextTag() found TagStart\n"); );
return true;
}
//identify type of tag, and read it
bool q_XML::readTag() {
if(m_fptr == 0 || m_mode != QXML_READ || m_parse != QXMLP_TAG_START) {
QXML_DEBUG( printf("q_XML: readTag() failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
currTag = "";
currName = "";
currType = "";
currVal = "";
//expect space between "<" and tag-name
char ch = fgetc(m_fptr);
if(ch == '/') {
QXML_DEBUG( printf("q_XML: readTag() found '/' must be TAG_CLOSE\n"); );
m_parse = QXMLP_TAG_CLOSE;
currTag = "close";
//TODO: make sure readClose matches name on token stack
if( readClose() == "" ) {
QXML_DEBUG( printf("q_XML: readTag() could not read close tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
QXML_DEBUG( printf("q_XML: readTag() looking for end of CLOSE tag..\n"); );
if(!seekTagEnd() ){
QXML_DEBUG( printf("q_XML: readTag() could not read end of tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
QXML_DEBUG( printf("q_XML: readTag() TAG_CLOSE completed on %s\n", currName.c_str()); );
return true;
}else if(ch != ' ') {
QXML_DEBUG( printf("q_XML: readTag() didnt find expected ' ', failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
//get tag-type
char buffer[64];
int buff_itr = 0;
while(buff_itr < 63) {
ch = fgetc(m_fptr);
if(ch == ' ') {
QXML_DEBUG( printf("q_XML: readTag() found unexpected ' ', failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
}
if(ch == EOF) {
QXML_DEBUG( printf("q_XML: readTag() found unexpected EOF, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
}
if(ch == '=') break;
buffer[buff_itr++] = ch;
}
buffer[buff_itr] = '\0';
QXML_DEBUG( printf("q_XML: readTag() completed tag-type, \"%s\"\n", buffer); );
currTag = std::string(buffer);
//ch = fgetc(m_fptr); move into begining of readNode/readAttr
//get tag name, type, (and value if attr)
if(currTag == "node") {
m_parse = QXMLP_TAG_NODE;
QXML_DEBUG( printf("q_XML: readTag() recognized tag-type, \"%s\"\n", buffer); );
if(! readNode() ){
QXML_DEBUG( printf("q_XML: readTag() could not read Node tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
}else if( currTag == "attr" ) {
m_parse = QXMLP_TAG_ATTR;
QXML_DEBUG( printf("q_XML: readTag() recognized tag-type, \"%s\"\n", buffer); );
if(! readAttr() ){
QXML_DEBUG( printf("q_XML: readTag() could not read Attr tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
}else {
QXML_DEBUG( printf("q_XML: readTag() unrecognized tag name \"%s\", failed\n", currTag.c_str()); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
QXML_DEBUG( printf("q_XML: readTag() looking for end tag..\n"); );
if(!seekTagEnd() ){
QXML_DEBUG( printf("q_XML: readTag() could not read end of tag, failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
QXML_DEBUG( printf("q_XML: readTag() completed tag\n"); );
return true;
}
std::string q_XML::readVal() {
if(m_fptr == 0 || m_mode != QXML_READ || m_parse != QXMLP_IN_VAL) {
QXML_DEBUG( printf("q_XML: readVal() failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
QXML_DEBUG( printf("q_XML: readVal() starting to read value.. \""); );
char buffer[64];
int buff_itr = 0;
char ch = getc(m_fptr);
while(buff_itr < 63) {
if( ch == '"') break;
if( ch == EOF ){
QXML_DEBUG( printf("q_XML: readVal() reached unexpected EOF\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return std::string("");
}
buffer[buff_itr++] = ch;
QXML_DEBUG( printf("%c", ch); );
ch = getc(m_fptr);
}
buffer[buff_itr] = '\0';
QXML_DEBUG( printf("\"\n"); );
std::string val = std::string(buffer);
return val;
}
bool q_XML::seekTagEnd() {
printf("");
if(m_fptr == 0 || m_mode != QXML_READ || (m_parse != QXMLP_TAG_NODE && m_parse != QXMLP_TAG_ATTR && m_parse != QXMLP_TAG_CLOSE) ) {
QXML_DEBUG( printf("q_XML: seekTagEnd() failed\n"); );
m_parse = QXMLP_ERROR;
m_err = true;
return false;
}
char ch;
char skip_str[] = " >";
for(unsigned int i=0; i