bss_file.c: reserve for option to encode file name in UTF-8 on Windows

[from HEAD].
This commit is contained in:
Andy Polyakov 2010-04-28 20:04:37 +00:00
parent bed2b769f5
commit 336d1ee733
2 changed files with 44 additions and 3 deletions

View File

@ -118,10 +118,47 @@ static BIO_METHOD methods_filep=
BIO *BIO_new_file(const char *filename, const char *mode) BIO *BIO_new_file(const char *filename, const char *mode)
{ {
BIO *ret; BIO *ret;
FILE *file; FILE *file=NULL;
if ((file=fopen(filename,mode)) == NULL) #if defined(_WIN32) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename)+1;
/*
* Basically there are three cases to cover: a) filename is
* pure ASCII string; b) actual UTF-8 encoded string and
* c) locale-ized string, i.e. one containing 8-bit
* characters that are meaningful in current system locale.
* If filename is pure ASCII or real UTF-8 encoded string,
* MultiByteToWideChar succeeds and _wfopen works. If
* filename is locale-ized string, chances are that
* MultiByteToWideChar fails reporting
* ERROR_NO_UNICODE_TRANSLATION, in which case we fall
* back to fopen...
*/
if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,
filename,len_0,NULL,0))>0)
{
WCHAR wmode[8];
WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,
filename,len_0,wfilename,sz) &&
MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
wmode,sizeof(wmode)/sizeof(wmode[0])) &&
(file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT
) /* UTF-8 decode succeeded, but no file, filename
* could still have been locale-ized... */
file = fopen(filename,mode);
}
else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
{
file = fopen(filename,mode);
}
#else
file=fopen(filename,mode);
#endif
if (file == NULL)
{ {
SYSerr(SYS_F_FOPEN,get_last_sys_error()); SYSerr(SYS_F_FOPEN,get_last_sys_error());
ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");

View File

@ -76,6 +76,10 @@ normally be closed so the BIO_NOCLOSE flag should be set.
Because the file BIO calls the underlying stdio functions any quirks Because the file BIO calls the underlying stdio functions any quirks
in stdio behaviour will be mirrored by the corresponding BIO. in stdio behaviour will be mirrored by the corresponding BIO.
On Windows BIO_new_files reserves for the filename argument to be
UTF-8 encoded. In other words if you have to make it work in multi-
lingual environment, encode file names in UTF-8.
=head1 EXAMPLES =head1 EXAMPLES
File BIO "hello world": File BIO "hello world":