in ff_dir.c [2187:2367]
void FF_CreateShortName( FF_FindParams_t * pxFindParams,
const FF_T_WCHAR * pcLongName )
#else
void FF_CreateShortName( FF_FindParams_t * pxFindParams,
const char * pcLongName )
#endif
{
BaseType_t xIndex, xPosition, xLastDot;
uint16_t NameLen;
#if ( ffconfigSHORTNAME_CASE != 0 )
uint8_t testAttrib = FF_FAT_CASE_ATTR_BASE;
#endif
/* Examples:
* "readme.TXT" will get the attribute FF_FAT_CASE_ATTR_BASE
* "README.txt" will get the attribute FF_FAT_CASE_ATTR_EXT
* "Readme.txt" can not be store as a short name */
pxFindParams->ucCaseAttrib = 0; /* May get the value FF_FAT_CASE_ATTR_BASE or FF_FAT_CASE_ATTR_EXT */
pxFindParams->ucFirstTilde = 6; /* The numerical position of the ~ */
pxFindParams->ulFlags |= FIND_FLAG_SHORTNAME_SET | FIND_FLAG_FITS_SHORT | FIND_FLAG_SIZE_OK;
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
{
NameLen = ( uint16_t ) wcslen( pcLongName );
}
#else
{
NameLen = ( uint16_t ) strlen( pcLongName );
}
#endif
/* Does pcLongName fit a shortname? */
for( xIndex = 0, xPosition = 0, xLastDot = NameLen; xIndex < NameLen; xIndex++ )
{
if( pcLongName[ xIndex ] != '.' )
{
xPosition++;
}
else
{
xLastDot = xIndex;
}
}
/* For example:
* "FILENAME.EXT": NameLen = 12, xLastDot = 8, xPosition = 11
* ".cproject" : NameLen = 9, xLastDot = 0, xPosition = 8
*/
if( ( NameLen > 12 ) || /* If name is longer than 12 characters (8.3). */
( NameLen - xPosition > 1 ) || /* If it contains more than 1 dot. */
( NameLen - xLastDot > 4 ) || /* If the file name extension is longer than 3 characters. */
( xLastDot > 8 ) ) /* If the file name base is too long. */
{
pxFindParams->ulFlags &= ~FIND_FLAG_SIZE_OK;
}
for( xIndex = 0, xPosition = 0; xIndex < 11; xPosition++ )
{
char ch = pcLongName[ xPosition ];
if( !ch )
{
break;
}
if( ( xIndex == 0 ) && ( ch == '.' ) )
{
pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT;
continue;
}
if( xPosition == xLastDot )
{
/* Remember where we put the first space. */
if( pxFindParams->ucFirstTilde > xIndex )
{
pxFindParams->ucFirstTilde = xIndex;
}
while( xIndex < 8 )
{
pxFindParams->pcEntryBuffer[ xIndex++ ] = 0x20;
}
#if ( ffconfigSHORTNAME_CASE != 0 )
{
testAttrib = FF_FAT_CASE_ATTR_EXT;
}
#endif
}
else
{
if( xIndex == 8 )
{
if( xPosition <= xLastDot )
{
xPosition = xLastDot;
ch = ( int8_t ) pcLongName[ xPosition ];
if( ch == '\0' )
{
break;
}
ch = ( int8_t ) pcLongName[ ++xPosition ];
#if ( ffconfigSHORTNAME_CASE != 0 )
{
testAttrib = FF_FAT_CASE_ATTR_EXT;
}
#endif
}
}
if( !FF_ValidShortChar( ch ) )
{
pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT;
continue;
}
#if ( ffconfigSHORTNAME_CASE != 0 )
{
if( ( ch >= 'a' ) && ( ch <= 'z' ) )
{
ch -= 0x20;
if( testAttrib )
{
pxFindParams->ucCaseAttrib |= testAttrib;
}
else
{
pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT; /* We had capital: does not fit. */
}
}
else if( ( ch >= 'A' ) && ( ch <= 'Z' ) )
{
if( ( pxFindParams->ucCaseAttrib & testAttrib ) != 0 )
{
pxFindParams->ulFlags &= ~FIND_FLAG_FITS_SHORT; /* We had lower-case: does not fit. */
}
testAttrib = 0;
}
}
#else /* if ( ffconfigSHORTNAME_CASE != 0 ) */
{
if( ( ch >= 'a' ) && ( ch <= 'z' ) )
{
ch -= 0x20;
}
}
#endif /* ffconfigSHORTNAME_CASE */
pxFindParams->pcEntryBuffer[ xIndex++ ] = ch;
}
}
if( ( xLastDot == 0 ) && ( xIndex < 6 ) )
{
/* This is a file name like ".info" or ".root" */
pxFindParams->ucFirstTilde = xIndex;
}
while( xIndex < 11 )
{
pxFindParams->pcEntryBuffer[ xIndex++ ] = 0x20;
}
if( ( xLastDot < pxFindParams->ucFirstTilde ) && ( xLastDot > 0 ) )
{
pxFindParams->ucFirstTilde = xLastDot;
}
if( NameLen < pxFindParams->ucFirstTilde ) /* Names like "Abc" will become "~Abc". */
{
pxFindParams->ucFirstTilde = ( uint8_t ) NameLen;
}
} /* FF_CreateShortName() */