java-gobject-introspection r139 - in trunk: src/org/gnome/gir/compiler src/org/gnome/gir/gobject stub-examples
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r139 - in trunk: src/org/gnome/gir/compiler src/org/gnome/gir/gobject stub-examples
- Date: Sat, 29 Nov 2008 19:15:30 +0000 (UTC)
Author: walters
Date: Sat Nov 29 19:15:30 2008
New Revision: 139
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=139&view=rev
Log:
Add support for GList/GSList conversion to java.util.List, with generics
Added:
trunk/src/org/gnome/gir/gobject/GenericGList.java
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
trunk/src/org/gnome/gir/compiler/TypeMap.java
trunk/src/org/gnome/gir/gobject/GList.java
trunk/src/org/gnome/gir/gobject/GSList.java
trunk/src/org/gnome/gir/gobject/GType.java
trunk/src/org/gnome/gir/gobject/GlibRuntime.java
trunk/stub-examples/Test.java
Modified: trunk/src/org/gnome/gir/compiler/CodeFactory.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/CodeFactory.java (original)
+++ trunk/src/org/gnome/gir/compiler/CodeFactory.java Sat Nov 29 19:15:30 2008
@@ -69,8 +69,11 @@
import org.gnome.gir.gobject.GErrorException;
import org.gnome.gir.gobject.GErrorStruct;
+import org.gnome.gir.gobject.GList;
import org.gnome.gir.gobject.GObjectAPI;
+import org.gnome.gir.gobject.GSList;
import org.gnome.gir.gobject.GType;
+import org.gnome.gir.gobject.GenericGList;
import org.gnome.gir.gobject.GlibAPI;
import org.gnome.gir.gobject.GlibRuntime;
import org.gnome.gir.gobject.NativeObject;
@@ -106,6 +109,8 @@
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureVisitor;
+import org.objectweb.asm.signature.SignatureWriter;
import org.objectweb.asm.util.CheckClassAdapter;
import com.sun.jna.Callback;
@@ -183,6 +188,37 @@
static String getInternalNameMapped(BaseInfo info) {
return GType.getInternalNameMapped(info.getNamespace(), info.getName());
}
+
+ static boolean writeConversionToJava(MethodVisitor mv, TypeInfo info, Transfer transfer) {
+ TypeTag infoTag = info.getTag();
+ if (infoTag.equals(TypeTag.GLIST) || infoTag.equals(TypeTag.GSLIST)) {
+ if (infoTag.equals(TypeTag.GLIST)) {
+ mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GList.class), "fromNative",
+ Type.getMethodDescriptor(getType(GList.class), new Type[] { getType(Pointer.class) }));
+ } else {
+ mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GSList.class), "fromNative",
+ Type.getMethodDescriptor(getType(GSList.class), new Type[] { getType(Pointer.class) }));
+ }
+ mv.visitFieldInsn(GETSTATIC, getType(Transfer.class).getInternalName(),
+ transfer.name(), getType(Transfer.class).getDescriptor());
+ TypeInfo param = info.getParamType(0);
+ TypeTag paramTag = param.getTag();
+ if (paramTag.equals(TypeTag.UTF8)) {
+ mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GlibRuntime.class), "convertListUtf8",
+ Type.getMethodDescriptor(getType(List.class), new Type[] { getType(GenericGList.class), getType(Transfer.class) }));
+ return true;
+ } else if (paramTag.equals(TypeTag.INTERFACE)) {
+ BaseInfo paramInfo = param.getInterface();
+ Type eltClass = TypeMap.typeFromInfo(paramInfo);
+ mv.visitLdcInsn(eltClass);
+ mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GlibRuntime.class), "convertListGObject",
+ Type.getMethodDescriptor(getType(List.class), new Type[] { getType(GenericGList.class), getType(Transfer.class), getType(Class.class) }));
+ return true;
+ }
+ }
+
+ return false;
+ }
private void compile(EnumInfo info) {
ClassCompilation compilation = getCompilation(info);
@@ -970,6 +1006,7 @@
ArgInfo[] args;
Type thisType;
List<Type> argTypes;
+ String argSignature;
List<String> argNames = new ArrayList<String>();
boolean throwsGError;
boolean isInterfaceMethod = false;
@@ -1053,7 +1090,16 @@
} else {
if (ctx.isMethod && thisType != null)
ctx.thisType = Type.getObjectType(getInternalNameMapped(thisType));
- ctx.returnType = TypeMap.getCallableReturn(si);
+ ctx.returnType = TypeMap.getCallableReturn(si);
+ if (ctx.returnType != null && TypeMap.visitCallableReturnSignature(si, null)) {
+ SignatureVisitor visitor = new SignatureWriter();
+ SignatureVisitor returnVisitor = visitor.visitReturnType();
+ returnVisitor.visitClassType(ctx.returnType.getInternalName());
+ if (TypeMap.visitCallableReturnSignature(si, returnVisitor)) {
+ visitor.visitEnd();
+ ctx.argSignature = visitor.toString();
+ }
+ }
}
if (ctx.returnType == null) {
logger.warning("Skipping callable with unhandled return signature: "+ si.getIdentifier());
@@ -1150,9 +1196,9 @@
if (fi.isDeprecated()) {
accessFlags += ACC_DEPRECATED;
- }
+ }
MethodVisitor mv = compilation.writer.visitMethod(accessFlags,
- name, descriptor, null, exceptions);
+ name, descriptor, ctx.argSignature, exceptions);
if (fi.isDeprecated()) {
AnnotationVisitor av = mv.visitAnnotation(Type.getType(Deprecated.class).getDescriptor(), true);
av.visitEnd();
@@ -1172,7 +1218,9 @@
((returnTransfer.equals(Transfer.NOTHING) &&
(returnTypeTag.equals(TypeTag.INTERFACE))) ||
(returnTransfer.equals(Transfer.EVERYTHING) &&
- returnTypeTag.equals(TypeTag.UTF8))) {
+ returnTypeTag.equals(TypeTag.UTF8)) ||
+ returnTypeTag.equals(TypeTag.GLIST) ||
+ returnTypeTag.equals(TypeTag.GSLIST)) {
nativeReturnType = Type.getType(Pointer.class);
} else {
nativeReturnType = ctx.returnType;
@@ -1295,6 +1343,8 @@
/* Strings which are *not* const and must be g_free'd */
mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GlibRuntime.class), "toStringAndGFree",
Type.getMethodDescriptor(getType(String.class), new Type[] { getType(Pointer.class) }));
+ } else if (returnTypeTag.equals(TypeTag.GLIST) || returnTypeTag.equals(TypeTag.GSLIST)) {
+ writeConversionToJava(mv, returnGIType, returnTransfer);
} else {
throw new IllegalArgumentException(String.format("Unhandled nativeReturn %s vs public %s", nativeReturnType, ctx.returnType));
}
Modified: trunk/src/org/gnome/gir/compiler/TypeMap.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/TypeMap.java (original)
+++ trunk/src/org/gnome/gir/compiler/TypeMap.java Sat Nov 29 19:15:30 2008
@@ -26,6 +26,7 @@
import org.gnome.gir.repository.TypeTag;
import org.gnome.gir.repository.UnionInfo;
import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureVisitor;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
@@ -135,11 +136,51 @@
static Type getCallableReturn(CallableInfo callable) {
TypeInfo info = callable.getReturnType();
- if (info.getTag().equals(TypeTag.INTERFACE)) {
+ TypeTag tag = info.getTag();
+ if (tag.equals(TypeTag.INTERFACE)) {
return TypeMap.typeFromInfo(info);
+ } else if (tag.equals(TypeTag.GLIST) || tag.equals(TypeTag.GSLIST)) {
+ if (!isCallableReturnSignatureSupported(callable))
+ return null;
+ return Type.getType(List.class);
}
return toJava(info.getTag());
}
+
+ private static boolean isCallableReturnSignatureSupported(CallableInfo callable) {
+ TypeInfo info = callable.getReturnType();
+ TypeTag tag = info.getTag();
+ if (!(tag.equals(TypeTag.GLIST) || tag.equals(TypeTag.GSLIST)))
+ return true;
+ TypeInfo param = info.getParamType(0);
+ TypeTag paramTag = param.getTag();
+ if (!(paramTag.equals(TypeTag.UTF8) || paramTag.equals(TypeTag.INTERFACE)))
+ return false;
+ if (paramTag.equals(TypeTag.INTERFACE)) {
+ BaseInfo paramInfo = param.getInterface();
+ if (!(paramInfo instanceof ObjectInfo || paramInfo instanceof InterfaceInfo))
+ return false;
+ }
+ Type containedType = toJava(param);
+ if (containedType == null)
+ return false;
+ return true;
+ }
+
+ public static boolean visitCallableReturnSignature(CallableInfo callable, SignatureVisitor visitor) {
+ TypeInfo info = callable.getReturnType();
+ TypeTag tag = info.getTag();
+ if (!(tag.equals(TypeTag.GLIST) || tag.equals(TypeTag.GSLIST)))
+ return false;
+ TypeInfo param = info.getParamType(0);
+ Type containedType = toJava(param);
+ if (visitor == null)
+ return true;
+ SignatureVisitor paramVisitor = visitor.visitTypeArgument('=');
+ paramVisitor.visitClassType(containedType.getInternalName());
+ paramVisitor.visitEnd();
+ return true;
+ }
public static Type toJava(ArgInfo arg) {
if (arg.getDirection() == Direction.IN) {
Modified: trunk/src/org/gnome/gir/gobject/GList.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GList.java (original)
+++ trunk/src/org/gnome/gir/gobject/GList.java Sat Nov 29 19:15:30 2008
@@ -3,27 +3,51 @@
import java.util.ArrayList;
import java.util.List;
+import org.gnome.gir.repository.Transfer;
+
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
-public class GList extends Structure {
- public static class ByReference extends GList implements Structure.ByReference {};
+public class GList extends Structure implements GenericGList {
+ public static class ByReference extends GList implements Structure.ByReference {
+ public ByReference() {
+ super();
+ }
+ protected ByReference(Pointer p) {
+ super(p);
+ }
+ };
public Pointer data;
public GList.ByReference next;
public GList.ByReference prev;
- public List<Pointer> copy() {
- List<Pointer> ret = new ArrayList<Pointer>();
- GList list = this;
- while (list.next != null) {
- ret.add(list.data);
- list = list.next;
- }
- return ret;
+ protected GList(Pointer p) {
+ useMemory(p);
+ read();
}
-
+
+ public GList() {
+ }
+
+ public static GList fromNative(Pointer p) {
+ if (p == null)
+ return null;
+ return new GList(p);
+ }
+
+ @Override
public void free() {
GlibAPI.glib.g_list_free(this);
}
+
+ @Override
+ public Pointer getData() {
+ return data;
+ }
+
+ @Override
+ public GenericGList getNext() {
+ return next;
+ }
}
Modified: trunk/src/org/gnome/gir/gobject/GSList.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GSList.java (original)
+++ trunk/src/org/gnome/gir/gobject/GSList.java Sat Nov 29 19:15:30 2008
@@ -1,28 +1,48 @@
package org.gnome.gir.gobject;
-import java.util.ArrayList;
-import java.util.List;
-
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
-public class GSList extends Structure {
- public static class ByReference extends GSList implements Structure.ByReference {};
+public class GSList extends Structure implements GenericGList {
+ public static class ByReference extends GSList implements Structure.ByReference {
+ public ByReference() {
+ super();
+ }
+ protected ByReference(Pointer p) {
+ super(p);
+ }
+ };
public Pointer data;
public GSList.ByReference next;
- public List<Pointer> copy() {
- List<Pointer> ret = new ArrayList<Pointer>();
- GSList list = this;
- while (list.next != null) {
- ret.add(list.data);
- list = list.next;
- }
- return ret;
+ protected GSList(Pointer p) {
+ useMemory(p);
+ read();
}
+
+ public GSList() {
+ super();
+ }
+
+ public static GSList fromNative(Pointer p) {
+ if (p == null)
+ return null;
+ return new GSList(p);
+ }
+ @Override
public void free() {
GlibAPI.glib.g_slist_free(this);
- }
+ }
+
+ @Override
+ public Pointer getData() {
+ return data;
+ }
+
+ @Override
+ public GenericGList getNext() {
+ return next;
+ }
}
Modified: trunk/src/org/gnome/gir/gobject/GType.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GType.java (original)
+++ trunk/src/org/gnome/gir/gobject/GType.java Sat Nov 29 19:15:30 2008
@@ -70,8 +70,6 @@
{
put("GLib.Value", "org/gnome/gir/gobject/GValue");
- put("GLib.List", "org/gnome/gir/gobject/GList");
- put("GLib.SList", "org/gnome/gir/gobject/GSList");
put("GLib.MainContext", "org/gnome/gir/gobject/GMainContext");
put("GLib.Closure", "org/gnome/gir/gobject/GClosure");
@@ -94,7 +92,7 @@
"MappedFile" };
for (String unmapped : glibPointerUnmapped)
put("GLib." + unmapped, "com/sun/jna/Pointer");
- String[] glibIntegerUnmapped = new String[] { "SpawnFlags", "SeekType", "IOCondition", "RegexMatchFlags" };
+ String[] glibIntegerUnmapped = new String[] { "GList", "GSList", "SpawnFlags", "SeekType", "IOCondition", "RegexMatchFlags" };
for (String unmapped : glibIntegerUnmapped)
put("GLib." + unmapped, "java/lang/Integer");
Added: trunk/src/org/gnome/gir/gobject/GenericGList.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/gobject/GenericGList.java Sat Nov 29 19:15:30 2008
@@ -0,0 +1,9 @@
+package org.gnome.gir.gobject;
+
+import com.sun.jna.Pointer;
+
+public interface GenericGList {
+ public abstract Pointer getData();
+ public abstract GenericGList getNext();
+ public abstract void free();
+}
Modified: trunk/src/org/gnome/gir/gobject/GlibRuntime.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GlibRuntime.java (original)
+++ trunk/src/org/gnome/gir/gobject/GlibRuntime.java Sat Nov 29 19:15:30 2008
@@ -22,10 +22,14 @@
package org.gnome.gir.gobject;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import org.gnome.gir.repository.Transfer;
+
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
@@ -63,4 +67,35 @@
outstandingCallbacks.add(data);
return destroy;
}
+
+ public static List<String> convertListUtf8(GenericGList glist, Transfer transfer) {
+ List<String> ret = new ArrayList<String>();
+ GenericGList origList = glist;
+ boolean stringFree = transfer.equals(Transfer.EVERYTHING);
+ while (glist != null) {
+ Pointer data = glist.getData();
+ String p = data.getString(0);
+ if (stringFree)
+ GlibAPI.glib.g_free(data);
+ ret.add(p);
+ glist = glist.getNext();
+ }
+ if (!transfer.equals(Transfer.NOTHING))
+ origList.free();
+ return ret;
+ }
+
+ public static List<GObject> convertListGObject(GenericGList glist, Transfer transfer, Class<? extends NativeObject> klass) {
+ List<GObject> ret = new ArrayList<GObject>();
+ GenericGList origList = glist;
+ boolean objTransfer = transfer.equals(Transfer.EVERYTHING);
+ while (glist != null) {
+ GObject obj = (GObject) NativeObject.Internals.objectFor(glist.getData(), klass, objTransfer);
+ ret.add(obj);
+ glist = glist.getNext();
+ }
+ if (!transfer.equals(Transfer.NOTHING))
+ origList.free();
+ return ret;
+ }
}
Modified: trunk/stub-examples/Test.java
==============================================================================
--- trunk/stub-examples/Test.java (original)
+++ trunk/stub-examples/Test.java Sat Nov 29 19:15:30 2008
@@ -1,13 +1,17 @@
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.gnome.gir.gobject.GErrorException;
import org.gnome.gir.gobject.GErrorStruct;
+import org.gnome.gir.gobject.GList;
import org.gnome.gir.gobject.GObject;
import org.gnome.gir.gobject.GType;
import org.gnome.gir.gobject.GTypeMapper;
+import org.gnome.gir.gobject.GlibRuntime;
import org.gnome.gir.gobject.NativeObject;
import org.gnome.gir.gobject.annotation.Return;
import org.gnome.gir.repository.Direction;
@@ -180,6 +184,14 @@
f.invoke(Void.class, args, Internals.invocationOptions);
}
+ public List<GObject> cow() {
+ Function f = Internals.library.getFunction("gtk_cow");
+ Object[] args = new Object[] { this };
+ Pointer p = (Pointer) f.invoke(Pointer.class, args, Internals.invocationOptions);
+ GList list = GList.fromNative(p);
+ return GlibRuntime.convertListGObject(list, Transfer.EVERYTHING, GObject.class);
+ }
+
public void ifaceFoo(String blah) {
Function f = Internals.library.getFunction("gtk_propagate_event");
Object[] args = new Object[] { this, blah };
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]