nfd_common.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. Native File Dialog
  3. http://www.frogtoss.com/labs
  4. */
  5. #include <stdlib.h>
  6. #include <assert.h>
  7. #include <string.h>
  8. #include "nfd_common.h"
  9. static char g_errorstr[NFD_MAX_STRLEN] = {0};
  10. /* public routines */
  11. const char *NFD_GetError( void )
  12. {
  13. return g_errorstr;
  14. }
  15. size_t NFD_PathSet_GetCount( const nfdpathset_t *pathset )
  16. {
  17. assert(pathset);
  18. return pathset->count;
  19. }
  20. nfdchar_t *NFD_PathSet_GetPath( const nfdpathset_t *pathset, size_t num )
  21. {
  22. assert(pathset);
  23. assert(num < pathset->count);
  24. return pathset->buf + pathset->indices[num];
  25. }
  26. void NFD_PathSet_Free( nfdpathset_t *pathset )
  27. {
  28. assert(pathset);
  29. NFDi_Free( pathset->indices );
  30. NFDi_Free( pathset->buf );
  31. }
  32. /* internal routines */
  33. void *NFDi_Malloc( size_t bytes )
  34. {
  35. void *ptr = malloc(bytes);
  36. if ( !ptr )
  37. NFDi_SetError("NFDi_Malloc failed.");
  38. return ptr;
  39. }
  40. void NFDi_Free( void *ptr )
  41. {
  42. assert(ptr);
  43. free(ptr);
  44. }
  45. void NFDi_SetError( const char *msg )
  46. {
  47. int bTruncate = NFDi_SafeStrncpy( g_errorstr, msg, NFD_MAX_STRLEN );
  48. assert( !bTruncate ); _NFD_UNUSED(bTruncate);
  49. }
  50. int NFDi_SafeStrncpy( char *dst, const char *src, size_t maxCopy )
  51. {
  52. size_t n = maxCopy;
  53. char *d = dst;
  54. assert( src );
  55. assert( dst );
  56. while ( n > 0 && *src != '\0' )
  57. {
  58. *d++ = *src++;
  59. --n;
  60. }
  61. /* Truncation case -
  62. terminate string and return true */
  63. if ( n == 0 )
  64. {
  65. dst[maxCopy-1] = '\0';
  66. return 1;
  67. }
  68. /* No truncation. Append a single NULL and return. */
  69. *d = '\0';
  70. return 0;
  71. }
  72. /* adapted from microutf8 */
  73. size_t NFDi_UTF8_Strlen( const nfdchar_t *str )
  74. {
  75. /* This function doesn't properly check validity of UTF-8 character
  76. sequence, it is supposed to use only with valid UTF-8 strings. */
  77. size_t character_count = 0;
  78. size_t i = 0; /* Counter used to iterate over string. */
  79. nfdchar_t maybe_bom[4];
  80. /* If there is UTF-8 BOM ignore it. */
  81. if (strlen(str) > 2)
  82. {
  83. strncpy(maybe_bom, str, 3);
  84. maybe_bom[3] = 0;
  85. if (strcmp(maybe_bom, (nfdchar_t*)NFD_UTF8_BOM) == 0)
  86. i += 3;
  87. }
  88. while(str[i])
  89. {
  90. if (str[i] >> 7 == 0)
  91. {
  92. /* If bit pattern begins with 0 we have ascii character. */
  93. ++character_count;
  94. }
  95. else if (str[i] >> 6 == 3)
  96. {
  97. /* If bit pattern begins with 11 it is beginning of UTF-8 byte sequence. */
  98. ++character_count;
  99. }
  100. else if (str[i] >> 6 == 2)
  101. ; /* If bit pattern begins with 10 it is middle of utf-8 byte sequence. */
  102. else
  103. {
  104. /* In any other case this is not valid UTF-8. */
  105. return -1;
  106. }
  107. ++i;
  108. }
  109. return character_count;
  110. }
  111. int NFDi_IsFilterSegmentChar( char ch )
  112. {
  113. return (ch==','||ch==';'||ch=='\0');
  114. }