static FF_Error_t FF_CreateLFNs()

in ff_dir.c [2614:2799]


        static FF_Error_t FF_CreateLFNs( FF_IOManager_t * pxIOManager,
                                         uint32_t ulDirCluster,
                                         FF_T_WCHAR * pcName,
                                         uint8_t ucCheckSum,
                                         uint16_t usEntry )
    #else
        static FF_Error_t FF_CreateLFNs( FF_IOManager_t * pxIOManager,
                                         uint32_t ulDirCluster,
                                         char * pcName,
                                         uint8_t ucCheckSum,
                                         uint16_t usEntry )
    #endif /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
    {
        FF_Error_t xError = FF_ERR_NONE;
        BaseType_t xNumLFNs;
        BaseType_t xEndPos;
        BaseType_t xIndex, y;
        FF_FetchContext_t xFetchContext;
        uint8_t pucEntryBuffer[ FF_SIZEOF_DIRECTORY_ENTRY ];

        #if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
            int32_t slRetVal;
        #endif

        #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
            uint16_t usUtf16Name[ ffconfigMAX_FILENAME + 1 ];
        #endif

        #if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
            char * NamePtr;
        #else
            int16_t * NamePtr;
        #endif


        #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
            {
                #if WCHAR_MAX <= 0xFFFF
                    {
                        y = wcslen( pcName );

                        if( y > ffconfigMAX_FILENAME )
                        {
                            xError = ( FF_Error_t ) ( FF_ERR_DIR_NAME_TOO_LONG | FF_CREATELFNS );
                        }
                        else
                        {
                            wcsncpy( usUtf16Name, pcName, ffconfigMAX_FILENAME );
                        }
                    }
                #else /* if WCHAR_MAX <= 0xFFFF */
                    {
                        xIndex = 0;
                        y = 0;

                        while( pcName[ xIndex ] )
                        {
                            FF_Utf32ctoUtf16c( &usUtf16Name[ y ], ( uint32_t ) pcName[ xIndex ], ffconfigMAX_FILENAME - xIndex );
                            y += FF_GetUtf16SequenceLen( usUtf16Name[ y ] );
                            xIndex++;

                            if( y > ffconfigMAX_FILENAME )
                            {
                                xError = ( FF_Error_t ) ( FF_ERR_DIR_NAME_TOO_LONG | FF_CREATELFNS );
                                break;
                            }
                        }
                    }
                #endif /* if WCHAR_MAX <= 0xFFFF */
            }
        #endif /* ffconfigUNICODE_UTF16_SUPPORT */

        /* Convert the name into UTF-16 format. */
        #if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
            {
                /* Simply convert the UTF8 to UTF16 and be done with it. */
                xIndex = 0;
                y = 0;

                while( pcName[ xIndex ] != 0 )
                {
                    slRetVal = FF_Utf8ctoUtf16c( &( usUtf16Name[ y ] ), ( uint8_t * ) &( pcName[ xIndex ] ), ffconfigMAX_FILENAME - xIndex );

                    if( slRetVal > 0 )
                    {
                        xIndex += slRetVal;
                    }
                    else
                    {
                        break; /* No more space in the UTF-16 buffer, simply truncate for safety. */
                    }

                    y += FF_GetUtf16SequenceLen( usUtf16Name[ y ] );

                    if( y > ffconfigMAX_FILENAME )
                    {
                        xError = ( FF_Error_t ) ( FF_ERR_DIR_NAME_TOO_LONG | FF_CREATELFNS );
                        break;
                    }
                }
            }
        #elif ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
            {
                /* Just check the length. */
                y = strlen( pcName );

                if( y > ffconfigMAX_FILENAME )
                {
                    xError = ( FF_Error_t ) ( FF_ERR_DIR_NAME_TOO_LONG | FF_CREATELFNS );
                }
            }
        #endif /* if ( ffconfigUNICODE_UTF8_SUPPORT != 0 ) */

        /* Whole name is now in a valid UTF-16 format. Lets go make thos LFN's.
         * At this point, it should a be the length of the name. */
        if( FF_isERR( xError ) == pdFALSE )
        {
            xNumLFNs = y / 13;  /* Number of LFNs is the total number of UTF-16 units, divided by 13 ( 13 units per LFN ). */
            xEndPos = y % 13;   /* The ending position in an LFN, of the last LFN UTF-16 character. */

            if( xEndPos )
            {
                xNumLFNs++;
            }
            else
            {
                xEndPos = 13;
            }

            xError = FF_InitEntryFetch( pxIOManager, ulDirCluster, &xFetchContext );

            if( FF_isERR( xError ) == pdFALSE )
            {
                #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
                    {
                        NamePtr = ( int16_t * ) ( usUtf16Name + 13 * ( xNumLFNs - 1 ) );
                    }
                #elif ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
                    {
                        NamePtr = ( char * ) ( usUtf16Name + 13 * ( xNumLFNs - 1 ) );
                    }
                #else
                    {
                        NamePtr = pcName + 13 * ( xNumLFNs - 1 );
                    }
                #endif /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */

                /* After this point, xIndex is no longer the length of the Filename in UTF-16 units. */
                for( xIndex = xNumLFNs; xIndex > 0; xIndex-- )
                {
                    if( xIndex == xNumLFNs )
                    {
                        FF_CreateLFNEntry( pucEntryBuffer, ( uint8_t * ) NamePtr, ( UBaseType_t ) xEndPos, ( UBaseType_t ) xIndex, ucCheckSum );
                        pucEntryBuffer[ 0 ] |= 0x40;
                    }
                    else
                    {
                        FF_CreateLFNEntry( pucEntryBuffer, ( uint8_t * ) NamePtr, ( UBaseType_t ) 13u, ( UBaseType_t ) xIndex, ucCheckSum );
                    }

                    NamePtr -= 13;

                    xError = FF_PushEntryWithContext( pxIOManager, ( uint32_t ) ( usEntry + ( xNumLFNs - xIndex ) ), &xFetchContext, pucEntryBuffer );

                    if( FF_isERR( xError ) )
                    {
                        break;
                    }
                }

                {
                    FF_Error_t xTempError;

                    /* Release any buffers that were used. */
                    xTempError = FF_CleanupEntryFetch( pxIOManager, &xFetchContext );

                    if( FF_isERR( xTempError ) == pdFALSE )
                    {
                        xError = xTempError;
                    }
                }
            }
        }

        return xError;
    }   /* FF_CreateLFNs() */