[Kde-bindings] KDE/kdebindings/csharp/qyoto

Arno Rehn kde at arnorehn.de
Sun May 10 16:21:11 UTC 2009


SVN commit 966212 by arnorehn:

* Add a QPair marshaller. We still need a List<QPair<...>> one.
* Fix some memory leaks.

CCMAIL: kde-bindings at kde.org



 M  +4 -0      ChangeLog  
 M  +4 -0      core/QPair.cs  
 M  +117 -2    src/SmokeMarshallers.cs  
 M  +39 -4     src/handlers.cpp  
 M  +105 -0    src/marshall_macros.h  
 M  +8 -0      src/qyoto.h  


--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #966211:966212
@@ -1,3 +1,7 @@
+2009-05-10  Arno Rehn  <arno at arnorehn.de>
+	* Add a QPair marshaller. We still need a List<QPair<...>> one.
+	* Fix some memory leaks.
+
 2009-04-12  Arno Rhen  <arno at arnorehn.de>
 	* Make it possible to register new metatypes. Works also with non-smoke
 	  types, i.e. all .NET types.
--- trunk/KDE/kdebindings/csharp/qyoto/core/QPair.cs #966211:966212
@@ -7,5 +7,9 @@
 
 		public T1 first;
 		public T2 second;
+		
+		public override string ToString() {
+			return "QPair[" + first.ToString() + ", " + second.ToString() + "]";
+		}
 	}
 }
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeMarshallers.cs #966211:966212
@@ -206,6 +206,21 @@
 		public static extern void InstallAddUIntToListUInt(AddUInt callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern void InstallQPairGetFirst(GetIntPtr callback);
+
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern void InstallQPairGetSecond(GetIntPtr callback);
+
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern void InstallCreateQPair(CreateQPairFn callback);
+
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern void InstallUnboxToStackItem(SetIntPtr callback);
+
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern void InstallBoxFromStackItem(CreateInstanceFn callback);
+
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern void InstallGenericPointerGetIntPtr(GetIntPtr callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
@@ -238,6 +253,7 @@
 		public delegate IntPtr ConstructDict(string type1, string type2);
 		public delegate void SetPropertyFn(IntPtr obj, string name, IntPtr variant);
 		public delegate void InvokeDelegateFn(Delegate d, IntPtr stack);
+		public delegate IntPtr CreateQPairFn(IntPtr first, IntPtr second);
 #endregion
 		
 #region marshalling functions
@@ -634,9 +650,9 @@
 
 		public static IntPtr IntPtrFromString(string str) {
 #if DEBUG
-			return (IntPtr) DebugGCHandle.Alloc(str);
+			return (IntPtr) DebugGCHandle.Alloc(string.Copy(str));
 #else
-			return (IntPtr) GCHandle.Alloc(str);
+			return (IntPtr) GCHandle.Alloc(string.Copy(str));
 #endif
 		}
 
@@ -868,6 +884,98 @@
 			return map;
 		}
 		
+		public static IntPtr QPairGetFirst(IntPtr pair) {
+			object o = ((GCHandle) pair).Target;
+			object field = o.GetType().GetField("first").GetValue(o);
+			if (field == null) return IntPtr.Zero;
+			return (IntPtr) GCHandle.Alloc(field);
+		}
+		
+		public static IntPtr QPairGetSecond(IntPtr pair) {
+			object o = ((GCHandle) pair).Target;
+			object field = o.GetType().GetField("second").GetValue(o);
+			if (field == null) return IntPtr.Zero;
+			return (IntPtr) GCHandle.Alloc(field);
+		}
+		
+		public static IntPtr CreateQPair(IntPtr first, IntPtr second) {
+			Type t = typeof(QPair<,>);
+			object firstObject = ((GCHandle) first).Target;
+			object secondObject = ((GCHandle) second).Target;
+			t = t.MakeGenericType(new Type[] { firstObject.GetType(), secondObject.GetType() });
+			object pair = Activator.CreateInstance(t, new object[] { firstObject, secondObject });
+			return (IntPtr) GCHandle.Alloc(pair);
+		}
+		
+		public static unsafe void UnboxToStackItem(IntPtr obj, IntPtr st) {
+			StackItem *item = (StackItem*) st;
+			object o = ((GCHandle) obj).Target;
+			Type t = o.GetType();
+			if (t == typeof(int) || t.IsEnum) {
+				item->s_int = (int) o;
+			} else if (t == typeof(bool)) {
+				item->s_bool = (bool) o;
+			} else if (t == typeof(short)) {
+				item->s_short = (short) o;
+			} else if (t == typeof(float)) {
+				item->s_float = (float) o;
+			} else if (t == typeof(double)) {
+				item->s_double = (double) o;
+			} else if (t == typeof(long)) {
+				item->s_long = (long) o;
+			} else if (t == typeof(ushort)) {
+				item->s_ushort = (ushort) o;
+			} else if (t == typeof(uint)) {
+				item->s_uint = (uint) o;
+			} else if (t == typeof(ulong)) {
+				item->s_ulong = (ulong) o;
+			} else if (t == typeof(sbyte)) {
+				item->s_char = (sbyte) o;
+			} else if (t == typeof(byte)) {
+				item->s_uchar = (byte) o;
+			} else if (t == typeof(char)) {
+				item->s_char = (sbyte) (char) o;
+			} else {
+				item->s_class = IntPtr.Zero;
+			}
+		}
+		
+		public static unsafe IntPtr BoxFromStackItem(string type, IntPtr st) {
+			Type t = Type.GetType(type);
+			if (t == null) return IntPtr.Zero;
+			StackItem *item = (StackItem*) st;
+			object box = null;
+			
+			if (t == typeof(int)) {
+				box = item->s_int;
+			} else if (t == typeof(bool)) {
+				box = item->s_bool;
+			} else if (t == typeof(short)) {
+				box = item->s_short;
+			} else if (t == typeof(float)) {
+				box = item->s_float;
+			} else if (t == typeof(double)) {
+				box = item->s_double;
+			} else if (t == typeof(long)) {
+				box = (SizeOfNativeLong < sizeof(long))? item->s_int : item->s_long;
+			} else if (t == typeof(ushort)) {
+				box = item->s_ushort;
+			} else if (t == typeof(uint)) {
+				box = item->s_uint;
+			} else if (t == typeof(ulong)) {
+				box = (SizeOfNativeLong < sizeof(long))? item->s_uint : item->s_ulong;
+			} else if (t == typeof(sbyte)) {
+				box = item->s_char;
+			} else if (t == typeof(byte)) {
+				box = item->s_uchar;
+			} else if (t == typeof(char)) {
+				box = (char) item->s_char;
+			}
+			
+			if (box == null) return IntPtr.Zero;
+			return (IntPtr) GCHandle.Alloc(box);
+		}
+		
 		public static IntPtr GenericPointerGetIntPtr(IntPtr obj) {
 			object o = ((GCHandle) obj).Target;
 			return (IntPtr) o.GetType().GetMethod("ToIntPtr").Invoke(o, null);
@@ -937,6 +1045,13 @@
 			InstallGetProperty(GetProperty);
 			InstallSetProperty(SetProperty);
 			
+			InstallQPairGetFirst(QPairGetFirst);
+			InstallQPairGetSecond(QPairGetSecond);
+			InstallCreateQPair(CreateQPair);
+			
+			InstallUnboxToStackItem(UnboxToStackItem);
+			InstallBoxFromStackItem(BoxFromStackItem);
+			
 			InstallGenericPointerGetIntPtr(GenericPointerGetIntPtr);
 			InstallCreateGenericPointer(CreateGenericPointer);
 			
--- trunk/KDE/kdebindings/csharp/qyoto/src/handlers.cpp #966211:966212
@@ -105,6 +105,13 @@
 Q_DECL_EXPORT AddUInt AddUIntToListUInt;
 Q_DECL_EXPORT AddIntObject AddIntObjectToDictionary;
 
+Q_DECL_EXPORT GetIntPtr QPairGetFirst;
+Q_DECL_EXPORT GetIntPtr QPairGetSecond;
+Q_DECL_EXPORT CreateQPairFn CreateQPair;
+
+Q_DECL_EXPORT SetIntPtr UnboxToStackItem;
+Q_DECL_EXPORT CreateInstanceFn BoxFromStackItem;
+
 Q_DECL_EXPORT GetIntPtr GenericPointerGetIntPtr;
 Q_DECL_EXPORT CreateInstanceFn CreateGenericPointer;
 
@@ -223,6 +230,31 @@
 	CreateGenericPointer = callback;
 }
 
+Q_DECL_EXPORT void InstallQPairGetFirst(GetIntPtr callback)
+{
+	QPairGetFirst = callback;
+}
+
+Q_DECL_EXPORT void InstallQPairGetSecond(GetIntPtr callback)
+{
+	QPairGetSecond = callback;
+}
+
+Q_DECL_EXPORT void InstallCreateQPair(CreateQPairFn callback)
+{
+	CreateQPair = callback;
+}
+
+Q_DECL_EXPORT void InstallUnboxToStackItem(SetIntPtr callback)
+{
+	UnboxToStackItem = callback;
+}
+
+Q_DECL_EXPORT void InstallBoxFromStackItem (CreateInstanceFn callback)
+{
+	BoxFromStackItem = callback;
+}
+
 Q_DECL_EXPORT void* ConstructPointerList()
 {
 	void * list = (void*) new QList<void*>;
@@ -808,10 +840,9 @@
 StringArrayToQStringList(int length, char ** strArray)
 {
 	QStringList * result = new QStringList();
-	char ** ca = (char**) StringArrayToCharStarStar(length, strArray);
 	
 	for (int i = 0; i < length; i++) {
-		(*result) << QString::fromUtf8(ca[i]);
+		(*result) << QString::fromUtf8(strArray[i]);
 	}
 	return (void*) result;
 }
@@ -1096,7 +1127,7 @@
 			return;
 		}
 	    if (p != 0) {
-			m->var().s_class = (*IntPtrFromCharStar)(strdup(p));
+			m->var().s_class = (*IntPtrFromCharStar)(p);
 	    } else {
 			m->var().s_class = 0;
 		}
@@ -1177,7 +1208,7 @@
 				m->var().s_class = (*IntPtrFromQString)(s);
 			}
 
-			if (m->cleanup())
+			if (m->cleanup() || m->type().isStack())
 				delete s;
 			} else {
 				m->var().s_voidp = 0;
@@ -1885,6 +1916,8 @@
 DEF_VALUELIST_MARSHALLER( QPrinterInfoList, QList<QPrinterInfo>, QPrinterInfo )
 #endif
 
+DEF_QPAIR_MARSHALLER( QPair_QHostAddress_int, QHostAddress, int, "Qyoto.QHostAddress", "System.Int32" )
+
 Q_DECL_EXPORT TypeHandler Qyoto_handlers[] = {
     { "bool*", marshall_boolR },
     { "bool&", marshall_boolR },
@@ -1960,6 +1993,8 @@
     { "QModelIndexList&", marshall_QModelIndexList },
     { "QObjectList", marshall_QObjectList },
     { "QObjectList&", marshall_QObjectList },
+    { "QPair<QHostAddress,int>", marshall_QPair_QHostAddress_int },
+    { "QPair<QHostAddress,int>&", marshall_QPair_QHostAddress_int },
     { "qreal*", marshall_doubleR },
     { "qreal&", marshall_doubleR },
     { "QStringList", marshall_QStringList },
--- trunk/KDE/kdebindings/csharp/qyoto/src/marshall_macros.h #966211:966212
@@ -182,3 +182,108 @@
 
 #define DEF_VALUELIST_MARSHALLER(ListIdent,ItemList,Item) namespace { char ListIdent##STR[] = #Item; }  \
         Marshall::HandlerFn marshall_##ListIdent = marshall_ValueListItem<Item,ItemList,ListIdent##STR>;
+
+template <class Item1, class Item2, const char *Item1STR, const char *Item2STR,
+          const char *Item1CliSTR, const char *Item2CliSTR >
+void marshall_QPair(Marshall *m) {
+	switch(m->action()) {
+		case Marshall::FromObject:
+		{
+			if (m->var().s_class == 0) {
+				m->item().s_class = 0;
+				return;
+			}
+			QPair<Item1, Item2> *pair = new QPair<Item1, Item2>();
+			
+			void *first = (*QPairGetFirst)(m->var().s_class);
+			if (Smoke::classMap[Item1STR]) {
+				smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(first);
+				if (o) pair->first = *(Item1*) o->ptr;
+			} else {
+				Smoke::StackItem item;
+				(*UnboxToStackItem)(first, &item);
+				// Smoke::StackItem is a union, so we can simply copy the data from 'item'
+				// when we know the size of it.
+				memcpy(&pair->first, &item, sizeof(Item1));
+			}
+			(*FreeGCHandle)(first);
+			
+			void *second = (*QPairGetSecond)(m->var().s_class);
+			if (Smoke::classMap[Item2STR]) {
+				smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(second);
+				if (o) pair->second = *(Item2*) o->ptr;
+			} else {
+				Smoke::StackItem item;
+				(*UnboxToStackItem)(second, &item);
+				memcpy(&pair->second, &item, sizeof(Item2));
+			}
+			(*FreeGCHandle)(second);
+			
+			m->item().s_voidp = pair;
+			m->next();
+			
+			(*FreeGCHandle)(m->var().s_voidp);
+
+			if (m->cleanup() || m->type().isStack()) {
+				delete pair;
+			}
+		}
+		break;
+      
+		case Marshall::ToObject:
+		{
+			QPair<Item1, Item2> *qpair = (QPair<Item1, Item2>*) m->item().s_voidp;
+			if (qpair == 0) {
+				m->var().s_voidp = 0;
+				return;
+			}
+
+			void *first, *second;
+			if (Smoke::classMap[Item1STR]) {
+				Smoke::ModuleIndex mi = m->smoke()->findClass(Item1STR);
+				Item1 *copy = new Item1(qpair->first);
+				smokeqyoto_object *o = alloc_smokeqyoto_object(true, mi.smoke, mi.index, copy);
+				first = (*CreateInstance)(Item1CliSTR, o);
+			} else {
+				Smoke::StackItem item;
+				memcpy(&item, &qpair->first, sizeof(Item1));
+				first = (*BoxFromStackItem)(Item1CliSTR, &item);
+			}
+			
+			if (Smoke::classMap[Item2STR]) {
+				Smoke::ModuleIndex mi = m->smoke()->findClass(Item2STR);
+				Item2 *copy = new Item2(qpair->second);
+				smokeqyoto_object *o = alloc_smokeqyoto_object(true, mi.smoke, mi.index, copy);
+				second = (*CreateInstance)(Item2CliSTR, o);
+			} else {
+				Smoke::StackItem item;
+				memcpy(&item, &qpair->second, sizeof(Item2));
+				second = (*BoxFromStackItem)(Item2CliSTR, &item);
+			}
+			
+			void *pair = (*CreateQPair)(first, second);
+			(*FreeGCHandle)(first);
+			(*FreeGCHandle)(second);
+			
+			m->var().s_voidp = pair;
+			m->next();
+
+			if (m->cleanup() || m->type().isStack()) {
+				delete qpair;
+			}
+		}
+		break;
+      
+		default:
+			m->unsupported();
+		break;
+	}
+}
+
+#define DEF_QPAIR_MARSHALLER(PairIdent,Item1,Item2,Item1CLI,Item2CLI) \
+        namespace { \
+            char PairIdent##Item1STR[] = #Item1; char PairIdent##Item2STR[] = #Item2; \
+            char PairIdent##Item1CliSTR[] = Item1CLI; char PairIdent##Item2CliSTR[] = Item2CLI; \
+        }  \
+        Marshall::HandlerFn marshall_##PairIdent = marshall_QPair<Item1,Item2,PairIdent##Item1STR,PairIdent##Item2STR, \
+            PairIdent##Item1CliSTR,PairIdent##Item2CliSTR>;
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyoto.h #966211:966212
@@ -84,6 +84,7 @@
 typedef void * (*DictToHash)(void *, int);
 typedef void * (*ConstructDict)(const char*, const char*);
 typedef void (*SetPropertyFn)(void *, const char*, void *);
+typedef void * (*CreateQPairFn)(void*, void*);
 
 extern Q_DECL_EXPORT QHash<Smoke*, QyotoModule> qyoto_modules;
 
@@ -165,6 +166,13 @@
 extern Q_DECL_EXPORT AddUInt AddUIntToListUInt;
 extern Q_DECL_EXPORT AddIntObject AddIntObjectToDictionary;
 
+extern Q_DECL_EXPORT GetIntPtr QPairGetFirst;
+extern Q_DECL_EXPORT GetIntPtr QPairGetSecond;
+extern Q_DECL_EXPORT CreateQPairFn CreateQPair;
+
+extern Q_DECL_EXPORT SetIntPtr UnboxToStackItem;
+extern Q_DECL_EXPORT CreateInstanceFn BoxFromStackItem;
+
 extern Q_DECL_EXPORT GetIntPtr GenericPointerGetIntPtr;
 extern Q_DECL_EXPORT CreateInstanceFn CreateGenericPointer;
 }



More information about the Kde-bindings mailing list