Beispiel #1
0
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 );
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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 &section)
{
	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);
		}
	}
}
Beispiel #8
0
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;
};
Beispiel #9
0
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());
}