// CompareNoCase // it's amazing what features std::string lacks. This function simply // does a lowercase compare against the two strings, returning 0 if they // match. int CompareNoCase(t_Str str1, t_Str str2) { #ifdef WIN32 return stricmp(str1.c_str(), str2.c_str()); #else return strcasecmp(str1.c_str(), str2.c_str()); #endif }
bool t_Str::operator!=(const t_Str &s1) const { if(compare(s1.getText()) != 0) return true; return false; }
t_Str::t_Str(const t_Str &str, size_t start, size_t chars) { init(); char *ptr = str.getText(); size_t len = str.getLength(); if(start >= len) return; ptr += start; len -= start; if(chars >= len) chars = len; set(ptr, chars); }
t_Str CDataFile::CommentStr(t_Str szComment) { t_Str szNewStr = t_Str(""); Trim(szComment); if ( szComment.size() == 0 ) return szComment; if ( szComment.find_first_of(CommentIndicators) != 0 ) { szNewStr = CommentIndicators[0]; szNewStr += " "; } szNewStr += szComment; return szNewStr; }
t_Str CDataFile::CommentStr(t_Str szComment) { t_Str szNewStr = t_Str(""); Trim(szComment); if ( szComment.size() == 0 ) return szComment; if ( szComment.find(CommentIndicators[0]) == gedString::npos && szComment.find(CommentIndicators[1]) == gedString::npos) { szNewStr = (char)CommentIndicators[0]; szNewStr += " "; } szNewStr += szComment; return szNewStr; }
// GetNextWord // Given a key +delimiter+ value string, pulls the key name from the string, // deletes the delimiter and alters the original string to contain the // remainder. Returns the key t_Str GetNextWord(t_Str& CommandLine) { int nPos = CommandLine.find_first_of(EqualIndicators); t_Str sWord = t_Str(""); if ( nPos > -1 ) { sWord = CommandLine.substr(0, nPos); CommandLine.erase(0, nPos+1); } else { sWord = CommandLine; CommandLine = t_Str(""); } Trim(sWord); return sWord; }
// SetFileName // Set's the m_szFileName member variable. For use when creating the CDataFile // object by hand (-vs- loading it from a file void CDataFile::SetFileName(t_Str szFileName) { if (m_szFileName.size() != 0 && CompareNoCase(szFileName, m_szFileName) != 0) { m_bDirty = true; Report(E_WARN, "[CDataFile::SetFileName] The filename has changed from <%s> to <%s>.", m_szFileName.c_str(), szFileName.c_str()); } m_szFileName = szFileName; }
// GetNextWord // Given a key +delimiter+ value string, pulls the key name from the string, // deletes the delimiter and alters the original string to contain the // remainder. Returns the key t_Str GetNextWord(t_Str& CommandLine) { int nPos = CommandLine.find(EqualIndicators[0]); if(nPos == gedString::npos) nPos = CommandLine.find(EqualIndicators[1]); t_Str sWord = t_Str(""); if ( nPos > -1 ) { sWord = CommandLine.substr(0, nPos); CommandLine.erase(0, nPos+1); } else { sWord = CommandLine; CommandLine = t_Str(""); } Trim(sWord); return sWord; }
// SetValue // Given a key, a value and a section, this function will attempt to locate the // Key within the given section, and if it finds it, change the keys value to // the new value. If it does not locate the key, it will create a new key with // the proper value and place it in the section requested. bool CDataFile::SetValue(t_Str szKey, t_Str szValue, t_Str szComment, t_Str szSection) { t_Key* pKey = GetKey(szKey, szSection); t_Section* pSection = GetSection(szSection); if (pSection == NULL) { if ( !(m_Flags & AUTOCREATE_SECTIONS) || !CreateSection(szSection,"")) return false; pSection = GetSection(szSection); } // Sanity check... if ( pSection == NULL ) return false; // if the key does not exist in that section, and the value passed // is not t_Str("") then add the new key. if ( pKey == NULL && szValue.size() > 0 && (m_Flags & AUTOCREATE_KEYS)) { t_Key Key; Key.szKey = szKey; Key.szValue = szValue; Key.szComment = szComment; m_bDirty = true; pSection->Keys.PushBack(Key); pKey = GetKey(szKey, szSection); return true; } if ( pKey != NULL ) { pKey->szValue = szValue; pKey->szComment = szComment; m_bDirty = true; return true; } return false; }
void t_Str::copy(const t_Str &original) { clear(); if(original.getLength() < minsize) { content.ministring.length = (unsigned)original.getLength(); memmove(content.ministring.text, original.getText(), original.getLength() + 1); content.ministring.big = false; return; } // ptr = original.getText(); content.bigstring.length = original.getLength(); content.bigstring.size = setSize(original.getLength() + 1); content.bigstring.text = getSpace(content.bigstring.size); content.ministring.big = true; memmove(content.bigstring.text, original.getText(), original.getLength() + 1); }
int strprintf(t_Str &str, size_t size, const char *format, ...) { va_list args; va_start(args, format); int rtn; if(!size) size = str.getSize(); if(size > str.getSize()) str.resize(size); char *ptr = str.getText(); str.setLength(0); ptr[0] = 0; rtn = vsnprintf(ptr, size, format, args); str.setLength(strlen(ptr)); va_end(args); return rtn; }
// Trim // Trims whitespace from both sides of a string. void Trim(t_Str& szStr) { t_Str szTrimChars = WhiteSpace; szTrimChars += EqualIndicators; int nPos, rPos; // trim left nPos = szStr.find_first_not_of(szTrimChars); if ( nPos > 0 ) szStr.erase(0, nPos); // trim right and return nPos = szStr.find_last_not_of(szTrimChars); rPos = szStr.find_last_of(szTrimChars); if ( rPos > nPos && rPos > -1) szStr.erase(rPos, szStr.size()-rPos); }
bool t_Str::operator*=(const t_Str &s1) const { return search(s1.getText(), s1.getLength()) != npos; }
// Trim // Trims whitespace from both sides of a string. void Trim(t_Str& szStr) { szStr.trimLeft(); szStr.trimRight(); }
size_t t_Str::rfind(const t_Str &str, size_t ind) const { return rfind(str.getText(), ind, str.getLength()); }
size_t t_Str::find(const t_Str &str, size_t ind, unsigned instance) const { return find(str.getText(), ind, str.getLength(), instance); }
unsigned t_Str::count(const t_Str &str, size_t ind) const { return count(str.getText(), ind, str.getLength()); }
void t_Str::append(const t_Str &str) { append(str.getText(), str.getLength()); }
void t_Str::set(const t_Str &str) { set(str.getText(), str.getLength()); }
void t_Str::insert(size_t start, const t_Str &s) { insert(start, s.getText(), s.getLength()); }
// Load // Attempts to load in the text file. If successful it will populate the // Section list with the key/value pairs found in the file. Note that comments // are saved so that they can be rewritten to the file later. bool CDataFile::Load(t_Str szFileName) { // We dont want to create a new file here. If it doesn't exist, just // return false and report the failure. std::fstream File(szFileName.c_str(), std::ios_base::in); // |std::ios_base::nocreate if ( File.is_open() ) { bool bDone = false; bool bAutoKey = (m_Flags & AUTOCREATE_KEYS) == AUTOCREATE_KEYS; bool bAutoSec = (m_Flags & AUTOCREATE_SECTIONS) == AUTOCREATE_SECTIONS; t_Str szLine; t_Str szComment; char buffer[MAX_BUFFER_LEN]; t_Section* pSection = GetSection(""); // These need to be set, we'll restore the original values later. m_Flags |= AUTOCREATE_KEYS; m_Flags |= AUTOCREATE_SECTIONS; while ( !bDone ) { memset(buffer, 0, MAX_BUFFER_LEN); File.getline(buffer, MAX_BUFFER_LEN); szLine = buffer; Trim(szLine); bDone = ( File.eof() || File.bad() || File.fail() ); if ( szLine.find_first_of(CommentIndicators) == 0 ) { szComment += "\n"; szComment += szLine; } else if ( szLine.find_first_of('[') == 0 ) // new section { szLine.erase( 0, 1 ); szLine.erase( szLine.find_last_of(']'), 1 ); CreateSection(szLine, szComment); pSection = GetSection(szLine); szComment = t_Str(""); } else if ( szLine.size() > 0 ) // we have a key, add this key/value pair { t_Str szKey = GetNextWord(szLine); t_Str szValue = szLine; if ( szKey.size() > 0 && szValue.size() > 0 ) { SetValue(szKey, szValue, szComment, pSection->szName); szComment = t_Str(""); } } } // Restore the original flag values. if ( !bAutoKey ) m_Flags &= ~AUTOCREATE_KEYS; if ( !bAutoSec ) m_Flags &= ~AUTOCREATE_SECTIONS; } else { Report(E_INFO, "[CDataFile::Load] Unable to open file. Does it exist?"); return false; } File.close(); return true; }
// CreateSection // Given a section name, this function first checks to see if the given section // allready exists in the list or not, if not, it creates the new section and // assigns it the comment given in szComment. The function returns true if // sucessfully created, or false otherwise. bool CDataFile::CreateSection(t_Str szSection, t_Str szComment) { t_Section* pSection = GetSection(szSection); if ( pSection ) { Report(E_INFO, "[CDataFile::CreateSection] Section <%s> allready exists. Aborting.", szSection.c_str()); return false; } t_Section section; section.szName = szSection; section.szComment = szComment; m_Sections.push_back(section); m_bDirty = true; return true; }