smsvn -> ssc-hg glue: rearrange directory structure
This commit is contained in:
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* The original MSD format is simply:
|
||||
*
|
||||
* #PARAM0:PARAM1:PARAM2:PARAM3;
|
||||
* #NEXTPARAM0:PARAM1:PARAM2:PARAM3;
|
||||
*
|
||||
* (The first field is typically an identifier, but doesn't have to be.)
|
||||
*
|
||||
* The semicolon is not optional, though if we hit a # on a new line, eg:
|
||||
* #VALUE:PARAM1
|
||||
* #VALUE2:PARAM2
|
||||
* we'll recover.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include "MsdFile.h"
|
||||
#include "RageFile.h"
|
||||
#include "RageLog.h"
|
||||
#include "RageUtil.h"
|
||||
|
||||
void MsdFile::AddParam( const char *buf, int len )
|
||||
{
|
||||
values.back().params.push_back( RString(buf, len) );
|
||||
}
|
||||
|
||||
void MsdFile::AddValue() /* (no extra charge) */
|
||||
{
|
||||
values.push_back( value_t() );
|
||||
values.back().params.reserve( 32 );
|
||||
}
|
||||
|
||||
void MsdFile::ReadBuf( const char *buf, int len, bool bUnescape )
|
||||
{
|
||||
values.reserve( 64 );
|
||||
|
||||
bool ReadingValue=false;
|
||||
int i = 0;
|
||||
char *cProcessed = new char[len];
|
||||
int iProcessedLen = -1;
|
||||
while( i < len )
|
||||
{
|
||||
if( i+1 < len && buf[i] == '/' && buf[i+1] == '/' )
|
||||
{
|
||||
/* Skip a comment entirely; don't copy the comment to the value/parameter */
|
||||
do
|
||||
{
|
||||
i++;
|
||||
} while( i < len && buf[i] != '\n' );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ReadingValue && buf[i] == '#' )
|
||||
{
|
||||
/* Unfortunately, many of these files are missing ;'s.
|
||||
* If we get a # when we thought we were inside a value, assume we
|
||||
* missed the ;. Back up and end the value. */
|
||||
/* Make sure this # is the first non-whitespace character on the line. */
|
||||
bool FirstChar = true;
|
||||
int j = iProcessedLen;
|
||||
while( j > 0 && cProcessed[j - 1] != '\r' && cProcessed[j - 1] != '\n' )
|
||||
{
|
||||
if( cProcessed[j - 1] == ' ' || cProcessed[j - 1] == '\t' )
|
||||
{
|
||||
--j;
|
||||
continue;
|
||||
}
|
||||
|
||||
FirstChar = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !FirstChar )
|
||||
{
|
||||
/* We're not the first char on a line. Treat it as if it were a normal character. */
|
||||
cProcessed[iProcessedLen++] = buf[i++];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip newlines and whitespace before adding the value. */
|
||||
iProcessedLen = j;
|
||||
while( iProcessedLen > 0 &&
|
||||
( cProcessed[iProcessedLen - 1] == '\r' || cProcessed[iProcessedLen - 1] == '\n' ||
|
||||
cProcessed[iProcessedLen - 1] == ' ' || cProcessed[iProcessedLen - 1] == '\t' ) )
|
||||
--iProcessedLen;
|
||||
|
||||
AddParam( cProcessed, iProcessedLen );
|
||||
iProcessedLen = 0;
|
||||
ReadingValue=false;
|
||||
}
|
||||
|
||||
/* # starts a new value. */
|
||||
if( !ReadingValue && buf[i] == '#' )
|
||||
{
|
||||
AddValue();
|
||||
ReadingValue=true;
|
||||
}
|
||||
|
||||
if( !ReadingValue )
|
||||
{
|
||||
if( bUnescape && buf[i] == '\\' )
|
||||
i += 2;
|
||||
else
|
||||
++i;
|
||||
continue; /* nothing else is meaningful outside of a value */
|
||||
}
|
||||
|
||||
/* : and ; end the current param, if any. */
|
||||
if( iProcessedLen != -1 && (buf[i] == ':' || buf[i] == ';') )
|
||||
AddParam( cProcessed, iProcessedLen );
|
||||
|
||||
/* # and : begin new params. */
|
||||
if( buf[i] == '#' || buf[i] == ':' )
|
||||
{
|
||||
++i;
|
||||
iProcessedLen = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ; ends the current value. */
|
||||
if( buf[i] == ';' )
|
||||
{
|
||||
ReadingValue=false;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We've gone through all the control characters. All that is left is either an escaped character,
|
||||
* ie \#, \\, \:, etc., or a regular character. */
|
||||
if( bUnescape && i < len && buf[i] == '\\' )
|
||||
++i;
|
||||
if( i < len )
|
||||
{
|
||||
cProcessed[iProcessedLen++] = buf[i++];
|
||||
}
|
||||
}
|
||||
|
||||
/* Add any unterminated value at the very end. */
|
||||
if( ReadingValue )
|
||||
AddParam( cProcessed, iProcessedLen );
|
||||
|
||||
delete [] cProcessed;
|
||||
}
|
||||
|
||||
// returns true if successful, false otherwise
|
||||
bool MsdFile::ReadFile( RString sNewPath, bool bUnescape )
|
||||
{
|
||||
error = "";
|
||||
|
||||
RageFile f;
|
||||
/* Open a file. */
|
||||
if( !f.Open( sNewPath ) )
|
||||
{
|
||||
error = f.GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate a string to hold the file
|
||||
RString FileString;
|
||||
FileString.reserve( f.GetFileSize() );
|
||||
|
||||
int iBytesRead = f.Read( FileString );
|
||||
if( iBytesRead == -1 )
|
||||
{
|
||||
error = f.GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
ReadBuf( FileString.c_str(), iBytesRead, bUnescape );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MsdFile::ReadFromString( const RString &sString, bool bUnescape )
|
||||
{
|
||||
ReadBuf( sString.c_str(), sString.size(), bUnescape );
|
||||
}
|
||||
|
||||
RString MsdFile::GetParam(unsigned val, unsigned par) const
|
||||
{
|
||||
if( val >= GetNumValues() || par >= GetNumParams(val) )
|
||||
return RString();
|
||||
|
||||
return values[val].params[par];
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2001-2006 Chris Danford, Glenn Maynard
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
Reference in New Issue
Block a user