?? unicode.c
字號:
char *locname = ToLocale( dirname ); int res; if( locname == NULL ) { errno = ENOENT; return -1; } res = mkdir( locname, mode ); LocaleFree( locname ); return res;#endif}/** * Opens a DIR pointer using UTF-8 paths * * @param dirname UTF-8 representation of the directory name * @return a pointer to the DIR struct, or NULL in case of error. * Release with standard closedir(). */DIR *utf8_opendir( const char *dirname ){#ifdef WIN32 wchar_t wname[MAX_PATH + 1]; if (MultiByteToWideChar (CP_UTF8, 0, dirname, -1, wname, MAX_PATH)) { wname[MAX_PATH] = L'\0'; return (DIR *)vlc_wopendir (wname); }#else const char *local_name = ToLocale( dirname ); if( local_name != NULL ) { DIR *dir = opendir( local_name ); LocaleFree( local_name ); return dir; }#endif errno = ENOENT; return NULL;}/** * Reads the next file name from an open directory. * * @param dir The directory that is being read * * @return a UTF-8 string of the directory entry. * Use free() to free this memory. */char *utf8_readdir( DIR *dir ){#ifdef WIN32 struct _wdirent *ent = vlc_wreaddir (dir); if (ent == NULL) return NULL; return FromWide (ent->d_name);#else struct dirent *ent; ent = readdir( (DIR *)dir ); if( ent == NULL ) return NULL; return vlc_fix_readdir( ent->d_name );#endif}static int dummy_select( const char *str ){ (void)str; return 1;}/** * Does the same as utf8_scandir(), but takes an open directory pointer * instead of a directory path. */int utf8_loaddir( DIR *dir, char ***namelist, int (*select)( const char * ), int (*compar)( const char **, const char ** ) ){ if( select == NULL ) select = dummy_select; if( dir == NULL ) return -1; else { char **tab = NULL; char *entry; unsigned num = 0; rewinddir( dir ); while( ( entry = utf8_readdir( dir ) ) != NULL ) { char **newtab; if( !select( entry ) ) { free( entry ); continue; } newtab = realloc( tab, sizeof( char * ) * (num + 1) ); if( newtab == NULL ) { free( entry ); goto error; } tab = newtab; tab[num++] = entry; } if( compar != NULL ) qsort( tab, num, sizeof( tab[0] ), (int (*)( const void *, const void *))compar ); *namelist = tab; return num; error:{ unsigned i; for( i = 0; i < num; i++ ) free( tab[i] ); if( tab != NULL ) free( tab ); } } return -1;}/** * Selects file entries from a directory, as GNU C scandir(), yet using * UTF-8 file names. * * @param dirname UTF-8 diretory path * @param pointer [OUT] pointer set, on succesful completion, to the address * of a table of UTF-8 filenames. All filenames must be freed with free(). * The table itself must be freed with free() as well. * * @return How many file names were selected (possibly 0), * or -1 in case of error. */int utf8_scandir( const char *dirname, char ***namelist, int (*select)( const char * ), int (*compar)( const char **, const char ** ) ){ DIR *dir = utf8_opendir (dirname); int val = -1; if (dir != NULL) { val = utf8_loaddir (dir, namelist, select, compar); closedir (dir); } return val;}static int utf8_statEx( const char *filename, struct stat *buf, bool deref ){#if defined (WIN32) || defined (UNDER_CE) /* retrieve Windows OS version */ if( GetVersion() < 0x80000000 ) { /* for Windows NT and above */ wchar_t wpath[MAX_PATH + 1]; if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH ) ) { errno = ENOENT; return -1; } wpath[MAX_PATH] = L'\0'; return _wstati64( wpath, buf ); }#endif#ifdef HAVE_SYS_STAT_H const char *local_name = ToLocale( filename ); if( local_name != NULL ) { int res = deref ? stat( local_name, buf ) : lstat( local_name, buf ); LocaleFree( local_name ); return res; } errno = ENOENT;#endif return -1;}/** * Finds file/inode informations, as stat(). * Consider usign fstat() instead, if possible. * * @param filename UTF-8 file path */int utf8_stat( const char *filename, struct stat *buf){ return utf8_statEx( filename, buf, true );}/** * Finds file/inode informations, as lstat(). * Consider usign fstat() instead, if possible. * * @param filename UTF-8 file path */int utf8_lstat( const char *filename, struct stat *buf){ return utf8_statEx( filename, buf, false );}/** * Removes a file. * * @param filename a UTF-8 string with the name of the file you want to delete. * @return A 0 return value indicates success. A -1 return value indicates an * error, and an error code is stored in errno */int utf8_unlink( const char *filename ){#if defined (WIN32) || defined (UNDER_CE) if( GetVersion() < 0x80000000 ) { /* for Windows NT and above */ wchar_t wpath[MAX_PATH + 1]; if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH ) ) { errno = ENOENT; return -1; } wpath[MAX_PATH] = L'\0'; /* * unlink() cannot open files with non-“ANSI” characters on Windows. * We use _wunlink() instead. */ return _wunlink( wpath ); }#endif const char *local_name = ToLocale( filename ); if( local_name == NULL ) { errno = ENOENT; return -1; } int ret = unlink( local_name ); LocaleFree( local_name ); return ret;}/** * Formats an UTF-8 string as vasprintf(), then print it to stdout, with * appropriate conversion to local encoding. */static int utf8_vasprintf( char **str, const char *fmt, va_list ap ){ char *utf8; int res = vasprintf( &utf8, fmt, ap ); if( res == -1 ) return -1; *str = ToLocaleDup( utf8 ); free( utf8 ); return res;}/** * Formats an UTF-8 string as vfprintf(), then print it, with * appropriate conversion to local encoding. */int utf8_vfprintf( FILE *stream, const char *fmt, va_list ap ){ char *str; int res = utf8_vasprintf( &str, fmt, ap ); if( res == -1 ) return -1; fputs( str, stream ); free( str ); return res;}/** * Formats an UTF-8 string as fprintf(), then print it, with * appropriate conversion to local encoding. */int utf8_fprintf( FILE *stream, const char *fmt, ... ){ va_list ap; int res; va_start( ap, fmt ); res = utf8_vfprintf( stream, fmt, ap ); va_end( ap ); return res;}static char *CheckUTF8( char *str, char rep ){ uint8_t *ptr = (uint8_t *)str; assert (str != NULL); for (;;) { uint8_t c = ptr[0]; int charlen = -1; if (c == '\0') break; for (int i = 0; i < 7; i++) if ((c >> (7 - i)) == ((0xff >> (7 - i)) ^ 1)) { charlen = i; break; } switch (charlen) { case 0: // 7-bit ASCII character -> OK ptr++; continue; case -1: // 1111111x -> error case 1: // continuation byte -> error goto error; } assert (charlen >= 2); uint32_t cp = c & ~((0xff >> (7 - charlen)) << (7 - charlen)); for (int i = 1; i < charlen; i++) { assert (cp < (1 << 26)); c = ptr[i]; if ((c == '\0') // unexpected end of string || ((c >> 6) != 2)) // not a continuation byte goto error; cp = (cp << 6) | (ptr[i] & 0x3f); } if (cp < 128) // overlong (special case for ASCII) goto error; if (cp < (1u << (5 * charlen - 3))) // overlong goto error; ptr += charlen; continue; error: if (rep == 0) return NULL; *ptr++ = rep; str = NULL; } return str;}/** * Replaces invalid/overlong UTF-8 sequences with question marks. * Note that it is not possible to convert from Latin-1 to UTF-8 on the fly, * so we don't try that, even though it would be less disruptive. * * @return str if it was valid UTF-8, NULL if not. */char *EnsureUTF8( char *str ){ return CheckUTF8( str, '?' );}/** * Checks whether a string is a valid UTF-8 byte sequence. * * @param str nul-terminated string to be checked * * @return str if it was valid UTF-8, NULL if not. */const char *IsUTF8( const char *str ){ return CheckUTF8( (char *)str, 0 );}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -