/* Native File Dialog http://www.frogtoss.com/labs */ #include #include #include #include "nfd_common.h" static char g_errorstr[NFD_MAX_STRLEN] = {0}; /* public routines */ const char *NFD_GetError( void ) { return g_errorstr; } size_t NFD_PathSet_GetCount( const nfdpathset_t *pathset ) { assert(pathset); return pathset->count; } nfdchar_t *NFD_PathSet_GetPath( const nfdpathset_t *pathset, size_t num ) { assert(pathset); assert(num < pathset->count); return pathset->buf + pathset->indices[num]; } void NFD_PathSet_Free( nfdpathset_t *pathset ) { assert(pathset); NFDi_Free( pathset->indices ); NFDi_Free( pathset->buf ); } /* internal routines */ void *NFDi_Malloc( size_t bytes ) { void *ptr = malloc(bytes); if ( !ptr ) NFDi_SetError("NFDi_Malloc failed."); return ptr; } void NFDi_Free( void *ptr ) { assert(ptr); free(ptr); } void NFDi_SetError( const char *msg ) { int bTruncate = NFDi_SafeStrncpy( g_errorstr, msg, NFD_MAX_STRLEN ); assert( !bTruncate ); _NFD_UNUSED(bTruncate); } int NFDi_SafeStrncpy( char *dst, const char *src, size_t maxCopy ) { size_t n = maxCopy; char *d = dst; assert( src ); assert( dst ); while ( n > 0 && *src != '\0' ) { *d++ = *src++; --n; } /* Truncation case - terminate string and return true */ if ( n == 0 ) { dst[maxCopy-1] = '\0'; return 1; } /* No truncation. Append a single NULL and return. */ *d = '\0'; return 0; } /* adapted from microutf8 */ size_t NFDi_UTF8_Strlen( const nfdchar_t *str ) { /* This function doesn't properly check validity of UTF-8 character sequence, it is supposed to use only with valid UTF-8 strings. */ size_t character_count = 0; size_t i = 0; /* Counter used to iterate over string. */ nfdchar_t maybe_bom[4]; /* If there is UTF-8 BOM ignore it. */ if (strlen(str) > 2) { strncpy(maybe_bom, str, 3); maybe_bom[3] = 0; if (strcmp(maybe_bom, (nfdchar_t*)NFD_UTF8_BOM) == 0) i += 3; } while(str[i]) { if (str[i] >> 7 == 0) { /* If bit pattern begins with 0 we have ascii character. */ ++character_count; } else if (str[i] >> 6 == 3) { /* If bit pattern begins with 11 it is beginning of UTF-8 byte sequence. */ ++character_count; } else if (str[i] >> 6 == 2) ; /* If bit pattern begins with 10 it is middle of utf-8 byte sequence. */ else { /* In any other case this is not valid UTF-8. */ return -1; } ++i; } return character_count; } int NFDi_IsFilterSegmentChar( char ch ) { return (ch==','||ch==';'||ch=='\0'); }