Make win32 version file handling use wide character functions (for non-latin filenames)

This commit is contained in:
Ron Pedde 2006-07-17 04:49:44 +00:00
parent 840fe59997
commit 5b18d69d28
16 changed files with 592 additions and 129 deletions

View File

@ -201,7 +201,7 @@ int _conf_existdir(char *path) {
DPRINTF(E_DBG,L_CONF,"Checking existence of %s\n",path);
if(stat(path,&sb)) {
if(os_stat(path,&sb)) {
return FALSE;
}

View File

@ -339,7 +339,7 @@ void config_handler(WS_CONNINFO *pwsc) {
}
/* this is quite broken, but will work */
stat(resolved_path,&sb);
os_stat(resolved_path,&sb);
if(sb.st_mode & S_IFDIR) {
ws_addresponseheader(pwsc,"Location","/index.html");
ws_returnerror(pwsc,302,"Moved");
@ -806,7 +806,7 @@ void config_emit_include(WS_CONNINFO *pwsc, void *value, char *arg) {
}
/* this should really return a 302:Found */
stat(resolved_path,&sb);
os_stat(resolved_path,&sb);
if(sb.st_mode & S_IFDIR) {
ws_writefd(pwsc,"<hr><i>error: cannot include dir %s</i><hr>",arg);
return;

View File

@ -106,7 +106,7 @@ void err_reopen(void) {
if(!(err_logdest & LOGDEST_LOGFILE))
return;
_err_lock();
// _err_lock();
fclose(err_file);
err_file = fopen(err_filename,"a");
if(!err_file) {
@ -122,7 +122,7 @@ void err_reopen(void) {
strerror(err));
return;
}
_err_unlock();
// _err_unlock();
DPRINTF(E_LOG,L_MISC,"Rotated logs\n");
}
@ -257,7 +257,7 @@ int err_setlogfile(char *file) {
if(strcmp(file,err_filename) == 0)
return TRUE;
*/
_err_lock();
// _err_lock();
if(err_file) {
fclose(err_file);
@ -279,7 +279,7 @@ int err_setlogfile(char *file) {
result=FALSE;
}
_err_unlock();
// _err_unlock();
return result;
}

View File

@ -364,7 +364,7 @@ int scan_path(char *path) {
mp3_path[0] = '\x0';
realpath(relative_path,mp3_path);
DPRINTF(E_DBG,L_SCAN,"Found %s\n",relative_path);
if(stat(mp3_path,&sb)) {
if(os_stat(mp3_path,&sb)) {
DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
} else {
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
@ -411,7 +411,7 @@ int scan_static_playlist(char *path) {
char *ptr;
DPRINTF(E_WARN,L_SCAN|L_PL,"Processing static playlist: %s\n",path);
if(stat(path,&sb)) {
if(os_stat(path,&sb)) {
DPRINTF(E_WARN,L_SCAN,"Error statting %s: %s\n",path,strerror(errno));
return FALSE;
}
@ -567,7 +567,7 @@ void scan_filename(char *path, int compdir, char *extensions) {
}
if(stat(mp3_path,&sb)) {
if(os_stat(mp3_path,&sb)) {
DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
} else {
/* we assume this is regular file */

153
src/os-win32-u.c Normal file
View File

@ -0,0 +1,153 @@
/*
* Win32 os functions that require unicode
*/
#define _UNICODE
#define UNICODE
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "daapd.h"
#include "win32.h"
#include "err.h"
#include "os-win32.h"
#include "util.h"
/* opendir/closedir/readdir emulation taken from emacs. Thanks. :) */
DIR *os_opendir(char *filename) {
DIR *dirp;
/* Opening is done by FindFirstFile. However, a read is inherent to
this operation, so we defer the open until read time. */
if (!(dirp = (DIR *) malloc (sizeof (DIR))))
return NULL;
dirp->dir_find_handle = INVALID_HANDLE_VALUE;
dirp->dd_fd = 0;
dirp->dd_loc = 0;
dirp->dd_size = 0;
strncpy (dirp->dir_pathname, filename,PATH_MAX);
dirp->dir_pathname[PATH_MAX] = '\0';
return dirp;
}
void os_closedir(DIR *dirp) {
/* If we have a find-handle open, close it. */
if (dirp->dir_find_handle != INVALID_HANDLE_VALUE) {
FindClose(dirp->dir_find_handle);
}
free((char *) dirp);
}
int os_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
char filename[PATH_MAX + 1];
WCHAR utf16[PATH_MAX + 1];
int ln;
if (dirp->dir_find_handle == INVALID_HANDLE_VALUE) {
/* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
strncpy (filename, dirp->dir_pathname,PATH_MAX - 3);
ln = (int) strlen (filename) - 1;
if(filename[ln] != '\\')
strcat (filename, "\\");
strcat (filename, "*");
/* filename is utf-8... let's convert to unicode */
util_utf8toutf16((unsigned char *)&utf16,sizeof(utf16),filename,(int)strlen(filename));
dirp->dir_find_handle = FindFirstFile(utf16, &dirp->dir_find_data);
if (dirp->dir_find_handle == INVALID_HANDLE_VALUE) {
*result=NULL;
return 2;
}
} else {
if (!FindNextFile (dirp->dir_find_handle, &dirp->dir_find_data)) {
*result = NULL;
return 0;
}
}
/* Emacs never uses this value, so don't bother making it match
value returned by stat(). */
entry->d_ino = 1;
memset(entry->d_name,0,MAXNAMLEN+1);
util_utf16toutf8(entry->d_name,MAXNAMLEN+1,
(unsigned char *)&dirp->dir_find_data.cFileName,
(int)wcslen(dirp->dir_find_data.cFileName)*2);
entry->d_namlen = (int) strlen (entry->d_name);
entry->d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 +
entry->d_namlen - entry->d_namlen % 4;
entry->d_type = 0;
if(dirp->dir_find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
entry->d_type |= DT_DIR;
} else if(dirp->dir_find_data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) {
entry->d_type |= DT_REG;
}
/*
if (dir_is_fat)
_strlwr (dir_static.d_name);
else if (!NILP (Vw32_downcase_file_names)) {
register char *p;
for (p = dir_static.d_name; *p; p++)
if (*p >= 'a' && *p <= 'z')
break;
if (!*p)
_strlwr (dir_static.d_name);
}
*/
*result = entry;
return 0;
}
int os_stat(const char *path, struct _stat *sb) {
WCHAR utf16_path[PATH_MAX+1];
memset(utf16_path,0,sizeof(utf16_path));
util_utf8toutf16((unsigned char *)&utf16_path,PATH_MAX * 2,(char*)path,(int)strlen(path));
return _wstat(utf16_path,sb);
}
/* FIXME: mode */
int os_open(const char *filename, int oflag) {
WCHAR utf16_path[PATH_MAX+1];
int fd;
memset(utf16_path,0,sizeof(utf16_path));
util_utf8toutf16((unsigned char *)&utf16_path,PATH_MAX * 2,(char*)filename,(int)strlen(filename));
fd = _wopen(utf16_path, oflag | O_BINARY);
return fd;
}
FILE *os_fopen(const char *filename, const char *mode) {
WCHAR utf16_path[PATH_MAX+1];
WCHAR utf16_mode[10];
memset(utf16_path,0,sizeof(utf16_path));
memset(utf16_mode,0,sizeof(utf16_mode));
util_utf8toutf16((unsigned char *)&utf16_path,PATH_MAX * 2,(char*)filename,(int)strlen(filename));
util_utf8toutf16((unsigned char *)&utf16_mode,10 * 2,(char*)mode,(int)strlen(mode));
return _wfopen((wchar_t *)&utf16_path, (wchar_t *)&utf16_mode);
}

View File

@ -1,7 +1,6 @@
/* $Id$
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
@ -19,6 +18,7 @@
#include "plugin.h"
#include "w32-eventlog.h"
#include "w32-service.h"
#include "util.h"
/* Globals */
static WSADATA w32_wsadata;
@ -425,13 +425,6 @@ int os_shutdown(int fd, int how) {
return 0;
}
/* FIXME: mode */
int os_open(const char *filename, int oflag) {
int fd;
fd = _open(filename, oflag | O_BINARY);
return fd;
}
int os_close(int fd) {
if(NOTSOCK) {
@ -470,7 +463,7 @@ char *os_realpath(const char *pathname, char *resolved_path) {
ptr = resolved_path;
while(*ptr) {
*ptr = tolower(*ptr);
// *ptr = tolower(*ptr);
if(*ptr == '/')
*ptr = '\\';
ptr++;
@ -524,92 +517,6 @@ void _os_socket_shutdown(void) {
/* COMPAT FUNCTIONS */
/* opendir/closedir/readdir emulation taken from emacs. Thanks. :) */
DIR *os_opendir(char *filename) {
DIR *dirp;
/* Opening is done by FindFirstFile. However, a read is inherent to
this operation, so we defer the open until read time. */
if (!(dirp = (DIR *) malloc (sizeof (DIR))))
return NULL;
dirp->dir_find_handle = INVALID_HANDLE_VALUE;
dirp->dd_fd = 0;
dirp->dd_loc = 0;
dirp->dd_size = 0;
strncpy (dirp->dir_pathname, filename,_MAX_PATH);
dirp->dir_pathname[_MAX_PATH] = '\0';
return dirp;
}
void os_closedir(DIR *dirp) {
/* If we have a find-handle open, close it. */
if (dirp->dir_find_handle != INVALID_HANDLE_VALUE) {
FindClose(dirp->dir_find_handle);
}
free((char *) dirp);
}
int os_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
if (dirp->dir_find_handle == INVALID_HANDLE_VALUE) {
/* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
char filename[MAXNAMLEN + 3];
int ln;
strcpy (filename, dirp->dir_pathname);
ln = (int) strlen (filename) - 1;
if(filename[ln] != '\\')
strcat (filename, "\\");
strcat (filename, "*");
dirp->dir_find_handle = FindFirstFile (filename, &dirp->dir_find_data);
if (dirp->dir_find_handle == INVALID_HANDLE_VALUE) {
*result=NULL;
return 2;
}
} else {
if (!FindNextFile (dirp->dir_find_handle, &dirp->dir_find_data)) {
*result = NULL;
return 0;
}
}
/* Emacs never uses this value, so don't bother making it match
value returned by stat(). */
entry->d_ino = 1;
entry->d_namlen = (int) strlen (dirp->dir_find_data.cFileName);
entry->d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 +
entry->d_namlen - entry->d_namlen % 4;
strcpy (entry->d_name, dirp->dir_find_data.cFileName);
entry->d_type = 0;
if(dirp->dir_find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
entry->d_type |= DT_DIR;
} else if(dirp->dir_find_data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) {
entry->d_type |= DT_REG;
}
/*
if (dir_is_fat)
_strlwr (dir_static.d_name);
else if (!NILP (Vw32_downcase_file_names)) {
register char *p;
for (p = dir_static.d_name; *p; p++)
if (*p >= 'a' && *p <= 'z')
break;
if (!*p)
_strlwr (dir_static.d_name);
}
*/
*result = entry;
return 0;
}
/* can't be worse then strerror */
char *os_strerror (int error_no) {

View File

@ -42,7 +42,7 @@ typedef struct {
int dd_size; /* amount of valid data */
char dd_buf[DIRBLKSIZ]; /* directory block */
HANDLE dir_find_handle;
char dir_pathname[_MAX_PATH+1];
char dir_pathname[PATH_MAX+1];
WIN32_FIND_DATA dir_find_data;
} DIR;
@ -58,6 +58,8 @@ extern int os_shutdown(int fd, int how);
extern int os_waitfdtimed(int fd, struct timeval end);
extern int os_close(int fd);
extern int os_open(const char *filename, int oflag);
extern FILE *os_fopen(const char *filename, const char *mode);
extern int os_read(int fd,void *buffer,unsigned int count);
extern int os_write(int fd, void *buffer, unsigned int count);
extern int os_getuid(void);

View File

@ -39,6 +39,7 @@ extern void *os_libfunc(char **pe, void *handle, char *function);
extern int os_unload(void *handle);
/* misc */
extern int os_stat(const char *path, struct stat *sb);
extern int os_islocaladdr(char *hostaddr);
extern char *os_apppath(char *parm);

View File

@ -6,6 +6,8 @@
# include "config.h"
#endif
#undef fopen
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -291,6 +291,7 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
int err;
int index;
int used;
int mp3_fd;
char *utf8_text;
int genre=WINAMP_GENRE_UNKNOWN;
int have_utf8;
@ -300,7 +301,13 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
int got_numeric_genre;
int rating;
pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);
mp3_fd = open(file,O_RDONLY);
if(mp3_fd == -1) {
DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file);
return FALSE;
}
pid3file=id3_file_fdopen(mp3_fd,ID3_FILE_MODE_READONLY);
if(!pid3file) {
DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file);
return FALSE;

View File

@ -427,7 +427,6 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
int fail=0;
int track, tracknumber;
char numbuff[40];
int new_size;
char *tmp;
@ -528,8 +527,8 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
pmp3->composer = descriptor_byte_value;
descriptor_byte_value = NULL;
} else {
size = strlen(pmp3->composer) + 1 +
strlen(descriptor_byte_value) + 1;
size = (int)strlen(pmp3->composer) + 1 +
(int)strlen(descriptor_byte_value) + 1;
tmp = malloc(size);
if(!tmp)
DPRINTF(E_FATAL,L_SCAN,"malloc: wma_ext_content_descr\n");

View File

@ -159,7 +159,7 @@ int scan_xml_rb_compare(const void *pa, const void *pb, const void *cfg) {
int scan_xml_is_file(char *path) {
struct stat sb;
if(stat(path,&sb))
if(os_stat(path,&sb))
return 0;
if(sb.st_mode & S_IFREG)

View File

@ -14,8 +14,20 @@
#include <string.h>
#include <sys/types.h>
#include "daapd.h"
//#include <iconv.h>
#include "daapd.h"
#include "err.h"
#include "util.h"
/* Forwards */
//int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size_t slen, char *from, char *to);
void _util_hexdump(unsigned char *block, int len);
/**
* Simple hash generator
*/
uint32_t util_djb_hash_block(unsigned char *data, uint32_t len) {
uint32_t hash = 5381;
unsigned char *pstr = data;
@ -27,7 +39,9 @@ uint32_t util_djb_hash_block(unsigned char *data, uint32_t len) {
return hash;
}
/**
* simple hash generator
*/
uint32_t util_djb_hash_str(char *str) {
uint32_t len;
@ -35,6 +49,362 @@ uint32_t util_djb_hash_str(char *str) {
return util_djb_hash_block((unsigned char *)str,len);
}
/**
* Dumb utility function that should probably be somehwere else
*/
int util_must_exit(void) {
return config.stop;
}
/**
* calculate how long a utf16le string will be once converted
*/
int util_utf16toutf8_len(unsigned char *utf16, int len) {
char *src = utf16;
int out_len = 0;
uint16_t temp_word;
while(src+2 <= utf16 + len) {
temp_word = src[1] << 8 | src[0];
if((temp_word & 0xFC00) == 0xD800) {
src += 2;
if(src + 2 <= utf16 + len) {
out_len += 4;
} else {
return -1;
}
} else {
if(temp_word <= 0x7F)
out_len += 1;
else if(temp_word <= 0x7FF)
out_len += 2;
else if(temp_word <= 0xFFFF)
out_len += 3;
}
src += 2;
}
return out_len;
}
/**
* convert utf16 string to utf8. This is a bit naive, but...
* Since utf-8 can't expand past 4 bytes per code point, and
* we're converting utf-16, we can't be more than 2n+1 bytes, so
* we'll just allocate that much.
*
* Probably it could be more efficiently calculated, but this will
* always work. Besides, these are small strings, and will be freed
* after the db insert.
*
* We assume this is utf-16LE, as it comes from windows
*
* @param utf16 utf-16 to convert
* @param len length of utf-16 string
*/
int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, int len) {
unsigned char *src=utf16;
char *dst;
unsigned int w1, w2;
int bytes;
int new_len;
if(!len)
return FALSE;
new_len = util_utf16toutf8_len(utf16,len);
if((new_len == -1) || (dlen <= new_len)) {
DPRINTF(E_LOG,L_MISC,"Cannot convert %s to utf8; E2BIG (%d vs %d)\n",utf8,new_len,dlen);
return FALSE;
}
dst=utf8;
while((src+2) <= utf16+len) {
w1=src[1] << 8 | src[0];
src += 2;
if((w1 & 0xFC00) == 0xD800) { // could be surrogate pair
if(src+2 > utf16+len) {
DPRINTF(E_INF,L_SCAN,"Invalid utf-16 in file\n");
return FALSE;
}
w2 = src[3] << 8 | src[2];
if((w2 & 0xFC00) != 0xDC00) {
DPRINTF(E_INF,L_SCAN,"Invalid utf-16 in file\n");
return FALSE;
}
// get bottom 10 of each
w1 = w1 & 0x03FF;
w1 = w1 << 10;
w1 = w1 | (w2 & 0x03FF);
// add back the 0x10000
w1 += 0x10000;
}
// now encode the original code point in utf-8
if (w1 < 0x80) {
*dst++ = w1;
bytes=0;
} else if (w1 < 0x800) {
*dst++ = 0xC0 | (w1 >> 6);
bytes=1;
} else if (w1 < 0x10000) {
*dst++ = 0xE0 | (w1 >> 12);
bytes=2;
} else {
*dst++ = 0xF0 | (w1 >> 18);
bytes=3;
}
while(bytes) {
*dst++ = 0x80 | ((w1 >> (6*(bytes-1))) & 0x3f);
bytes--;
}
}
*dst = '\x0';
return TRUE;
}
/**
* calculate how long a utf8 string will be once converted
*/
int util_utf8toutf16_len(unsigned char *utf8) {
int len,out_len,trailing_bytes;
unsigned char *src = utf8;
len=(int)strlen(utf8);
out_len = 0;
while(src < utf8 + len) {
trailing_bytes = 0;
if((*src & 0xE0) == 0xC0) trailing_bytes = 1;
else if((*src & 0xF0) == 0xE0) trailing_bytes = 2;
else if((*src & 0xF8) == 0xF0) trailing_bytes = 3;
if(src + trailing_bytes > utf8 + len)
return -1;
out_len += 2;
if(trailing_bytes == 3) /* surrogate pair */
out_len += 2;
src += (1 + trailing_bytes);
}
return out_len;
}
unsigned char *util_utf8toutf16_alloc(unsigned char *utf8) {
unsigned char *out;
int new_len;
new_len = util_utf8toutf16_len(utf8);
if(new_len == -1)
return NULL;
out = calloc(1,new_len + 2);
if(!util_utf8toutf16(out,new_len + 2,utf8,(int)strlen(utf8))) {
free(out);
return NULL;
}
return out;
}
unsigned char *util_utf16touft8_alloc(unsigned char *utf16, int len) {
unsigned char *out;
int new_len;
new_len = util_utf16toutf8_len(utf16,len);
if(new_len == -1)
return NULL;
out = calloc(1,new_len + 1);
if(!util_utf16toutf8(out,new_len + 1,utf16,len)) {
free(out);
return NULL;
}
return out;
}
int util_utf8toutf16(unsigned char *utf16, int dlen, unsigned char *utf8, int len) {
unsigned char *src=utf8;
char *dst;
int new_len;
int trailing_bytes;
uint32_t utf32;
uint16_t temp_word;
len=(int)strlen(utf8); /* ignore passed length, might be wrong! */
if(!len)
return FALSE;
new_len = util_utf8toutf16_len(utf8);
if((new_len == -1) || (dlen <= (new_len+1))) {
DPRINTF(E_LOG,L_MISC,"Cannot convert %s to utf16; E2BIG (%d vs %d)\n",utf8,new_len,dlen);
return FALSE;
}
dst=utf16;
while(src < utf8 + len) {
utf32=0;
trailing_bytes=0;
if((*src & 0xE0) == 0xC0) trailing_bytes = 1;
else if((*src & 0xF0) == 0xE0) trailing_bytes = 2;
else if((*src & 0xF8) == 0xF0) trailing_bytes = 3;
if(src + trailing_bytes > utf8 + len) {
DPRINTF(E_LOG,L_SCAN,"Invalid UTF8 string\n");
return FALSE;
}
switch(trailing_bytes) {
case 0:
utf32 = *src;
break;
case 1:
utf32 = ((src[0] & 0x1F) << 6) |
(src[1] & 0x3F);
break;
case 2:
utf32 = ((src[0] & 0x0F) << 12) |
((src[1] & 0x3F) << 6) |
((src[2] & 0x3F));
break;
case 3:
utf32 = ((src[0] & 0x07) << 18) |
((src[1] & 0x3F) << 12) |
((src[2] & 0x3F) << 6) |
((src[3] & 0x3F));
break;
}
if(utf32 <= 0xFFFF) {
/* we are encoding LE style... */
*dst++ = utf32 & 0xFF;
*dst++ = (utf32 & 0xFF00) >> 8;
} else {
/* Encode with surrogates */
temp_word = 0xD800 | ((utf32 & 0x0FFC00) >> 10);
*dst++ = temp_word & 0xFF;
*dst++ = (temp_word & 0xFF00) >> 8;
temp_word = 0xDC00 | (utf32 & 0x3FF);
*dst++ = temp_word & 0xFF;
*dst++ = (temp_word & 0xFF00) >> 8;
}
src += (trailing_bytes + 1);
}
*dst++ = '\x0';
*dst = '\x0';
return TRUE;
}
/*
int util_utf8toutf16(unsigned char *utf16, size_t dlen, unsigned char *utf8, size_t slen) {
int result;
DPRINTF(E_DBG,L_MISC,"Converting %s to utf-16le (slen=%d, dlen=%d)\n",utf8,slen,dlen);
result=_util_xtoy(utf16, dlen, utf8, slen, "UTF-8","UTF-16LE");
DPRINTF(E_DBG,L_MISC,"Result: %d\n",result);
_util_hexdump(utf16,32);
return result;
}
int util_utf16toutf8(unsigned char *utf8, size_t dlen, unsigned char *utf16, size_t slen) {
int result;
DPRINTF(E_DBG,L_MISC,"Converting *something* to utf-8 (slen=%d, dlen=%d)\n",slen,dlen);
_util_hexdump(utf16,32);
result = _util_xtoy(utf8, dlen, utf16, slen, "UTF-16LE","UTF-8");
DPRINTF(E_DBG,L_MISC,"Converted to %s\n",utf8);
return result;
}
unsigned char *util_alloc_utf16toutf8(unsigned char *utf16, size_t slen) {
char *utf8;
utf8=calloc(1, slen * 2 + 1);
if(_util_xtoy(utf8,slen * 2 + 1,utf16,slen,"UTF-16LE","UTF-8")) {
return utf8;
}
free(utf8);
return NULL;
}
int _util_xtoy(unsigned char *dbuffer, size_t dlen, unsigned char *sbuffer, size_t slen, char *from, char *to) {
iconv_t iv;
size_t csize;
iv=iconv_open(to,from);
if(iv == (iconv_t)-1) {
DPRINTF(E_LOG,L_MISC,"iconv error: iconv_open failed with %d\n",errno);
}
csize = iconv(iv,&sbuffer,&slen,&dbuffer,&dlen);
if(csize == (size_t)-1) {
switch(errno) {
case EILSEQ:
DPRINTF(E_LOG,L_MISC,"iconv error: Invalid multibyte sequence\n");
break;
case EINVAL:
DPRINTF(E_LOG,L_MISC,"iconv error: Incomplete multibyte sequence\n");
break;
case E2BIG:
DPRINTF(E_LOG,L_MISC,"iconv error: Insufficient buffer size\n");
break;
default:
DPRINTF(E_LOG,L_MISC,"iconv error: unknown (%d)\n",errno);
break;
}
}
iconv_close(iv);
return (csize != (size_t)-1);
}
*/
void _util_hexdump(unsigned char *block, int len) {
char charmap[256];
int index;
int row, offset;
char output[80];
char tmp[20];
memset(charmap,'.',sizeof(charmap));
for(index=' ';index<'~';index++) charmap[index]=index;
for(row=0;row<(len+15)/16;row++) {
sprintf(output,"%04X: ",row*16);
for(offset=0; offset < 16; offset++) {
if(row * 16 + offset < len) {
sprintf(tmp,"%02X ",block[row*16 + offset]);
} else {
sprintf(tmp," ");
}
strcat(output,tmp);
}
for(offset=0; offset < 16; offset++) {
if(row * 16 + offset < len) {
sprintf(tmp,"%c",charmap[block[row*16 + offset]]);
} else {
sprintf(tmp," ");
}
strcat(output,tmp);
}
fprintf(stderr,"%s\n",output);
}
}

View File

@ -21,5 +21,19 @@ extern uint32_t util_djb_hash_str(char *str);
extern int util_must_exit(void);
//extern char *util_utf16toutf8(unsigned char *utf16, int len);
//int util_utf8toutf16(unsigned char *utf16, size_t dlen, unsigned char *utf8, size_t slen);
//int util_utf16toutf8(unsigned char *utf8, size_t dlen, unsigned char *utf16, size_t slen);
//unsigned char *util_alloc_utf16toutf8(unsigned char *utf16, int slen);
extern unsigned char *util_utf8toutf16_alloc(unsigned char *utf8);
extern unsigned char *util_utf16touft8_alloc(unsigned char *utf16, int len);
extern int util_utf8toutf16_len(unsigned char *utf8);
extern int util_utf16toutf8_len(unsigned char *utf16, int len);
extern int util_utf8toutf16(unsigned char *utf16, int dlen, unsigned char *utf8, int len);
extern int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, int len);
#endif /* _UTIL_H_ */

View File

@ -25,6 +25,23 @@
#include <direct.h>
#include <stdio.h>
/* Type fixups */
#define mode_t int
#define ssize_t int
#define socklen_t int
/* Consts */
#define PIPE_BUF 256 /* What *should* this be on win32? */
#define MAXDESC 512 /* http://msdn.microsoft.com/en-us/library/kdfaxaay.aspx */
#define SHUT_RDWR 2
#define ETIME 101
#define PATH_MAX 512 /* it's clearly not _MAX_PATH... other projects seem to use 512 */
#define MAX_NAME_LEN _MAX_PATH
#define EADDRINUSE WSAEADDRINUSE
#define HOST "unknown-windows-ick"
#define SERVICENAME "Firefly Media Server"
#include "os-win32.h"
#ifndef TRUE
@ -65,6 +82,7 @@ typedef INT32 int32_t;
#define strsep os_strsep
#define open os_open
#define waitfdtimed os_waitfdtimed
#define fopen os_fopen
#define readdir_r os_readdir_r
#define closedir os_closedir
@ -80,22 +98,6 @@ typedef INT32 int32_t;
/* privately implemented functions: @see os-win32.c */
#define gettimeofday os_gettimeofday
/* Type fixups */
#define mode_t int
#define ssize_t int
#define socklen_t int
/* Consts */
#define PIPE_BUF 256 /* What *should* this be on win32? */
#define MAXDESC 512 /* http://msdn.microsoft.com/en-us/library/kdfaxaay.aspx */
#define SHUT_RDWR 2
#define MAX_NAME_LEN _MAX_PATH
#define ETIME 101
#define PATH_MAX 512 /* it's clearly not _MAX_PATH... other projects seem to use 512 */
#define EADDRINUSE WSAEADDRINUSE
#define HOST "unknown-windows-ick"
#define SERVICENAME "Firefly Media Server"
#define CONFFILE os_configpath()

View File

@ -168,6 +168,9 @@
<File
RelativePath="..\src\mp3-scanner.c">
</File>
<File
RelativePath="..\src\os-win32-u.c">
</File>
<File
RelativePath="..\src\os-win32.c">
</File>
@ -287,6 +290,9 @@
<File
RelativePath="..\src\uici.h">
</File>
<File
RelativePath="..\src\util.h">
</File>
<File
RelativePath="..\src\w32-eventlog.h">
</File>