I'm working on a server, and i need to load data.Part of data i need to load is written in xml files so i writen a basic XMLDocumentParser.
const byte XMLDocumentParser::ParseXMLDocument(std::vector<XMLNode*>& out_nodes, const char * fileName)
{
std::ifstream file = std::ifstream(fileName, std::ifstream::ate);
if (!file.is_open())
return 1;
unsigned int fileSize = file.tellg();
file.seekg(std::ifstream::beg);
char * buffer = new char[fileSize];
file.read((char*)buffer, fileSize);
file.close();
if (fileSize <= 80)
{
return 2; // nothing to read
}
XMLNode * newNode = nullptr;
int mainCursor = 0;
for (size_t i = 0; i < 2; i++)
{
newNode = new XMLNode();
mainCursor += GetNode(buffer, mainCursor, newNode);
if (newNode)
{
out_nodes.push_back(newNode);
}
}
delete[] buffer;
buffer = 0;
return 0;
}
and the main recursive function
int XMLDocumentParser::GetNode(char* buffer, int mainCursor, XMLNode* outNode)
{
int argumentCursor = 0, valueCursor = 0, nameCursor = 0; byte result = 0;
short argumentNameSize = 0, argumentValueSize = 0, nameSize;
char* name = 0;
#pragma region NAME
while (1)
{
if (buffer[mainCursor] == '<')
{
mainCursor++;
while (buffer[mainCursor] == ' ')
mainCursor++; //remove whiteSpaces
nameCursor = mainCursor;
while (buffer[nameCursor] != ' ' && buffer[nameCursor] != '>')
nameCursor++;
nameSize = nameCursor - mainCursor;
if (nameSize <= 0)
{
#ifdef XML_DEBUG
result = 3;
std::cout << "::NAME SIZE IS [" << nameSize << "] LINE[" << __LINE__ << "] ->ERROR\n\n";
#endif
break;
}
name = new char[nameSize + 1];
if (memcpy((void*)name, (const void*)&buffer[mainCursor], nameSize) == 0)
{
#ifndef XML_DEBUG
result = 4;
std::cout << "::NAME MEMCPY FAILED NAMESIZE[" << nameSize << "] MAINCURRSOR[" << mainCursor << "] NAMECURSOR[" << nameCursor << "] ERROR\n\n";
#endif
break;
}
mainCursor += nameSize;
name[nameSize] = '\0';
break;
}
mainCursor++;
}
#pragma endregion
outNode->tagName = name;
while (buffer[mainCursor] == ' ')
mainCursor++; //remove whiteSpaces
if (name[0] == '/')
return mainCursor;
//case <tagname> or <tagname/>
if (buffer[mainCursor] == '/' && buffer[mainCursor + 1] == '>')
{
mainCursor += 2; //go past />
return mainCursor;
}
else if (buffer[mainCursor] == '>')
{
XMLNode* childNode = nullptr;
while (1)
{
childNode = new XMLNode();
childNode->parentNode = outNode;
mainCursor = GetNode(buffer, mainCursor, childNode);
outNode->childNodes.push_back(childNode);
char* toCheckName = new char[strlen(name) + 2];
toCheckName[0] = '/';
memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
{
delete[] toCheckName;
toCheckName = 0;
break;
}
delete[] toCheckName;
toCheckName = 0;
}
return mainCursor;
}
#pragma region ARGUMENTS
while (1)
{
while (buffer[mainCursor] == ' ')
mainCursor++; //remove whiteSpaces
if (buffer[mainCursor] == '>') // node with no arguments
{
argumentCursor++; // go past >
XMLNode* childNode = nullptr;
while (1)
{
childNode = new XMLNode();
childNode->parentNode = outNode;
argumentCursor = GetNode(buffer, argumentCursor, childNode);
outNode->childNodes.push_back(childNode);
char* toCheckName = new char[strlen(name) + 2];
toCheckName[0] = '/';
memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
{
delete[] toCheckName;
toCheckName = 0;
break;
}
delete[] toCheckName;
toCheckName = 0;
}
mainCursor = argumentCursor;
break;
}
else if (buffer[mainCursor] == '/' && buffer[mainCursor] == '>')
{
break;// no arguemtns , node finished
}
XMLNodeArgument * newArg = new XMLNodeArgument();
valueCursor = 0; argumentCursor = mainCursor;
while (1)
{
if (buffer[argumentCursor] == '\"' && valueCursor == 0)
{
if (buffer[argumentCursor + 1] == '\"') //case argName=""
{
argumentCursor++;
valueCursor = argumentCursor;
argumentCursor++;
break;
}
argumentCursor++;
valueCursor = argumentCursor;
}
else if (buffer[argumentCursor] == '\"' && valueCursor != 0)
{
argumentCursor++;
break;
}
argumentCursor++;
}
argumentValueSize = argumentCursor - valueCursor - 1;
argumentNameSize = valueCursor - mainCursor - 2;
newArg->argumentName = new char[argumentNameSize + 1];
newArg->argumentValue = new char[argumentValueSize + 1];
if (memcpy((void*)newArg->argumentName, (const void*)&buffer[mainCursor], argumentNameSize) == 0)
{
#ifdef XML_DEBUG
result = 1;
std::cout << "ARGUMENT NAME FAILED ARGUMENTCURSOR[" << argumentCursor << "] ARGUMENTNAMESIZE[" << argumentNameSize << "] MAINCURSOR[" << mainCursor << "] buffer[MAINCURSOR]=" << buffer[mainCursor] << "]\n";
#endif
break;
}
if (memcpy((void*)newArg->argumentValue, (const void*)&buffer[valueCursor], argumentValueSize) == 0)
{
#ifdef XML_DEBUG
result = 1;
std::cout << "ARGUMENT VALUE FAILED ARGUMENTCURSOR[" << argumentCursor << "] ARGUMENTNAMESIZE[" << argumentNameSize << "] MAINCURSOR[" << mainCursor << "] buffer[MAINCURSOR]=" << buffer[mainCursor] << "]\nARGUMENTVALUESIZE[" << argumentValueSize << "] ARGUMENTCUROSR[" << argumentCursor << "]\n";
#endif
break;
}
newArg->argumentName[argumentNameSize] = '\0';
newArg->argumentValue[argumentValueSize] = '\0';
outNode->_arguments.push_back(newArg);
while (buffer[argumentCursor] == ' ')
argumentCursor++;
if (buffer[argumentCursor] == '>')
{
argumentCursor++; // go past >
XMLNode* childNode = nullptr;
while (1)
{
childNode = new XMLNode();
childNode->parentNode = outNode;
argumentCursor = GetNode(buffer, argumentCursor, childNode);
outNode->childNodes.push_back(childNode);
char* toCheckName = new char[strlen(name) + 2];
toCheckName[0] = '/';
memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
{
delete[] toCheckName;
toCheckName = 0;
break;
}
delete[] toCheckName;
toCheckName = 0;
}
mainCursor = argumentCursor;
break;
}
else if (buffer[argumentCursor] == '/' && buffer[argumentCursor + 1] == '>')
{
//we dont have ChildNodes return size
argumentCursor += 2; //go past />
mainCursor = argumentCursor;
return mainCursor;
}
else if (buffer[argumentCursor] == '?' && buffer[argumentCursor + 1] == '>')
{
//we dont have ChildNodes return size
argumentCursor += 2; //go past />
mainCursor = argumentCursor;
return mainCursor;
}
mainCursor += argumentNameSize + argumentValueSize + 3;
}
#pragma endregion
return mainCursor;
}
Then i use this function to get desired data out of XMLNodes
void XMLDocumentParser::BuildItems(XMLNode * mainnode, std::vector<IItem*>& out_items)
{
for (size_t j = 0; j < mainnode->childNodes.size() - 1; j++)
{
XMLNode* node = mainnode->childNodes[j];
XMLNodeArgument* arg = nullptr;
IItem* out = new IItem();
for (size_t i = 0; i < node->_arguments.size(); i++)
{
if ((arg = node->ConsumeArgument("id")))
{
out->_id = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("name")))
{
out->_name = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_name, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("coolTime")))
{
out->_coolTime = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("category")))
{
out->_category = itemCategoryDictionary[(const char*)arg->argumentValue];
}
else if ((arg = node->ConsumeArgument("level")))
{
out->_itemLevel = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("rank")))
{
out->_rank = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("maxStack")))
{
out->_maxStack = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("rareGrade")))
{
out->_rareGrade = (ItemRareGrade)atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("requiredEquipmentType")))
{
out->_requiredEquipmentType = itemTypeDictionary[(const char*)arg->argumentValue];
}
else if ((arg = node->ConsumeArgument("combatItemType")))
{
out->_type = itemTypeDictionary[(const char*)arg->argumentValue];
}
else if ((arg = node->ConsumeArgument("requiredLevel")))
{
out->_requiredLevel = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("artisanable")))
{
out->_artisanable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("dismantlable")))
{
out->_dismantlable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("enchantEnable")))
{
out->_enchantEnabled = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("extractLook")))
{
//todo
}
else if ((arg = node->ConsumeArgument("guildWarehouseStorable")))
{
out->_guildBankStorable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("masterpieceRate")))
{
out->_masterpieceRate = atof((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("obtainable")))
{
out->_obtainable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("sellPrice")))
{
out->_sellPrice = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("slotLimit")))
{
out->_slotLimit = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("sortingNumber")))
{
out->_sortingNumber = atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("storeSellable")))
{
out->_sellable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("tradable")))
{
out->_tradable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("unidentifiedItemGrade")))
{
out->_itemGrade = (ItemGrade)atoi((const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("useOnlyTerritory")))
{
out->_useOnlyTerritory = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("warehouseStorable")))
{
out->_warehouseStoreable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("changeColorEnable")))
{
out->_changeColorEnable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
else if ((arg = node->ConsumeArgument("boundType")))
{
out->_bountType = itemBoundTypeDictionary[(const char*)arg->argumentValue];
}
else if ((arg = node->ConsumeArgument("requiredClass")))
{
out->_requiredClass = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_requiredClass, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkMasterpiecePassivityCategoryId")))
{
out->_linkMasterpiecePassivityCategoryId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkMasterpiecePassivityCategoryId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkPassivityCategoryId")))
{
out->_linkPassivityCategoryId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkPassivityCategoryId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkPassivityId")))
{
out->_linkPassivityId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkPassivityId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkCrestId")))
{
out->_linkCrestId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkCrestId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkCustomizingId")))
{
out->_linkCustomizingId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkCustomizingId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkEquipmentId")))
{
out->_linkEquipmentId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkEquipmentId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkLookInfoId")))
{
out->_linkLookInfoId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkLookInfoId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkPetAdultId")))
{
out->_linkPetAdultId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkPetAdultId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkPetOrbId")))
{
out->_linkPetOrbId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkPetOrbId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkSkillId")))
{
out->_linkSkillId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkSkillId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("linkEnchantId")))
{
out->_linkEnchantId = new char[strlen((const char*)arg->argumentValue)];
strcpy((char*)out->_linkEnchantId, (const char*)arg->argumentValue);
}
else if ((arg = node->ConsumeArgument("dropIdentify")))
{
out->_dropIdentify = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
}
}
out_items.push_back(out);
}
}
The XMLDocumentParser::ParseXMLDocument goes well, but when i'm get IItems out of XMLNodes [as shown above] [with program compiled in Release mode VS2015] it crashes randomly at delete _arguments[i];
XMLDocumentParser::XMLNode::~XMLNode()
{
if (tagName)
{
delete[] tagName;
tagName = 0;
}
//clean arguments
for (size_t i = 0; i < _arguments.size(); i++)
{
if (_arguments[i])
{
delete _arguments[i];
_arguments[i] = 0;
}
}
_arguments.clear();
//clean childNodes
for (size_t i = 0; i < childNodes.size(); i++)
{
if (childNodes[i])
{
delete childNodes[i];
childNodes[i] = 0;
}
}
childNodes.clear();
parentNode = 0;
}
Why is that happening...Please help. Thanks!
Aucun commentaire:
Enregistrer un commentaire