CString Font::GetPageNameFromFileName( const CString &sFilename ) { size_t begin = sFilename.find_first_of( '[' ); if( begin == string::npos ) return "main"; size_t end = sFilename.find_first_of( ']', begin ); if( end == string::npos ) return "main"; begin++; end--; if( end == begin ) return "main"; return sFilename.substr( begin, end-begin+1 ); }
bool CKeyMap::parseModifiers(CString& x, KeyModifierMask& mask) { // initialize tables initKeyNameMaps(); mask = 0; CString::size_type tb = x.find_first_not_of(" \t", 0); while (tb != CString::npos) { // get next component CString::size_type te = x.find_first_of(" \t+)", tb); if (te == CString::npos) { te = x.size(); } CString c = x.substr(tb, te - tb); if (c.empty()) { // missing component return false; } if (s_nameToModifierMap->count(c) > 0) { KeyModifierMask mod = s_nameToModifierMap->find(c)->second; if ((mask & mod) != 0) { // modifier appears twice return false; } mask |= mod; } else { // unknown string x.erase(0, tb); CString::size_type tb = x.find_first_not_of(" \t"); CString::size_type te = x.find_last_not_of(" \t"); if (tb == CString::npos) { x = ""; } else { x = x.substr(tb, te - tb + 1); } return true; } // check for '+' or end of string tb = x.find_first_not_of(" \t", te); if (tb != CString::npos) { if (x[tb] != '+') { // expected '+' return false; } tb = x.find_first_not_of(" \t", tb + 1); } } // parsed the whole thing x = ""; return true; }
bool CUser::AddCTCPReply(const CString& sCTCP, const CString& sReply) { // Reject CTCP requests containing spaces if (sCTCP.find_first_of(' ') != CString::npos) { return false; } // Reject empty CTCP requests if (sCTCP.empty()) { return false; } m_mssCTCPReplies[sCTCP.AsUpper()] = sReply; return true; }
CString CUser::AddTimestamp(time_t tm, const CString& sStr) const { CString sRet = sStr; if (!GetTimestampFormat().empty() && (m_bAppendTimestamp || m_bPrependTimestamp)) { CString sTimestamp = CUtils::FormatTime(tm, GetTimestampFormat(), m_sTimezone); if (sTimestamp.empty()) { return sRet; } if (m_bPrependTimestamp) { sRet = sTimestamp; sRet += " " + sStr; } if (m_bAppendTimestamp) { // From http://www.mirc.com/colors.html // The Control+O key combination in mIRC inserts ascii character 15, // which turns off all previous attributes, including color, bold, // underline, and italics. // // \x02 bold // \x03 mIRC-compatible color // \x04 RRGGBB color // \x0F normal/reset (turn off bold, colors, etc.) // \x12 reverse (weechat) // \x16 reverse (mirc, kvirc) // \x1D italic // \x1F underline // Also see http://www.visualirc.net/tech-attrs.php // // Keep in sync with CIRCSocket::IcuExt__UCallback if (CString::npos != sRet.find_first_of("\x02\x03\x04\x0F\x12\x16\x1D\x1F")) { sRet += "\x0F"; } sRet += " " + sTimestamp; } } return sRet; }
static void tokenize(CStringList& tokens, const CString& src) { // find first non-whitespace CString::size_type x = src.find_first_not_of(" \t\r\n"); if (x == CString::npos) { return; } // find next whitespace do { CString::size_type y = src.find_first_of(" \t\r\n", x); if (y == CString::npos) { y = src.size(); } tokens.push_back(src.substr(x, y - x)); x = src.find_first_not_of(" \t\r\n", y); } while (x != CString::npos); }
void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const CString &sTexturePath, const CString &sPageName, CString sChars ) { cfg.m_sTexturePath = sTexturePath; /* If we have any characters to map, add them. */ for( unsigned n=0; n<sChars.size(); n++ ) { char c = sChars[n]; cfg.CharToGlyphNo[c] = n; } int iNumFramesWide, iNumFramesHigh; RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh ); int iNumFrames = iNumFramesWide * iNumFramesHigh; ini.RenameKey("Char Widths", "main"); // LOG->Trace("Loading font page '%s' settings from page name '%s'", // TexturePath.c_str(), sPageName.c_str()); ini.GetValue( sPageName, "DrawExtraPixelsLeft", cfg.m_iDrawExtraPixelsLeft ); ini.GetValue( sPageName, "DrawExtraPixelsRight", cfg.m_iDrawExtraPixelsRight ); ini.GetValue( sPageName, "AddToAllWidths", cfg.m_iAddToAllWidths ); ini.GetValue( sPageName, "ScaleAllWidthsBy", cfg.m_fScaleAllWidthsBy ); ini.GetValue( sPageName, "LineSpacing", cfg.m_iLineSpacing ); ini.GetValue( sPageName, "Top", cfg.m_iTop ); ini.GetValue( sPageName, "Baseline", cfg.m_iBaseline ); ini.GetValue( sPageName, "DefaultWidth", cfg.m_iDefaultWidth ); ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels ); ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints ); /* Iterate over all keys. */ const XNode* pNode = ini.GetChild( sPageName ); if( pNode ) { FOREACH_CONST_Attr( pNode, pAttr ) { CString sName = pAttr->m_sName; const CString &sValue = pAttr->m_sValue; sName.MakeUpper(); /* If val is an integer, it's a width, eg. "10=27". */ if( IsAnInt(sName) ) { cfg.m_mapGlyphWidths[atoi(sName)] = atoi( sValue ); continue; } /* "map codepoint=frame" maps a char to a frame. */ if( sName.substr(0, 4) == "MAP " ) { /* * map CODEPOINT=frame. CODEPOINT can be * 1. U+hexval * 2. an alias ("oq") * 3. a game type followed by a game alias, eg "pump menuleft" * 4. a character in quotes ("X") * * map 1=2 is the same as * range unicode #1-1=2 */ CString sCodepoint = sName.substr(4); /* "CODEPOINT" */ const Game* pGame = NULL; if( sCodepoint.find_first_of(' ') != sCodepoint.npos ) { /* There's a space; the first word should be a game type. Split it. */ unsigned pos = sCodepoint.find_first_of( ' ' ); CString gamename = sCodepoint.substr( 0, pos ); sCodepoint = sCodepoint.substr( pos+1 ); pGame = GameManager::StringToGameType(gamename); if( pGame == NULL ) { LOG->Warn( "Font definition '%s' uses unknown game type '%s'", ini.GetPath().c_str(), gamename.c_str() ); continue; } } wchar_t c; if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) ) sscanf( sCodepoint.substr(2).c_str(), "%x", &c ); else if( sCodepoint.size() > 0 && utf8_get_char_len(sCodepoint[0]) == int(sCodepoint.size()) ) { c = utf8_get_char( sCodepoint.c_str() ); if(c == wchar_t(-1)) LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); } else if( !FontCharAliases::GetChar(sCodepoint, c) ) { LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); continue; } cfg.CharToGlyphNo[c] = atoi( sValue ); continue; } if( sName.substr(0, 6) == "RANGE " ) { /* * range CODESET=first_frame or * range CODESET #start-end=first_frame * eg * range CP1252=0 (default for 256-frame fonts) * range ASCII=0 (default for 128-frame fonts) * * (Start and end are in hex.) * * Map two high-bit portions of ISO-8859- to one font: * range ISO-8859-2 #80-FF=0 * range ISO-8859-3 #80-FF=128 * * Map hiragana to 0-84: * range Unicode #3041-3094=0 */ vector<CString> asMatches; static Regex parse("^RANGE ([A-Z\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$"); bool bMatch = parse.Compare( sName, asMatches ); ASSERT( asMatches.size() == 4 ); /* 4 parens */ if( !bMatch || asMatches[0].empty() ) RageException::Throw("Font definition '%s' has an invalid range '%s': parse error", ini.GetPath().c_str(), sName.c_str() ); /* We must have either 1 match (just the codeset) or 4 (the whole thing). */ int iCount = -1; int iFirst = 0; if( !asMatches[2].empty() ) { sscanf( asMatches[2].c_str(), "%x", &iFirst ); int iLast; sscanf( asMatches[3].c_str(), "%x", &iLast ); if( iLast < iFirst ) RageException::Throw("Font definition '%s' has an invalid range '%s': %i < %i.", ini.GetPath().c_str(), sName.c_str(), iLast < iFirst ); iCount = iLast - iFirst + 1; } CString sRet = cfg.MapRange( asMatches[0], iFirst, atoi(sValue), iCount ); if( !sRet.empty() ) RageException::Throw( "Font definition '%s' has an invalid range '%s': %s.", ini.GetPath().c_str(), sName.c_str(), sRet.c_str() ); continue; } if( sName.substr(0, 5) == "LINE " ) { /* line ROW=CHAR1CHAR2CHAR3CHAR4 * eg. * line 0=ABCDEFGH * * This lets us assign characters very compactly and readably. */ CString sRowStr = sName.substr(5); ASSERT( IsAnInt(sRowStr) ); const int iRow = atoi( sRowStr.c_str() ); const int iFirstFrame = iRow * iNumFramesWide; if( iRow > iNumFramesHigh ) RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high", ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh ); /* Decode the string. */ const wstring wdata( CStringToWstring(sValue) ); if( int(wdata.size()) > iNumFramesWide ) RageException::Throw( "The font definition \"%s\" assigns %i characters to row %i (\"%ls\"), but the font only has %i characters wide", ini.GetPath().c_str(), wdata.size(), iRow, wdata.c_str(), iNumFramesWide ); for( unsigned i = 0; i < wdata.size(); ++i ) cfg.CharToGlyphNo[wdata[i]] = iFirstFrame+i; } } }
void TitleSubst::Load(const CString &filename, const CString §ion) { RageFile f; if( !f.Open(filename) ) { LOG->Trace("Error opening %s: %s", filename.c_str(), f.GetError().c_str() ); return; } CString CurrentSection; TitleTrans tr; while (!f.AtEOF()) { CString line; int ret = f.GetLine( line ); if( ret == 0 ) break; if( ret < 0 ) { LOG->Trace("Error reading %s: %s", filename.c_str(), f.GetError().c_str() ); break; } if(line.size() > 0 && utf8_get_char(line.c_str()) == 0xFEFF) { /* Annoying header that Windows puts on UTF-8 plaintext * files; remove it. */ line.erase(0, utf8_get_char_len(line[0])); } TrimLeft(line); TrimRight(line); if(line.size() == 0) continue; /* blank */ if(line[0] == '#') continue; /* comment */ if(!line.CompareNoCase("DontTransliterate")) { tr.translit = false; continue; } size_t pos = line.find_first_of(':'); if(pos != string::npos) { /* x: y */ CString id = line.substr(0, pos); CString txt = line.substr(pos+1); TrimLeft(txt); /* Surround each regex with ^(...)$, to force all comparisons to default * to being a full-line match. (Add ".*" manually if this isn't wanted.) */ if(!id.CompareNoCase("TitleFrom")) tr.TitleFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("ArtistFrom")) tr.ArtistFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("SubtitleFrom")) tr.SubFrom = "^(" + txt + ")$"; else if(!id.CompareNoCase("TitleTo")) tr.Dest.Title = txt; else if(!id.CompareNoCase("ArtistTo")) tr.Dest.Artist = txt; else if(!id.CompareNoCase("SubtitleTo")) tr.Dest.Subtitle = txt; else if(!id.CompareNoCase("TitleTransTo")) tr.Dest.TitleTranslit = txt; else if(!id.CompareNoCase("ArtistTransTo")) tr.Dest.ArtistTranslit = txt; else if(!id.CompareNoCase("SubtitleTransTo")) tr.Dest.SubtitleTranslit = txt; else LOG->Warn( "Unknown TitleSubst tag: \"%s\"", id.c_str() ); } /* Add the translation if this is a terminator (*) or section * marker ([foo]). */ if(line[0] == '*' || line[0] == '[') { if(!CurrentSection.CompareNoCase(section)) AddTrans(tr); /* Reset. */ tr = TitleTrans(); } if(line[0] == '[' && line[line.size()-1] == ']') { CurrentSection = line.substr(1, line.size()-2); } } }
bool CIniFile::ReadString(const char* ini_str) { CString line; CString keyname, valuename, value; CString::size_type pLeft, pRight; Clear(); CString _str = ini_str; while( getline( _str, line)) { // To be compatible with Win32, check for existence of '\r'. // Win32 files have the '\r' and Unix files don't at the end of a line. // Note that the '\r' will be written to INI files from // Unix so that the created INI file can be read under Win32 // without change. //printf("str=%s \n line=%s\n",_str.c_str(),line.c_str()); if ( line[line.length() - 1] == '\r') line = line.substr( 0, line.length() - 1); if ( line.length()) { // Check that the user hasn't openned a binary file by checking the first // character of each line! if ( !isprint( line.at(0))) { // printf( "Failing on char %d\n", line[0]); // f.close(); // return false; }; if (( pLeft = line.find_first_of(";#[=:")) != CString::npos) { switch ( line[pLeft]) { case '[': if ((pRight = line.find_last_of("]")) != CString::npos && pRight > pLeft) { keyname = line.substr( pLeft + 1, pRight - pLeft - 1); AddKeyName( keyname); // printf("Section: %s\n",keyname.c_str()); } break; case '=': // case ':': valuename = line.substr( 0, pLeft); value = line.substr( pLeft + 1); AddValue( keyname, valuename, value); // printf("%s=%s\n",valuename.c_str(),value.c_str()); break; case ';': case '#': if ( !names.size()) HeaderComment( line.substr( pLeft + 1)); else KeyComment( keyname, line.substr( pLeft + 1)); break; };//switch() }//if(( pLeft = line.find_first_of(";#[=")) != CString::npos) };//if ( line.length()) };//while( getline( ini_str, line)) if(minSize <= 0) return true; if ( names.size()) return true; return false; };
bool CIniFile::ReadFile(const CString& _path) { // Normally you would use ifstream, but the SGI CC compiler has // a few bugs with ifstream. So ... fstream used. ifstream f; CString line; CString keyname, valuename, value; CString::size_type pLeft, pRight; //если файл испортили из-вне. //проверка испорченности файла: открытие f.open( _path.c_str()); if ( f.fail()){ printf("Warning: ini file:'%s' is NOT OPENED\n", _path.c_str()); f.close(); return false; }; //проверка испорченности файла: проверяем размер if((minSize > 0) && (size_of_stream(f) < minSize)){ printf("Warning: ini file:'%s' is suspiciously SMALL\n", _path.c_str()); f.close(); return false; }; try{ Clear(); while( getline( f, line)) { // To be compatible with Win32, check for existence of '\r'. // Win32 files have the '\r' and Unix files don't at the end of a line. // Note that the '\r' will be written to INI files from // Unix so that the created INI file can be read under Win32 // without change. //printf("str=%s \n line=%s\n",_str.c_str(),line.c_str()); if ( line[line.length() - 1] == '\r') line = line.substr( 0, line.length() - 1); if ( line.length()) { // Check that the user hasn't openned a binary file by checking the first // character of each line! // if ( !isprint( line[0])) { // printf( "Failing on char %d\n", line[0]); // f.close(); // return false; // }; if (( pLeft = line.find_first_of(";#[=:")) != CString::npos) { switch ( line[pLeft]) { case '[': if ((pRight = line.find_last_of("]")) != CString::npos && pRight > pLeft) { keyname = trim(line.substr( pLeft + 1, pRight - pLeft - 1)); AddKeyName(keyname); //printf("Section: %s\n",keyname.c_str()); } break; case '=': valuename = trim(line.substr( 0, pLeft)); value = trim(line.substr( pLeft + 1)); SetValue( keyname, valuename, value); break; // // case ':': // valuename = line.substr( 0, pLeft); // value = line.substr( pLeft + 1); // AddValue( keyname, valuename, value); // break; case ';': case '#': if ( !names.size()) HeaderComment( line.substr( pLeft + 1)); else KeyComment( keyname, line.substr( pLeft + 1)); break; };//switch() }//if(( pLeft = line.find_first_of(";#[=")) != CString::npos) };//if ( line.length()) };//while( getline( ini_str, line)) }catch(...){ }; f.close(); //проверка испорченности файла: проверяем размер if(minSize<=0) return true; if(0 == names.size()){ printf("Warning: ini file:'%s' is NOT contain any names\n", _path.c_str()); return false; }; return (CheckFile()); }