//---------------------------------------------------------------- CPUTResult ReadLine(cString &szString, FILE *pFile) { // TODO: 128 chars is a narrow line. Why the limit? // Is this not really reading a line, but instead just reading the next 128 chars to parse? TCHAR szCurrLine[128] = {0}; TCHAR *ret = fgetws(szCurrLine, 128, pFile); if(ret != szCurrLine) { if(!feof(pFile)) { return CPUT_ERROR_FILE_ERROR; } } szString = szCurrLine; RemoveWhitespace(szString); // TODO: why are we checking feof twice in this loop? // And, why are we using an error code to signify done? // eof check should be performed outside ReadLine() if(feof(pFile)) { return CPUT_ERROR_FILE_ERROR; } return CPUT_SUCCESS; }
Node::Type Node::DetermineType(const std::string &_json) { std::string json; RemoveWhitespace(_json, json); switch (json.at(0)) { case '{' : return T_OBJECT; break; case '[' : return T_ARRAY; break; default : return T_VALUE; break; } }
Node::Type Node::DetermineType(const std::string &_json) { std::string json; RemoveWhitespace(_json, json); Node::Type type = T_VALUE; if (!json.empty()) { switch (json.at(0)) { case '{' : type = T_OBJECT; break; case '[' : type = T_ARRAY; break; } } return type; }
Sequence* PatchTree::SetMachineCode(const char *mcpFileName, const char *section, const char *prefix, char *line) { Sequence *code = NULL; char *key = new char[MAX_LINE]; GetPrivateProfileString(section, NULL, NULL, line, MAX_LINE, mcpFileName); char *keyname = line; int length = strlen(prefix); while(*keyname != '\0') { int keylen = strlen(keyname); if(keylen > length && _strnicmp(keyname, prefix, length) == 0) { GetPrivateProfileString(section, keyname, NULL, key, MAX_LINE, mcpFileName); char *name = &keyname[length]; while(isspace(*name) && strlen(name)) name++; LPVOID address = _stricmp(PK_ATTACH, prefix) ? (void*)strtol(name, NULL, 16) : strcpy(new char[strlen(name)+1], name); if(strlen(RemoveWhitespace(key))>0) code = new Sequence(address, _strlwr(key), code); } keyname += keylen + 1; } delete[] key; return code; }
//---------------------------------------------------------------- CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename) { // Load the file cString szCurrLine; CPUTConfigBlock *pCurrBlock = NULL; FILE *pFile = NULL; int nCurrBlock = 0; CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile); if(CPUTFAILED(result)) { return result; } _locale_t locale = _get_current_locale(); /* Determine file size */ fseek(pFile, 0, SEEK_END); int nBytes = ftell(pFile); // for text files, this is an overestimate fseek(pFile, 0, SEEK_SET); /* Read the whole thing */ char *pFileContents = new char[nBytes + 1]; nBytes = (int)fread(pFileContents, 1, nBytes, pFile); fclose(pFile); pFileContents[nBytes] = 0; // add 0-terminator /* Count the number of blocks */ const char *pCur = pFileContents; const char *pStart, *pEnd; while(ReadLine(&pStart, &pEnd, &pCur)) { const char *pOpen = FindFirst(pStart, pEnd, '['); const char *pClose = FindLast(pOpen + 1, pEnd, ']'); if (pOpen < pClose) { // This line is a valid block header mnBlockCount++; } } // For files that don't have any blocks, just add the entire file to one block if(mnBlockCount == 0) { mnBlockCount = 1; } pCur = pFileContents; mpBlocks = new CPUTConfigBlock[mnBlockCount]; pCurrBlock = mpBlocks; /* Find the first block first */ while(ReadLine(&pStart, &pEnd, &pCur)) { const char *pOpen = FindFirst(pStart, pEnd, '['); const char *pClose = FindLast(pOpen + 1, pEnd, ']'); if (pOpen < pClose) { // This line is a valid block header pCurrBlock = mpBlocks + nCurrBlock++; AssignStr(pCurrBlock->mszName, pOpen + 1, pClose, locale); std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower); } else if (pStart < pEnd) { // It's a value if (pCurrBlock == NULL) { continue; } const char *pEquals = FindFirst(pStart, pEnd, '='); if (pEquals == pEnd) { // No value, just a key, save it anyway // Optimistically, we assume it's new cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName; AssignStr(name, pStart, pEnd, locale); bool dup = false; for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(name)) { dup = true; break; } } if(!dup) { pCurrBlock->mnValueCount++; } } else { const char *pNameStart = pStart; const char *pNameEnd = pEquals; const char *pValStart = pEquals + 1; const char *pValEnd = pEnd; RemoveWhitespace(pNameStart, pNameEnd); RemoveWhitespace(pValStart, pValEnd); // Optimistically assume the name is new cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName; AssignStr(name, pNameStart, pNameEnd, locale); std::transform(name.begin(), name.end(), name.begin(), ::tolower); bool dup = false; for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(name)) { dup = true; break; } } if(!dup) { AssignStr(pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue, pValStart, pValEnd, locale); pCurrBlock->mnValueCount++; } } } } delete[] pFileContents; return CPUT_SUCCESS; }
void Unit::DeserializeSQM(std::istream &in) { std::string strLine; std::getline(in, strLine); unsigned short scope = 1; while(scope != 0) { std::getline(in, strLine); scope += CharCount(strLine, '{'); scope -= CharCount(strLine, '}'); size_t eqPos = strLine.find('='); std::string strCmd = RemoveWhitespace(strLine.substr(0, eqPos)); std::string strArg = strLine.substr(eqPos+1, strLine.size()-1); if(strCmd == "position[]") { strArg = StringReplace(strArg, "{", ""); size_t commaPos = strArg.find(','); m_dX = atof(strArg.substr(0, commaPos).c_str()); strArg = strArg.substr(commaPos+1, strArg.length()); commaPos = strArg.find(','); m_dZ = atof(strArg.substr(0, commaPos).c_str()); strArg = strArg.substr(commaPos+1, strArg.length()); commaPos = strArg.find("};"); m_dY = atof(strArg.substr(0, commaPos).c_str()); } else if(strCmd == "azimut") { m_dAzimuth = atof(strArg.substr(0, strArg.length()-1).c_str()); } else if(strCmd == "special") { m_strSpecial = strArg.substr(1, strArg.length()-3); } else if(strCmd == "vehicle") { m_strType = strArg.substr(1, strArg.length()-3); } else if(strCmd == "player") { if(strArg == "\"PLAY CDG\";") { m_bPlayable = true; } else if(strArg == "\"PLAYER COMMANDER\";") { m_bPlayer = true; } } else if(strCmd == "leader") { if(strArg == "1;") { m_bLeader = 1; } } else if(strCmd == "rank") { m_strRank = strArg.substr(1, strArg.length()-3); } else if(strCmd == "skill") { m_dSkill = atof(strArg.substr(0, strArg.length()-1).c_str()); } else if(strCmd == "init") { m_strInit = strArg.substr(1, strArg.length()-3); } else if(strCmd == "description") { m_strDesc = strArg.substr(1, strArg.length()-3); } else if(strCmd == "health") { m_dHealth = atof(strArg.substr(0, strArg.length()-1).c_str()); } else if(strCmd == "ammo") { m_dAmmo = atof(strArg.substr(0, strArg.length()-1).c_str()); } else if(strCmd == "placement") { m_dPlacement = atof(strArg.substr(0, strArg.length()-1).c_str()); } else if(strCmd == "text") { m_strName = strArg.substr(1, strArg.length()-3); } else if(strCmd == "age") { m_strAge = strArg.substr(1, strArg.length()-3); } } }
/* * GetNextURL - get the next url from html[pos] into result * * Assumptions: * 1. html and base_url are allocated and valid * 2. pos = 0 on initial call * 3. result is NULL and will be allocated internally * * Pseudocode: * 1. check arguments * 2. if pos = 0: remove whitespace from html * 3. find hyperlink starting tags "<a" or "<A" * 4. find next href attribute "href=" * 5. find next end tag ">" * 6. check that href comes before end tag * 7. deal with quoted and unquoted urls * 8. determine if url is absolute * 9. fixup relative links * 10. create new character buffer for result and return it */ int GetNextURL(char *html, int pos, char *base_url, char **result) { int bad_link; // is this link ill formatted? int relative; // is this link relative? char delim; // url delimiter: ' ', ''', '"' char *lnk; // hyperlink tags char *href; // href in a tag char *end; // end of hyperlink tag or url char *ptr; // absolute vs. relative // make sure we have text and base url if(!html || !base_url) return -1; // condense html, makes parsing easier if(pos == 0) RemoveWhitespace(html); // parse for hyperlinks do { relative = 0; // assume absolute link bad_link = 0; // assume valid link // find tag "<a" or "<A"" lnk = strcasestr(&html[pos], "<a"); // no more links on this page if(!lnk) { result = NULL; return -1; } // find next href after hyperlink tag href = strcasestr(lnk, "href="); // no more links on this page if(!href) { result = NULL; return -1; } // find end of hyperlink tag end = strchr(lnk, '>'); // if the href we have is outside the current tag, continue if(end && (end < href)) { bad_link = 1; pos+=2; continue; } // move href to beginning of url href+=5; // something went wrong, just continue if(!href) { bad_link=1; pos+=2; continue; } // is the url quoted? if(*href == '\'' || *href == '"') { // yes, href="url" or href='url' delim = *(href++); // remember delimiter end = strchr(href, delim); // find next of same delimiter } else { // no, href=url end = strchr(href, '>'); // hope: <a ... href=url> // since we've stripped whitespace // this could mangle things like: // <a ... href=url name=val> } // if we don't know where to end the url, continue if(!end) { bad_link = 1; pos += 2; continue; } // have a link now if(*href == '#') { // internal reference bad_link = 1; pos += 2; continue; } // is the url absolute, i.e, ':' must preceede any '/', '?', or '#' ptr = strpbrk(href, ":/?#"); if(!ptr || *ptr != ':') { relative = 1; } else if(strncasecmp(href, "http", 4)) { // absolute, but not http(s) bad_link = 1; pos += 2; continue; } } while(bad_link); // keep parsing // have a good link now if(relative) { // need to fixup relative links *result = FixupRelativeURL(base_url, href, end - href); if(!*result) { return -2; } } else { // create new buffer *result = calloc(end-href+1, sizeof(char)); if(!*result) { return -2; } // check memory // copy over absolute url strncpy(*result, href, end - href); } // return position at the end of the url return end - html; }
//---------------------------------------------------------------- CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename) { // Load the file cString szCurrLine; CPUTConfigBlock *pCurrBlock = NULL; FILE *pFile = NULL; int nCurrBlock = 0; CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile); if(CPUTFAILED(result)) { return result; } /* count the number of blocks */ while(1) { /* Find the block */ // Read lines until a '[' is found CPUTResult readResult = ReadLine(szCurrLine, pFile); if(readResult != CPUT_SUCCESS) break; size_t nOpenBracketIndex = szCurrLine.find_first_of(_L('[')); size_t nCloseBracketIndex = szCurrLine.find_last_of(_L(']')); if(nOpenBracketIndex != cString::npos && nCloseBracketIndex != cString::npos) { // This line is a valid block header mnBlockCount++; } }; /* Mtl files don't have headers, so we have to do some magic to support them */ if(mnBlockCount == 0) { mnBlockCount = 1; } fseek(pFile, 0, SEEK_SET); mpBlocks = new CPUTConfigBlock[mnBlockCount]; pCurrBlock = mpBlocks; /* Find the first block first */ while(1) { /* Find the block */ // Read lines until a '[' is found CPUTResult readResult = ReadLine(szCurrLine, pFile); if(readResult != CPUT_SUCCESS && szCurrLine == _L("")) { fclose(pFile); return CPUT_SUCCESS; } size_t nOpenBracketIndex = szCurrLine.find_first_of(_L('[')); size_t nCloseBracketIndex = szCurrLine.find_last_of(_L(']')); if(nOpenBracketIndex != cString::npos && nCloseBracketIndex != cString::npos) { // This line is a valid block header pCurrBlock = mpBlocks + nCurrBlock++; szCurrLine.erase(nCloseBracketIndex,1); pCurrBlock->mszName = szCurrLine.c_str()+1; /* size_t nSpaceIndex = szCurrLine.find_first_of(_L(' ')); cString szValue = szCurrLine.substr(nSpaceIndex+1); cString szName = szCurrLine.erase(nSpaceIndex, 1024); RemoveWhitespace(szValue); RemoveWhitespace(szName); pCurrBlock->mName.szName = szName; pCurrBlock->mName.szValue = szValue; */ std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower); } else if(szCurrLine != _L("")) { // It's a value if(pCurrBlock == NULL) { continue; } size_t nEqualsIndex = szCurrLine.find_first_of(_L('=')); if(nEqualsIndex == cString::npos) { bool dup = false; // No value, just a key, save it anyway for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(szCurrLine)) { dup = true; break; } } if(!dup) { pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName = szCurrLine; pCurrBlock->mnValueCount++; } } else { cString szValue = szCurrLine.substr(nEqualsIndex+1); cString szName = szCurrLine.erase(nEqualsIndex, 1024); RemoveWhitespace(szValue); RemoveWhitespace(szName); std::transform(szName.begin(), szName.end(), szName.begin(), ::tolower); bool dup = false; for(int ii=0;ii<pCurrBlock->mnValueCount;++ii) { if(!pCurrBlock->mpValues[ii].szName.compare(szName)) { dup = true; break; } } if(!dup) { pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue = szValue; pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName = szName; pCurrBlock->mnValueCount++; } } } }; fclose(pFile); return CPUT_SUCCESS; }