[PATCH 2/8] Files: add wrappers for open(), fopen(), sqlite3_open()

Thiago Macieira thiago at macieira.org
Wed Dec 18 15:13:31 UTC 2013


Looks good, just one suggestion for improvement.

On quinta-feira, 19 de dezembro de 2013 00:47:00, Lubomir I. Ivanov wrote:
> --- a/macos.c
> +++ b/macos.c

> +/* NOP wrappers to comform with windows.c */
> +int subsurface_open(const char *path, int oflags, mode_t mode)
> +{
> +	return open(path, oflags, mode);
> +}
> +
> +FILE *subsurface_fopen(const char *path, const char *mode)
> +{
> +	return fopen(path, mode);
> +}
> +
> +int subsurface_sqlite3_open(const char *path, sqlite3 **handle)
> +{
> +	return sqlite3_open(path, handle);
> +}

Technically, on Mac it should be NFD UTF-8, but I guess we should fix that on 
the file name generation side instead. This is a braindead situation because 
applying transformations is likely to cause data loss somewhere. The right 
thing to do would be to change Macs so that their input mechanisms produce NFD 
text in the first place.

I can make some patches for that.

> +/* this function converts a utf-8 string to win32's utf-16 2 byte string.
> + * the caller function should manage the allocated memory.
> + */
> +static wchar_t *utf8_to_utf16_fl(const char *utf8, char *file, int line)
> +{
> +	if (!file) {
> +		file = "unknown";
> +		line = 0;
> +	}

Just assert(). We shouldn't pass null pointers here and there's no easy 
recovery anyway.

> +	int sz = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
> +	if (!sz) {
> +		fprintf(stderr, "%s:%d: %s", file, line, "cannot estimate string 
size.");
> +		return NULL;
> +	}

UTF-8 to UTF-16 contains always at most the same number of characters. So you 
can replace the call above by a simple strlen(utf8). In the worst case, we'll 
overestimate the buffer by 3x, but since we're going to free it anyway soon 
after, it's no big deal.

> +FILE *subsurface_fopen(const char *path, const char *mode)
> +{
> +	FILE *ret = NULL;
> +	wchar_t *wpath = utf8_to_utf16(path);
> +	if (wpath) {
> +		wchar_t *wmode = utf8_to_utf16(mode);

This one is going to be expensive... the mode is actually US-ASCII, so a 
simpler algorithm would be cheaper, but then we have to write it, maintain it, 
etc. This is fine.

> +		if (wmode) {
> +			ret = _wfopen(wpath, wmode);
> +			free((void *)wpath);
> +			free((void *)wmode);
> +			return ret;
> +		}
> +		free((void *)wpath);
> +		return ret;
> +	}
> +	return ret;
> +}
> +
> +int subsurface_sqlite3_open(const char *path, sqlite3 **handle)
> +{
> +	int ret = SQLITE_ERROR;
> +	wchar_t *wpath = utf8_to_utf16(path);
> +	if (wpath) {
> +		/* try to use _open16 here */
> +		ret = sqlite3_open16((const void *)wpath, handle);
> +		free((void *)wpath);
> +		return ret;
> +	}
> +	return ret;
> +}

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.hohndel.org/pipermail/subsurface/attachments/20131218/45a66269/attachment.sig>


More information about the subsurface mailing list