Long win pathes: Make makeLongWinPath function return the num of alloc bytes.

This enables the calling function to free these accordingly. That is needed
because the makeLongWinPath for efficiency reasons does not always realloc
the original string.
This commit is contained in:
Klaas Freitag 2015-06-23 11:40:26 +02:00
parent 2b391396c6
commit b9b5e1cf33
4 changed files with 44 additions and 15 deletions

View file

@ -274,24 +274,32 @@ char* c_utf8_from_locale(const mbchar_t *wstr)
return dst;
}
const char *makeLongWinPath(const char *str)
/*
*/
const char *makeLongWinPath(const char *str, int *mem_reserved)
{
int len = 0;
char *longStr = NULL;
int mem_reserved = 0;
if( mem_reserved ) {
*mem_reserved = 0;
}
len = strlen(str);
// prepend \\?\ and convert '/' => '\' to support long names
if( len > 2 ) { // FIXME set this to 250 or so
if( len > 250 ) { // Only do realloc for long pathes. Shorter pathes are fine.
int i = 4;
// reserve mem for a new string with the prefix
mem_reserved = len + 5;
longStr = c_malloc(mem_reserved);
if( mem_reserved ) {
*mem_reserved = len + 5;
}
longStr = c_malloc(len+5);
*longStr = '\0';
strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars.
strcat( longStr, str );
/* replace all occurences of / with the windows native \ */
while(longStr[i] != '\0') {
if(longStr[i] == '/') {
longStr[i] = '\\';
@ -312,7 +320,7 @@ mbchar_t* c_utf8_to_locale(const char *str)
#ifdef _WIN32
size_t len = 0;
int size_needed = 0;
char *longStr = NULL;
const char *longStr = NULL;
int mem_reserved = 0;
#endif
@ -321,7 +329,7 @@ mbchar_t* c_utf8_to_locale(const char *str)
}
#ifdef _WIN32
longStr = makeLongWinPath(str);
longStr = makeLongWinPath(str, &mem_reserved);
if( longStr ) {
len = strlen(longStr);
@ -333,7 +341,7 @@ mbchar_t* c_utf8_to_locale(const char *str)
MultiByteToWideChar(CP_UTF8, 0, longStr, -1, dst, size_needed);
}
if( mem_reserved > 0 ) { // FIXME!! free mem.
if( mem_reserved > 0 ) { // Free mem reserved in hte makeLongWinPath function
SAFE_FREE(longStr);
}
}

View file

@ -155,7 +155,7 @@ void c_strlist_destroy(c_strlist_t *strlist);
char* c_utf8_from_locale(const mbchar_t *str);
const char *makeLongWinPath(const char *str);
const char *makeLongWinPath(const char *str, int *mem_reserved);
/**
* @brief Convert a utf8 encoded string to platform specific locale.

View file

@ -130,7 +130,6 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
}
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
struct _tdirent *dirent = NULL;
dhandle_t *handle = NULL;
csync_vio_file_stat_t *file_stat = NULL;
@ -171,6 +170,8 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
#else
struct _tdirent *dirent = NULL;
dirent = _treaddir(handle->dh);
if (dirent == NULL) {
if (errno) {

View file

@ -145,12 +145,32 @@ static void check_to_multibyte(void **state)
static void check_long_win_path(void **state)
{
const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3";
const char *new = makeLongWinPath(path);
int mem_reserved = 0;
const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; // check a short path
const char *new_short = makeLongWinPath(path, &mem_reserved);
assert_string_equal(new, "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3");
printf( "XXXXXXXXXXXX %s\n", new);
assert_int_equal( strlen(new), 37);
(void) state; /* unused */
assert_string_equal(new_short, path);
assert_int_equal(mem_reserved, 0);
const char *longPath = "D://alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/"
"elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/"
"jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/"
"olonglonglonglong/file.txt";
const char *longPathConv = "\\\\?\\D:\\\\alonglonglonglong\\blonglonglonglong\\clonglonglonglong\\dlonglonglonglong\\"
"elonglonglonglong\\flonglonglonglong\\glonglonglonglong\\hlonglonglonglong\\ilonglonglonglong\\"
"jlonglonglonglong\\klonglonglonglong\\llonglonglonglong\\mlonglonglonglong\\nlonglonglonglong\\"
"olonglonglonglong\\file.txt";
const char *new_long = makeLongWinPath(longPath, &mem_reserved);
// printf( "XXXXXXXXXXXX %s %d\n", new_long, mem_reserved);
assert_string_equal(new_long, longPathConv);
assert_int_equal(mem_reserved, 287);
// printf( "YYYYYYYYYYYY %ld\n", strlen(new_long));
assert_int_equal( strlen(new_long), 286);
}