//fs_unicode.c #include #include "fs_common.h" //void _FAT_unicode_init_default() // ANSI CODE PAGE //{ // _L2UTable = NULL; // _U2LTable = NULL; // _ankTable = NULL; //} static inline const char* _FAT_utf8decode(const char* utf8, u16 *ucs) { unsigned char c = *utf8++; unsigned long code; int tail = 0; if ((c <= 0x7f) || (c >= 0xc2)) { /* Start of new character. */ if (c < 0x80) { /* U-00000000 - U-0000007F, 1 byte */ code = c; } else if (c < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */ tail = 1; code = c & 0x1f; } else if (c < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */ tail = 2; code = c & 0x0f; } else if (c < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */ tail = 3; code = c & 0x07; } else { /* Invalid size. */ code = 0; } while (tail-- && ((c = *utf8++) != 0)) { if ((c & 0xc0) == 0x80) { /* Valid continuation character. */ code = (code << 6) | (c & 0x3f); } else { /* Invalid continuation char */ code = 0xfffd; utf8--; break; } } } else { /* Invalid UTF-8 char */ code = 0; } /* currently we don't support chars above U-FFFF */ *ucs = (code < 0x10000) ? code : 0; return utf8; } void _FAT_utf8_to_unicode16( const char* src, unsigned short* dest ) { while('\0' != *src) { src = _FAT_utf8decode(src, dest++); } *dest = '\0'; } #if 0 static inline int _FAT_utf8coding(const u16* ucs, char* dest) { int len= 0; if (*ucs < 0x80) //one byte { dest[len++] = *ucs; } else if (*ucs < 0x800) //two bytes { dest[len++] = 0xC0 | (*ucs >> 6 & 0x1F); dest[len++] = 0x80 | (*ucs & 0x3F); } else //if(*ucs < 0x10000) //three bytes { dest[len++] = 0xE0 | (*ucs >> 12); dest[len++] = 0x80 | (*ucs >>6 & 0x3F); dest[len++] = 0x80 | (*ucs &0x3F); } return len; } #endif void _FAT_unicode16_to_utf8( const u16* src, char* dest) { int len=0; while(*src) { if (*src < 0x80) //1 byte { dest[len++] = *src; } else if (*src < 0x800) //2 bytes { dest[len++] = 0xC0 | (*src >> 6 & 0x1F); dest[len++] = 0x80 | (*src & 0x3F); } else //if(*src < 0x10000) //3 bytes { dest[len++] = 0xE0 | (*src >> 12); dest[len++] = 0x80 | (*src >>6 & 0x3F); dest[len++] = 0x80 | (*src &0x3F); } src ++; } dest[len] = 0; } u32 _unistrnlen( const u16* unistr, u32 maxlen ) { const u16 * pstr = NULL; u32 len = 0; if( NULL == unistr ) return 0; if( 0 == maxlen ) return 0; pstr = unistr; while( len < maxlen && *pstr != 0x0000 ) { ++len; ++pstr; } return len; } int _unistrncmp( const u16* src, const u16* dest, u32 maxlen ) { if( NULL == src || NULL == dest ) { if( src == dest ) return 0; return (NULL == src ) ? -1 : 1; } while( *src == *dest && maxlen && *src != 0x0000 && *dest != 0x0000 ) { ++src; ++dest; --maxlen; } if( 0 == maxlen ) return 0; return *src > *dest ? 1 : -1; } const u16 * _unistrchr( const u16 * str, u16 unichar ) { if( NULL == str ) return NULL; while( *str != unichar && *str != 0x0000 ) { ++str; } return str; } int _uniisalnum( u8 ch ) { return isalnum( ch ); }