[glib] [MacOS] Fallback to CFStringGetCSTring if CFStringGetCStringPtr fails.
- From: John Ralls <jralls src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] [MacOS] Fallback to CFStringGetCSTring if CFStringGetCStringPtr fails.
- Date: Fri, 13 Oct 2017 21:04:55 +0000 (UTC)
commit c60226e0a1cae40a96ed0bf95ca7d5a508548f58
Author: John Ralls <jralls ceridwen us>
Date: Fri Oct 13 13:45:01 2017 -0700
[MacOS] Fallback to CFStringGetCSTring if CFStringGetCStringPtr fails.
gio/gosxappinfo.c | 34 ++++++++++++++++++++++++++++++++--
gio/gosxcontenttype.c | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 64 insertions(+), 4 deletions(-)
---
diff --git a/gio/gosxappinfo.c b/gio/gosxappinfo.c
index b24b6ff..7c2b402 100644
--- a/gio/gosxappinfo.c
+++ b/gio/gosxappinfo.c
@@ -175,14 +175,44 @@ static gchar *
create_cstr_from_cfstring (CFStringRef str)
{
const gchar *cstr;
+ CFIndex length = CFStringGetLength (str);
+ char *buffer = NULL;
if (str == NULL)
return NULL;
cstr = CFStringGetCStringPtr (str, kCFStringEncodingUTF8);
+ /* CFStringGetCStringPtr returns "NULL if the internal storage of
+ * theString does not allow [a pointer] to be returned efficiently".
+ * (Apple's docs don't say what that means). In that case we must
+ * use CFStringGetCString as a fallback.
+ */
+ if (cstr != NULL)
+ {
+ CFRelease (str);
+ return g_strdup (cstr);
+ }
+
+ buffer = g_malloc0 (length + 1);
+ /* Start off with a buffer size sufficient for the most likely case
+ * that the CFString is ASCII so the UTF8 representation will be 1
+ * byte per code point. Keep trying up to 4 bytes per code point,
+ * the max allowed by RFC3629.
+ */
+ for (int i = 1; i <= 4; ++i)
+ {
+ if (CFStringGetCString (str, buffer, length, kCFStringEncodingUTF8))
+ {
+ CFRelease (str);
+ return buffer;
+ }
+ length += length;
+ buffer = g_realloc (buffer, length + 1);
+ }
+
+ g_free (buffer);
CFRelease (str);
-
- return g_strdup (cstr);
+ return NULL;
}
static char *
diff --git a/gio/gosxcontenttype.c b/gio/gosxcontenttype.c
index 485f5bf..c046d9e 100644
--- a/gio/gosxcontenttype.c
+++ b/gio/gosxcontenttype.c
@@ -53,14 +53,44 @@ static gchar *
create_cstr_from_cfstring (CFStringRef str)
{
const gchar *cstr;
+ CFIndex length = CFStringGetLength (str);
+ char *buffer = NULL;
if (str == NULL)
return NULL;
cstr = CFStringGetCStringPtr (str, kCFStringEncodingUTF8);
+ /* CFStringGetCStringPtr returns "NULL if the internal storage of
+ * theString does not allow [a pointer] to be returned efficiently".
+ * (Apple's docs don't say what that means). In that case we must
+ * use CFStringGetCString as a fallback.
+ */
+ if (cstr != NULL)
+ {
+ CFRelease (str);
+ return g_strdup (cstr);
+ }
+
+ buffer = g_malloc0 (length + 1);
+ /* Start off with a buffer size sufficient for the most likely case
+ * that the CFString is ASCII so the UTF8 representation will be 1
+ * byte per code point. Keep trying up to 4 bytes per code point,
+ * the max allowed by RFC3629.
+ */
+ for (int i = 1; i <= 4; ++i)
+ {
+ if (CFStringGetCString (str, buffer, length, kCFStringEncodingUTF8))
+ {
+ CFRelease (str);
+ return buffer;
+ }
+ length += length;
+ buffer = g_realloc (buffer, length + 1);
+ }
+
+ g_free (buffer);
CFRelease (str);
-
- return g_strdup (cstr);
+ return NULL;
}
/*< internal >
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]