[Xfce4-commits] <glib-objc:no-foundation-dep> WIP: string stuff
Brian J. Tarricone
noreply at xfce.org
Sun Nov 22 04:02:20 CET 2009
Updating branch refs/heads/no-foundation-dep
to 77118dd5d7cfd682cef9ae5c7ff0a2a1fcc39c7a (commit)
from d5c7bec9bec6f9b8eade690b3c08d67211def16d (commit)
commit 77118dd5d7cfd682cef9ae5c7ff0a2a1fcc39c7a
Author: Brian J. Tarricone <brian at tarricone.org>
Date: Tue Aug 11 03:36:44 2009 -0700
WIP: string stuff
configure.ac.in | 37 +++
glib-objc/{GOCIterable.h => GOCConstantString.h} | 25 +-
glib-objc/GOCString.h | 103 +++++++
glib-objc/GOCString.m | 311 ++++++++++++++++++++++
gobject-objc/GOCObject.m | 44 ++--
5 files changed, 486 insertions(+), 34 deletions(-)
diff --git a/configure.ac.in b/configure.ac.in
index 72e3819..99e36eb 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -134,6 +134,40 @@ AC_MSG_CHECKING([the type signature of enums])
GOC_ARGTYPE_ENUM='e'
AC_MSG_RESULT([$GOC_ARGTYPE_ENUM])
+dnl figure out if we can use our own constant string class
+AC_MSG_CHECKING([if $CC supports -fconstant-string-class])
+saved_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -fconstant-string-class=TestConstantString"
+AC_LANG_PUSH([Objective C])
+AC_RUN_IFELSE(
+[AC_LANG_PROGRAM(
+ [
+ #import <objc/Object.h>
+
+ @interface TestConstantString : Object
+ {
+ const char *c_string;
+ unsigned int length;
+ }
+ @end
+ ],
+ [
+ TestConstantString *conststr = @"this is a test";
+ ])],
+ [
+ GOC_CONSTANT_STRING_CLASS=GOCConstantString
+ GOC_CONSTANT_STRING_PCFILE_CFLAGS="-fconstant-string-class=$GOC_CONSTANT_STRING_CLASS"
+ AC_MSG_RESULT([yes])
+ ],
+ [
+ GOC_CONSTANT_STRING_CLASS=NXConstantString
+ GOC_CONSTANT_STRING_CPPFLAGS="-DGOCConstantString=NXConstantString"
+ AC_MSG_RESULT([no])
+ ])
+CPPFLAGS="$saved_CPPFLAGS $GOC_CONSTANT_STRING_CPPFLAGS"
+AC_SUBST(GOC_CONSTANT_STRING_PCFILE_CFLAGS)
+AC_SUBST(GOC_CONSTANT_STRING_CLASS)
+
dnl check for debugging support
AC_ARG_ENABLE([debug],
[AC_HELP_STRING([--enable-debug=[full|yes|no]],
@@ -176,6 +210,8 @@ AC_CONFIG_COMMANDS([glib-objc-config.h],
#define __GOC_ARGTYPE_FLAGS "$argtype_flags"
#define __GOC_ARGTYPE_ENUM "$argtype_enum"
+#define GOC_CONSTANT_STRING_CLASS $const_str_class
+
#endif /* __GLIB_OBJC_CONFIG_H__ */
__EOF
if cmp -s $outfile glib-objc-config.h; then
@@ -189,6 +225,7 @@ __EOF
argtype_bool=$GOC_ARGTYPE_BOOL
argtype_flags=$GOC_ARGTYPE_FLAGS
argtype_enum=$GOC_ARGTYPE_ENUM
+ const_str_class=$GOC_CONSTANT_STRING_CLASS
])
AC_OUTPUT([
diff --git a/glib-objc/GOCIterable.h b/glib-objc/GOCConstantString.h
similarity index 79%
copy from glib-objc/GOCIterable.h
copy to glib-objc/GOCConstantString.h
index 5e15e9e..3e3d977 100644
--- a/glib-objc/GOCIterable.h
+++ b/glib-objc/GOCConstantString.h
@@ -17,20 +17,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GOC_ITERABLE_H__
-#define __GOC_ITERABLE_H__
+#ifndef __GOC_CONSTANT_STRING__
+#define __GOC_CONSTANT_STRING__
- at protocol GOCIter
+ at interface GOCConstantString
+{
+ Class isa;
+ char *c_string;
+ unsigned int length;
+}
-- (id <GOCObject>)next;
+- (const char *)cString;
+- (unsigned int)length;
- at end
+ at endif
- at protocol GOCIterable
-
-- (id <GOCIter>)getIter;
-
- at end
-
-
-#endif /* __GOC_ITERABLE_H__ */
+#endif
diff --git a/glib-objc/GOCString.h b/glib-objc/GOCString.h
new file mode 100644
index 0000000..fcdff60
--- /dev/null
+++ b/glib-objc/GOCString.h
@@ -0,0 +1,103 @@
+/*
+ * glib-objc - objective-c bindings for glib/gobject
+ *
+ * Copyright (c) 2009 Brian Tarricone <brian at tarricone.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GOC_STRING_H__
+#define __GOC_STRING_H__
+
+
+#include <glib.h>
+#import <glib-objc/GOCObjectBase.h>
+
+typedef struct _GOCStringPriv GOCStringPriv;
+
+ at interface GOCString : GOCObjectBase <GOCComparable>
+{
+ @private
+ GOCStringPriv *gspriv;
+}
+
++ (id)stringWithCString:(const char *)cString
+ encoding:(const char *)encoding;
++ (id)stringWithUTF8String:(const char *)utf8String;
++ (id)stringWithFormat:(const char *)format,...;
++ (id)stringWithString:(GOCString *)aString;
+
+/* this is the designated initializer */
+- (id)initWithCString:(const char *)cString
+ encoding:(const char *)encoding;
+- (id)initWithUTF8String:(const char *)utf8String;
+- (id)initWithFormat:(const char *)format,...;
+- (id)initWithString:(GOCString *)aString;
+
+- (id)initWithBytes:(const char *)byteString
+ length:(int)length
+ encoding:(const char *)encoding;
+- (id)initWithBytes:(const char *)byteString
+ length:(int)length
+ encoding:(const char *)encoding
+ takeOwnership:(BOOL)takeOwnership;
+
+/* length in characters */
+- (unsigned int)length;
+
+- (gunichar)characterAtIndex:(int)pos;
+/* returns utf8 representation of the character. buffer must be at least
+ * four bytes long (no checking is done). returns NO if char doesn't exist */
+- (BOOL)characterAtIndex:(int)pos
+ inBuffer:(char *)buffer;
+
+- (const char *)cStringUsingEncoding:(const char *)encoding;
+- (const char *)UTF8String;
+
+- (GOCString *)substringfromIndex:(int)pos
+ ofLength:(unsigned int)length;
+
+/* modifies the string */
+- (void)appendString:(GOCString *)aString;
+- (void)appendCString:(const char *)cString
+ encoding:(const char *)encoding;
+- (void)appendUTF8String:(const char *)utf8String;
+- (void)appendFormat:(const char *)format,...;
+
+- (void)insertString:(GOCString *)aString
+ atIndex:(int)pos;
+- (void)insertCString:(const char *)cString
+ atIndex:(int)pos;
+- (void)insertUTF8String:(const char *)utf8String;
+- (void)insertFormat:(const char *)format,...;
+
+- (void)makeLower;
+- (void)makeUpper;
+
+/* returns new autounref'd strings */
+- (GOCString *)stringAsLower;
+- (GOCString *)stringAsUpper;
+
+- (BOOL)hasPrefix:(GOCString *)aString;
+- (BOOL)hasSuffix:(GOCString *)aString;
+
+/* attempts to convert the string to a numeric value */
+- (BOOL)boolValue;
+- (int)intValue;
+- (long long)int64Value;
+- (double)doubleValue;
+
+ at end
+
+#endif /* __GOC_STRING_H__ */
diff --git a/glib-objc/GOCString.m b/glib-objc/GOCString.m
new file mode 100644
index 0000000..ae1a597
--- /dev/null
+++ b/glib-objc/GOCString.m
@@ -0,0 +1,311 @@
+/*
+ * glib-objc - objective-c bindings for glib/gobject
+ *
+ * Copyright (c) 2009 Brian Tarricone <brian at tarricone.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#import "GOString.h"
+
+struct _GOCStringPriv
+{
+ GString *gstr;
+ unsigned int length_chars;
+ GCache *encoded_strings;
+};
+
+ at implementation GOCString : GOCObjectBase <GOCComparable>
+
+- (id)_initWithFormat:(const char *)format
+ encoding:(const char *)encoding
+ andArgList:(va_list)var_args;
+{
+ char *new_string = NULL;
+
+ /* TODO: do stuff */
+
+ return [self initWithBytes:new_string
+ length:strlen(new_string)
+ encoding:encoding
+ takeOwnership:YES];
+}
+
++ (id)stringWithCString:(const char *)cString
+ encoding:(const char *)encoding
+{
+ return [[[GOCString alloc] initWithCString:cString encoding:encoding] autounref];
+}
+
++ (id)stringWithUTF8String:(const char *)utf8String
+{
+ return [GOCString stringWithCString:utf8String encoding:"UTF-8"];
+}
+
++ (id)stringWithFormat:(const char *)format,...
+{
+ va_list var_args;
+ id ret;
+
+ va_start(var_args, format);
+ ret = [[[GOCString alloc] _initWithFormat:format
+ encoding:"UTF-8"
+ andArgList:var_args];
+ va_end(var_args);
+
+ return ret;
+}
+
++ (id)stringWithString:(GOCString *)aString
+{
+ return [self stringWithUTF8String:[aString UTF8String]];
+}
+
+/* this is the designated initializer */
+- (id)initWithCString:(const char *)cString
+ encoding:(const char *)encoding
+{
+ if(!cString)
+ return [self init];
+ return [self initWithBytes:cString
+ length:strlen(cString)
+ encoding:encoding
+ takeOwnership:NO];
+}
+
+- (id)initWithUTF8String:(const char *)utf8String
+{
+ if(!tf8String)
+ return [self init];
+ return [self initWithBytes:utf8String
+ length:strlen(utf8String)
+ encoding:"UTF-8"
+ takeOwnership:NO];
+}
+
+- (id)initWithFormat:(const char *)format,...
+{
+ va_list var_args;
+ id ret;
+
+ va_start(var_args, format);
+ ret = [[[GOCString alloc] _initWithFormat:format
+ encoding:"UTF-8"
+ andArgList:var_args];
+ va_end(var_args);
+
+ return ret;
+}
+
+- (id)initWithFormat:(const char *)format
+ encoding:(const char *)encoding
+ arguments:...
+{
+ va_list var_args;
+ id ret;
+
+ va_start(var_args, encoding);
+ ret = [[[GOCString alloc] _initWithFormat:format
+ encoding:encoding
+ andArgList:var_args];
+ va_end(var_args);
+
+ return ret;
+}
+
+- (id)initWithString:(GOCString *)aString
+{
+ return [self initWithUTF8String:[aString UTF8String]];
+}
+
+- (id)initWithBytes:(const char *)byteString
+ length:(int)length
+ encoding:(const char *)encoding
+{
+ return [self initWithBytes:byteString
+ length:length
+ encoding:encoding
+ takeOwnership:NO];
+}
+
+- (id)initWithBytes:(const char *)byteString
+ length:(int)length
+ encoding:(const char *)encoding
+ takeOwnership:(BOOL)takeOwnership;
+{
+ self = [super init];
+ if(self) {
+ gspriv = g_slice_new0(GOCStringPriv);
+
+ if(takeOwnership) {
+ /* this is probably evil and broken */
+ gspriv->gstr = g_slice_new0(GString);
+ gspriv->gstr->str = (char *)byteString;
+ gspriv->allocated_len = length + 1;
+ gspriv->len = length;
+ } else
+ gspriv->gstr = g_string_new_len(byteString, length);
+
+ gspriv->length_chars = g_utf8_strlen(gspriv->gstr->str);
+
+ /* FIXME: need to pass struct { GString, encoding } to new func */
+ gspriv->encoded_strings = g_cache_new((GCacheNewFunc)cached_string_new,
+ (GCacheDestroyFunc)g_free,
+ (GCacheDupFunc)g_strdup,
+ (GCacheDestroyFunc)g_free,
+ g_str_hash, g_str_hash,
+ g_str_equal);
+ }
+ return self;
+}
+
+/* length in characters */
+- (unsigned int)length
+{
+ return gspriv->length_chars;
+}
+
+- (gunichar)characterAtIndex:(int)pos;
+/* returns utf8 representation of the character. buffer must be at least
+ * four bytes long (no checking is done). returns NO if char doesn't exist */
+- (BOOL)characterAtIndex:(int)pos
+ inBuffer:(char *)buffer;
+
+- (const char *)cStringUsingEncoding:(const char *)encoding
+{
+ gchar *new_str = NULL;
+ gsize bread = 0, bwritten = 0;
+ GError **error = NULL;
+
+ new_str = g_hash_table_lookup(gspriv->cached_encodings, encoding);
+ if(new_str)
+ return new_str;
+
+ new_str = g_convert(gspriv->gstr->str, gspriv->gstr->len, encoding,
+ "UTF-8", &bread, &bwritten, &error);
+ if(error) {
+ g_warning("Unable to convert string to %s: %s", encoding, error->message);
+ if(new_str)
+ g_free(new_str);
+ g_error_free(error);
+ return NULL;
+ }
+
+ if(new_str)
+ g_hash_table_replace(gspriv->cached_encodings, g_strdup(encoding), new_str);
+
+ return new_str;
+}
+
+- (const char *)UTF8String
+{
+ return gspriv->gstr->str; //[self cStringUsingEncoding:"UTF-8"];
+}
+
+- (GOCString *)substringfromIndex:(int)pos
+ ofLength:(unsigned int)length
+{
+
+}
+
+- (void)appendString:(GOCString *)aString
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)appendCString:(const char *)cString
+ encoding:(const char *)encoding
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+- (void)appendUTF8String:(const char *)utf8String
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)appendFormat:(const char *)format,...
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)insertString:(GOCString *)aString
+ atIndex:(int)pos
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)insertCString:(const char *)cString
+ atIndex:(int)pos
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)insertUTF8String:(const char *)utf8String
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)insertFormat:(const char *)format,...
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)makeLower
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+- (void)makeUpper
+{
+
+ g_hash_table_remove_all(gspriv->cached_encodings);
+}
+
+/* returns new autounref'd strings */
+- (GOCString *)stringAsLower;
+- (GOCString *)stringAsUpper;
+
+- (BOOL)hasPrefix:(GOCString *)aString;
+- (BOOL)hasSuffix:(GOCString *)aString;
+
+/* attempts to convert the string to a numeric value */
+- (BOOL)boolValue;
+- (int)intValue;
+- (long long)int64Value;
+- (double)doubleValue;
+
+- (void)free
+{
+ g_hash_table_destroy(gspriv->cached_encodings);
+ g_string_free(gspriv->gstr, TRUE);
+
+ g_slice_free(GOCStringPriv, gspriv);
+
+ [super free];
+}
+
+ at end
diff --git a/gobject-objc/GOCObject.m b/gobject-objc/GOCObject.m
index 1d7d61d..1cd3deb 100644
--- a/gobject-objc/GOCObject.m
+++ b/gobject-objc/GOCObject.m
@@ -26,6 +26,7 @@
#import "GOCObject.h"
#import "GOCValue.h"
#import "GOCBoxedValue.h"
+#import "GOCClosure.h"
#include "gobject-objc-private.h"
#include "goc-private.h"
@@ -45,7 +46,8 @@ typedef struct
guint signal_id;
GQuark detail;
BOOL after;
- NSInvocation *invocation; /* FIXME: no-ns */
+
+ GOCClosure *closure;
} ObjCClosure;
typedef struct
@@ -178,41 +180,41 @@ gobject_objc_marshal_signal(GClosure *closure,
{
GOCAutoreleasePool *pool = [[GOCAutoreleasePool alloc] init];
ObjCClosure *occlosure = (ObjCClosure *)closure;
- NSInvocation *invoc = occlosure->invocation; /* FIXME: no-ns */
- id param;
+ GOCClosure *gclo = occlosure->closure;
+ GOCValue **argv;
+ GOCValue *retval;
int i;
gboolean clear_target = FALSE;
+
+ argv = g_new0(GOCValue *, n_param_values + 1);
for(i = 0; i < n_param_values; ++i) {
- param = _gobject_objc_nsobject_from_gvalue(¶m_values[i]); /* FIXME: no-ns */
- if(!param) {
+ argv[i] = _gobject_objc_gocvalue_from_gvalue(¶m_values[i]);
+ if(!argv[i]) {
g_critical("%s: couldn't marshal value of type \"%s\"", PACKAGE,
G_VALUE_TYPE_NAME(¶m_values[i]));
}
-
- [invoc setArgument:param atIndex:i+2]; /* FIXME: no-ns */
}
- if(![invoc target]) {
+ /* FIXME: this needs rethinking -- why do we want 'self' in the arglist at all? */
+ if(![gclo target]) {
/* this is to handle class closures */
id target = nil;
- [invoc getArgument:&target atIndex:2]; /* FIXME: no-ns */
- [invoc setTarget:target]; /* FIXME: no-ns */
+ [gclo setTarget:argv[0]];
clear_target = TRUE;
}
-
- [invoc invoke]; /* FIXME: no-ns */
+
+ retval = [gclo invokeWithInvocationHint:invocation_hint andArgV:argv];
if(G_VALUE_TYPE(return_value)) {
- id ret = nil;
- [invoc getReturnValue:(void *)&ret]; /* FIXME: no-ns */
- _gobject_objc_gvalue_from_nsobject(return_value, ret, FALSE); /* FIXME: no-ns */
+ /* FIXME: i don't recall what the bool value is supposed to do */
+ _gobject_objc_gvalue_from_gocvalue(return_value, ret, FALSE);
}
if(clear_target)
- [invoc setTarget:nil]; /* FIXME: no-ns */
+ [gclo setTarget:nil];
- [pool unref]; /* FIXME: no-ns */
+ [pool unref];
}
static gboolean
@@ -242,7 +244,7 @@ gobject_objc_accumulate_signal(GSignalInvocationHint *ihint,
_gobject_objc_gvalue_from_nsobject(return_accu, returnAccu, FALSE); /* FIXME: no-ns */
[invoc getReturnValue:&ret]; /* FIXME: no-ns */
- [pool unref]; /* FIXME: no-ns */
+ [pool unref];
return ret;
}
@@ -252,7 +254,7 @@ objc_closure_finalize(gpointer data,
GClosure *closure)
{
ObjCClosure *occlosure = (ObjCClosure *)closure;
- [occlosure->invocation release];
+ [occlosure->closure unref];
}
static void
@@ -273,7 +275,7 @@ gobject_objc_gobject_set_property(GObject *obj,
return;
}
- nsobject = _gobject_objc_nsobject_from_gvalue(value);
+ nsobject = _gobject_objc_nsobject_from_gvalue(value); /* FIXME: no-ns */
pool = [[GOCAutoreleasePool alloc] init];
[objCObj performSelector:@selector(handleSetProperty:toValue:)
@@ -305,7 +307,7 @@ gobject_objc_gobject_get_property(GObject *obj,
withObject:[NSString stringWithUTF8String:g_param_spec_get_name(pspec)]];
[pool unref];
- _gobject_objc_gvalue_from_nsobject(value, nsobject, NO);
+ _gobject_objc_gvalue_from_nsobject(value, nsobject, NO); /* FIXME: no-ns */
}
More information about the Xfce4-commits
mailing list