| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784 |
- /*
- * FreeRTOS+FAT V2.3.3
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. 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, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * 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. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
- /**
- * @file ff_string.c
- * @ingroup STRING
- *
- * @defgroup STRING FreeRTOS+FAT String Library
- * @brief Portable String Library for FreeRTOS+FAT
- *
- *
- **/
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "ff_headers.h"
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- #include <wchar.h>
- #include <wctype.h>
- #endif
- /*
- * These will eventually be moved into a platform independent string
- * library. Which will be optional. (To allow the use of system specific versions).
- */
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- void FF_cstrntowcs( FF_T_WCHAR * wcsDest,
- const char * szpSource,
- uint32_t ulLength )
- {
- while( ( *szpSource != '\0' ) && ( ulLength-- != 0 ) )
- {
- *( wcsDest++ ) = *( szpSource++ );
- }
- *wcsDest = '\0';
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /*-----------------------------------------------------------*/
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- void FF_cstrtowcs( FF_T_WCHAR * wcsDest,
- const char * szpSource )
- {
- while( *szpSource != '\0' )
- {
- *wcsDest++ = ( FF_T_WCHAR ) *( szpSource++ );
- }
- *wcsDest = '\0';
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /*-----------------------------------------------------------*/
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- void FF_wcstocstr( char * szpDest,
- const FF_T_WCHAR * wcsSource )
- {
- while( *wcsSource != '\0' )
- {
- *szpDest++ = ( int8_t ) *( wcsSource++ );
- }
- *szpDest = '\0';
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /*-----------------------------------------------------------*/
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- void FF_wcsntocstr( char * szpDest,
- const FF_T_WCHAR * wcsSource,
- uint32_t ulLength )
- {
- while( ( *wcsSource != '\0' ) && ( ulLength-- != 0 ) )
- {
- *( szpDest++ ) = ( int8_t ) *( wcsSource++ );
- }
- *szpDest = '\0';
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /*-----------------------------------------------------------*/
- /*-----------------------------------------------------------*/
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
- void FF_toupper( FF_T_WCHAR * string,
- uint32_t ulLength )
- {
- uint32_t i;
- for( i = 0; i < ulLength; i++ )
- {
- string[ i ] = towupper( string[ i ] );
- }
- }
- /*-----------------------------------------------------------*/
- void FF_tolower( FF_T_WCHAR * string,
- uint32_t ulLength )
- {
- uint32_t i;
- for( i = 0; i < ulLength; i++ )
- {
- string[ i ] = towlower( string[ i ] );
- }
- }
- /*-----------------------------------------------------------*/
- #else /* ffconfigUNICODE_UTF16_SUPPORT */
- void FF_toupper( char * string,
- uint32_t ulLength )
- {
- uint32_t i;
- for( i = 0; i < ulLength; i++ )
- {
- if( ( string[ i ] >= 'a' ) && ( string[ i ] <= 'z' ) )
- {
- string[ i ] -= 32;
- }
- if( string[ i ] == '\0' )
- {
- break;
- }
- }
- }
- /*-----------------------------------------------------------*/
- void FF_tolower( char * string,
- uint32_t ulLength )
- {
- uint32_t i;
- for( i = 0; i < ulLength; i++ )
- {
- if( ( string[ i ] >= 'A' ) && ( string[ i ] <= 'Z' ) )
- {
- string[ i ] += 32;
- }
- if( string[ i ] == '\0' )
- {
- break;
- }
- }
- }
- /*-----------------------------------------------------------*/
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /**
- * @private
- * @brief Compares 2 strings for the specified length, and returns pdTRUE is they are identical
- * otherwise pdFALSE is returned.
- *
- **/
- #if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
- BaseType_t FF_strmatch( const char * str1,
- const char * str2,
- BaseType_t xLength )
- {
- register BaseType_t i;
- register char char1, char2;
- if( xLength == 0 )
- {
- xLength = strlen( str1 );
- if( xLength != ( BaseType_t ) strlen( str2 ) )
- {
- return pdFALSE;
- }
- }
- for( i = 0; i < xLength; i++ )
- {
- char1 = str1[ i ];
- char2 = str2[ i ];
- if( ( char1 >= 'A' ) && ( char1 <= 'Z' ) )
- {
- char1 += 32;
- }
- if( ( char2 >= 'A' ) && ( char2 <= 'Z' ) )
- {
- char2 += 32;
- }
- if( char1 != char2 )
- {
- return pdFALSE;
- }
- }
- return pdTRUE;
- }
- #else /* ffconfigUNICODE_UTF16_SUPPORT */
- BaseType_t FF_strmatch( const FF_T_WCHAR * str1,
- const FF_T_WCHAR * str2,
- BaseType_t xLength )
- {
- register BaseType_t i;
- register FF_T_WCHAR char1, char2;
- if( xLength == 0 )
- {
- xLength = wcslen( str1 );
- if( xLength != wcslen( str2 ) )
- {
- return pdFALSE;
- }
- }
- for( i = 0; i < xLength; i++ )
- {
- char1 = towlower( str1[ i ] );
- char2 = towlower( str2[ i ] );
- if( char1 != char2 )
- {
- return pdFALSE;
- }
- }
- return pdTRUE;
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /**
- * @private
- * @brief A re-entrant Strtok function. No documentation is provided :P
- * Use at your own risk. (This is for FreeRTOS+FAT's use only).
- **/
- #if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
- char * FF_strtok( const char * string,
- char * token,
- uint16_t * tokenNumber,
- BaseType_t * last,
- BaseType_t xLength )
- {
- uint16_t i, y, tokenStart, tokenEnd = 0;
- i = 0;
- y = 0;
- if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
- {
- i++;
- }
- tokenStart = i;
- while( i < xLength )
- {
- if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
- {
- y++;
- if( y == *tokenNumber )
- {
- tokenStart = ( uint16_t ) ( i + 1 );
- }
- if( y == ( *tokenNumber + 1 ) )
- {
- tokenEnd = i;
- break;
- }
- }
- i++;
- }
- if( tokenEnd == 0 )
- {
- if( *last == pdTRUE )
- {
- return NULL;
- }
- else
- {
- *last = pdTRUE;
- }
- tokenEnd = i;
- }
- if( ( tokenEnd - tokenStart ) < ffconfigMAX_FILENAME )
- {
- memcpy( token, ( string + tokenStart ), ( uint32_t ) ( tokenEnd - tokenStart ) );
- token[ tokenEnd - tokenStart ] = '\0';
- }
- else
- {
- memcpy( token, ( string + tokenStart ), ( uint32_t ) ( ffconfigMAX_FILENAME ) );
- token[ ffconfigMAX_FILENAME - 1 ] = '\0';
- }
- /*token[tokenEnd - tokenStart] = '\0'; */
- *tokenNumber += 1;
- return token;
- }
- #else /* ffconfigUNICODE_UTF16_SUPPORT */
- FF_T_WCHAR * FF_strtok( const FF_T_WCHAR * string,
- FF_T_WCHAR * token,
- uint16_t * tokenNumber,
- BaseType_t * last,
- BaseType_t xLength )
- {
- uint16_t i, y, tokenStart, tokenEnd = 0;
- i = 0;
- y = 0;
- if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
- {
- i++;
- }
- tokenStart = i;
- while( i < xLength )
- {
- if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
- {
- y++;
- if( y == *tokenNumber )
- {
- tokenStart = ( uint16_t ) ( i + 1 );
- }
- if( y == ( *tokenNumber + 1 ) )
- {
- tokenEnd = i;
- break;
- }
- }
- i++;
- }
- if( tokenEnd == 0 )
- {
- if( *last == pdTRUE )
- {
- return NULL;
- }
- else
- {
- *last = pdTRUE;
- }
- tokenEnd = i;
- }
- if( ( tokenEnd - tokenStart ) < ffconfigMAX_FILENAME )
- {
- memcpy( token, ( string + tokenStart ), ( uint32_t ) ( tokenEnd - tokenStart ) * sizeof( FF_T_WCHAR ) );
- token[ tokenEnd - tokenStart ] = '\0';
- }
- else
- {
- memcpy( token, ( string + tokenStart ), ( uint32_t ) ( ffconfigMAX_FILENAME ) * sizeof( FF_T_WCHAR ) );
- token[ ffconfigMAX_FILENAME - 1 ] = '\0';
- }
- /*token[tokenEnd - tokenStart] = '\0'; */
- *tokenNumber += 1;
- return token;
- }
- #endif /* ffconfigUNICODE_UTF16_SUPPORT */
- /* UTF-8 Routines */
- /*
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
- * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
- */
- #if ( ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
- UBaseType_t FF_GetUtf16SequenceLen( uint16_t usLeadChar )
- {
- UBaseType_t uxReturn;
- if( ( usLeadChar & 0xFC00 ) == 0xD800 )
- {
- uxReturn = 2;
- }
- else
- {
- uxReturn = 1;
- }
- return uxReturn;
- } /* FF_GetUtf16SequenceLen() */
- #endif /* if ( ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 ) */
- /*-----------------------------------------------------------*/
- /*
- * Returns the number of UTF-8 units read.
- * Will not exceed ulSize UTF-16 units. (ulSize * 2 bytes).
- */
- /*
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
- * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
- */
- #if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
- int32_t FF_Utf8ctoUtf16c( uint16_t * utf16Dest,
- const uint8_t * utf8Source,
- uint32_t ulSize )
- {
- uint32_t ulUtf32char;
- uint16_t utf16Source = 0;
- register int32_t lSequenceNumber = 0;
- /* Count number of set bits before a zero. */
- while( ( *utf8Source != '\0' ) && (*utf8Source & ( 0x80 >> ( lSequenceNumber ) ) ) ) // ZJH modification
- {
- lSequenceNumber++;
- }
- if( lSequenceNumber == 0UL )
- {
- lSequenceNumber++;
- }
- if( ulSize == 0UL )
- {
- /* Returned value becomes an error, with the highest bit set. */
- lSequenceNumber = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF8CTOUTF16C;
- }
- else
- {
- switch( lSequenceNumber )
- {
- case 1:
- utf16Source = ( uint16_t ) *utf8Source;
- memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
- break;
- case 2:
- utf16Source = ( uint16_t ) ( ( *utf8Source & 0x1F ) << 6 ) | ( ( *( utf8Source + 1 ) & 0x3F ) );
- memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
- break;
- case 3:
- utf16Source = ( uint16_t ) ( ( *utf8Source & 0x0F ) << 12 ) | ( ( *( utf8Source + 1 ) & 0x3F ) << 6 ) | ( ( *( utf8Source + 2 ) & 0x3F ) );
- memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
- break;
- case 4:
- if( ulSize < 2 )
- {
- /* Returned value becomes an error. */
- lSequenceNumber = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF8CTOUTF16C;
- }
- else
- {
- /* Convert to UTF-32 and then into UTF-16 */
- ulUtf32char = ( uint16_t )
- ( ( *utf8Source & 0x0F ) << 18 ) |
- ( ( *( utf8Source + 1 ) & 0x3F ) << 12 ) |
- ( ( *( utf8Source + 2 ) & 0x3F ) << 6 ) |
- ( ( *( utf8Source + 3 ) & 0x3F ) );
- utf16Source = ( uint16_t ) ( ( ( ulUtf32char - 0x10000 ) & 0xFFC00 ) >> 10 ) | 0xD800;
- memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
- utf16Source = ( uint16_t ) ( ( ( ulUtf32char - 0x10000 ) & 0x003FF ) >> 00 ) | 0xDC00;
- memcpy( utf16Dest + 1, &utf16Source, sizeof( uint16_t ) );
- }
- break;
- default:
- break;
- }
- }
- return lSequenceNumber;
- } /* FF_Utf8ctoUtf16c() */
- #endif /* ffconfigUNICODE_UTF8_SUPPORT */
- /*-----------------------------------------------------------*/
- /*
- * Returns the number of UTF-8 units required to encode the UTF-16 sequence.
- * Will not exceed ulSize UTF-8 units. (ulSize * 1 bytes).
- */
- #if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
- int32_t FF_Utf16ctoUtf8c( uint8_t * utf8Dest,
- const uint16_t * utf16Source,
- uint32_t ulSize )
- {
- uint32_t ulUtf32char;
- uint16_t ulUtf16char;
- int32_t lReturn = 0L;
- do
- {
- if( ulSize == 0UL )
- {
- lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
- break;
- }
- memcpy( &ulUtf16char, utf16Source, sizeof( uint16_t ) );
- /* A surrogate sequence was encountered. Must transform to UTF32 first. */
- if( ( ulUtf16char & 0xF800 ) == 0xD800 )
- {
- ulUtf32char = ( ( uint32_t ) ( ulUtf16char & 0x003FF ) << 10 ) + 0x10000;
- memcpy( &ulUtf16char, utf16Source + 1, sizeof( uint16_t ) );
- if( ( ulUtf16char & 0xFC00 ) != 0xDC00 )
- {
- /* Invalid UTF-16 sequence. */
- lReturn = FF_ERR_UNICODE_INVALID_SEQUENCE | FF_UTF16CTOUTF8C;
- break;
- }
- ulUtf32char |= ( ( uint32_t ) ( ulUtf16char & 0x003FF ) );
- }
- else
- {
- ulUtf32char = ( uint32_t ) ulUtf16char;
- }
- /* Now convert to the UTF-8 sequence. */
- /* Single byte UTF-8 sequence. */
- if( ulUtf32char < 0x00000080 )
- {
- *( utf8Dest + 0 ) = ( uint8_t ) ulUtf32char;
- lReturn = 1;
- break;
- }
- /* Double byte UTF-8 sequence. */
- if( ulUtf32char < 0x00000800 )
- {
- if( ulSize < 2 )
- {
- lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
- }
- else
- {
- *( utf8Dest + 0 ) = ( uint8_t ) ( 0xC0 | ( ( ulUtf32char >> 6 ) & 0x1F ) );
- *( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
- lReturn = 2;
- }
- break;
- }
- /* Triple byte UTF-8 sequence. */
- if( ulUtf32char < 0x00010000 )
- {
- if( ulSize < 3 )
- {
- lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
- }
- else
- {
- *( utf8Dest + 0 ) = ( uint8_t ) ( 0xE0 | ( ( ulUtf32char >> 12 ) & 0x0F ) );
- *( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 6 ) & 0x3F ) );
- *( utf8Dest + 2 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
- lReturn = 3;
- }
- break;
- }
- /* Quadruple byte UTF-8 sequence. */
- if( ulUtf32char < 0x00200000 )
- {
- if( ulSize < 4 )
- {
- lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
- }
- else
- {
- *( utf8Dest + 0 ) = ( uint8_t ) ( 0xF0 | ( ( ulUtf32char >> 18 ) & 0x07 ) );
- *( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 12 ) & 0x3F ) );
- *( utf8Dest + 2 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 6 ) & 0x3F ) );
- *( utf8Dest + 3 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
- lReturn = 4;
- }
- break;
- }
- lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF16CTOUTF8C; /* Invalid Character */
- }
- while( pdFALSE );
- return lReturn;
- } /* FF_Utf16ctoUtf8c() */
- #endif /* ffconfigUNICODE_UTF8_SUPPORT */
- /*-----------------------------------------------------------*/
- /* UTF-16 Support Functions */
- /* Converts a UTF-32 Character into its equivalent UTF-16 sequence. */
- #if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF )
- int32_t FF_Utf32ctoUtf16c( uint16_t * utf16Dest,
- uint32_t utf32char,
- uint32_t ulSize )
- {
- int32_t lReturn;
- /* Check that its a valid UTF-32 wide-char! */
- /* This range is not a valid Unicode code point. */
- if( ( utf32char >= 0xD800 ) && ( utf32char <= 0xDFFF ) )
- {
- lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF32CTOUTF16C; /* Invalid character. */
- }
- else if( utf32char < 0x10000 )
- {
- *utf16Dest = ( uint16_t ) utf32char; /* Simple conversion! Char comes within UTF-16 space (without surrogates). */
- lReturn = 1;
- }
- else if( ulSize < 2 )
- {
- lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF32CTOUTF16C; /* Not enough UTF-16 units to record this character. */
- }
- else if( utf32char < 0x00200000 )
- {
- /* Conversion to a UTF-16 Surrogate pair! */
- /*valueImage = utf32char - 0x10000; */
- *( utf16Dest + 0 ) = ( uint16_t ) ( ( ( utf32char - 0x10000 ) & 0xFFC00 ) >> 10 ) | 0xD800;
- *( utf16Dest + 1 ) = ( uint16_t ) ( ( ( utf32char - 0x10000 ) & 0x003FF ) >> 00 ) | 0xDC00;
- lReturn = 2; /* Surrogate pair encoded value. */
- }
- else
- {
- /* Invalid Character */
- lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF32CTOUTF16C;
- }
- return lReturn;
- } /* FF_Utf32ctoUtf16c() */
- #endif /* #if( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) */
- /*-----------------------------------------------------------*/
- /* Converts a UTF-16 sequence into its equivalent UTF-32 code point. */
- #if ( ffconfigNOT_USED_FOR_NOW != 0 )
- int32_t FF_Utf16ctoUtf32c( uint32_t * utf32Dest,
- const uint16_t * utf16Source )
- {
- int32_t lReturn;
- /*Not a surrogate sequence. */
- if( ( *utf16Source & 0xFC00 ) != 0xD800 )
- {
- *utf32Dest = ( uint32_t ) *utf16Source;
- lReturn = 1; /* A single UTF-16 item was used to represent the character. */
- }
- else
- {
- *utf32Dest = ( ( uint32_t ) ( *( utf16Source + 0 ) & 0x003FF ) << 10 ) + 0x10000;
- if( ( *( utf16Source + 1 ) & 0xFC00 ) != 0xDC00 )
- {
- lReturn = FF_ERR_UNICODE_INVALID_SEQUENCE | FF_UTF16CTOUTF32C; /* Invalid UTF-16 sequence. */
- }
- else
- {
- *utf32Dest |= ( ( uint32_t ) ( *( utf16Source + 1 ) & 0x003FF ) );
- lReturn = 2; /* 2 utf-16 units make up the Unicode code-point. */
- }
- }
- return lReturn;
- } /* FF_Utf16ctoUtf32c() */
- #endif /* ffconfigNOT_USED_FOR_NOW */
- /*-----------------------------------------------------------*/
- /*
- * Returns the total number of UTF-16 items required to represent
- * the provided UTF-32 string in UTF-16 form.
- */
- /*
- * UBaseType_t FF_Utf32GetUtf16Len( const uint32_t *utf32String )
- * {
- * UBaseType_t utf16len = 0;
- *
- * while( *utf32String )
- * {
- * if( *utf32String++ <= 0xFFFF )
- * {
- * utf16len++;
- * }
- * else
- * {
- * utf16len += 2;
- * }
- * }
- *
- * return utf16len;
- * }
- */
- /*-----------------------------------------------------------*/
- /* String conversions */
- #if ( ffconfigNOT_USED_FOR_NOW != 0 )
- int32_t FF_Utf32stoUtf8s( uint8_t * Utf8String,
- uint32_t * Utf32String )
- {
- int i = 0, y = 0;
- uint16_t utf16buffer[ 2 ];
- while( Utf32String[ i ] != '\0' )
- {
- /* Convert to a UTF16 char. */
- FF_Utf32ctoUtf16c( utf16buffer, Utf32String[ i ], 2 );
- /* Now convert the UTF16 to UTF8 sequence. */
- y += FF_Utf16ctoUtf8c( &Utf8String[ y ], utf16buffer, 4 );
- i++;
- }
- Utf8String[ y ] = '\0';
- return 0;
- } /* FF_Utf32stoUtf8s() */
- #endif /* ffconfigNOT_USED_FOR_NOW */
- /*-----------------------------------------------------------*/
|