]> git.draconx.ca Git - upkg.git/blobdiff - src/uobject/uobject.c
uobject: Rename U_OBJECT_TYPE to U_TYPE_OBJECT.
[upkg.git] / src / uobject / uobject.c
index 6ad6f76ac01cd986e5ee1904b56944c289fee4b2..a64cf17718f5259b7fcdf91db37fbb545099eb49 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  upkg: tool for manipulating Unreal Tournament packages.
- *  Copyright (C) 2009 Nick Bowler
+ *  Copyright © 2009-2011 Nick Bowler
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 #include <glib-object.h>
 
 #include <uobject/uobject.h>
+#include <uobject/module.h>
 #include "upkg.h"
 #include "pack.h"
 
 #define U_OBJECT_GET_PRIV(o) \
-       G_TYPE_INSTANCE_GET_PRIVATE(o, U_OBJECT_TYPE, struct u_object_priv)
+       G_TYPE_INSTANCE_GET_PRIVATE(o, U_TYPE_OBJECT, struct u_object_priv)
 
 enum {
        PROPERTY_BYTE = 1,
@@ -86,6 +87,34 @@ get_real_size(unsigned long *real, unsigned size, unsigned char *buf, size_t n)
        return 0;
 }
 
+static int decode_object_property(UObject *uo, GValue *val, unsigned long len)
+{
+       struct u_object_priv *priv = U_OBJECT_GET_PRIV(uo);
+       GObject *obj = NULL;
+       long index;
+       int rc;
+
+       rc = upkg_decode_index(&index, priv->buf+len, priv->nbuf-len);
+       if (rc == 0 || index == 0)
+               return -1;
+
+       if (index < 0) {
+               fprintf(stderr, "Imports not supported yet.\n");
+       } else {
+               obj = u_object_new_from_package(uo->pkg, index-1);
+       }
+
+       g_value_init(val, U_TYPE_OBJECT);
+       g_value_take_object(val, obj);
+       return 0;
+}
+
+/*
+ * XXX: I must have been smoking the happy plant when I started property
+ * decoding.  The tracking of various sizes in these functions makes no
+ * sense at all.
+ */
+
 static unsigned long
 decode_property(UObject *o, const char *name, struct upkg_file *f, unsigned long len)
 {
@@ -122,6 +151,12 @@ decode_property(UObject *o, const char *name, struct upkg_file *f, unsigned long
                g_value_set_ulong(&val, unpack_32_le(priv->buf+len));
                g_object_set_property(G_OBJECT(o), name, &val);
                break;
+       case PROPERTY_OBJECT:
+               rc = decode_object_property(o, &val, len);
+               if (rc != 0)
+                       return 0;
+               g_object_set_property(G_OBJECT(o), name, &val);
+               break;
        default:
                fprintf(stderr, "Unhandled property type %x\n", (unsigned)type);
        }
@@ -216,6 +251,27 @@ int u_object_deserialize(GObject *obj, struct upkg *pkg, unsigned long idx)
        return rc;
 }
 
+GObject *u_object_new_from_package(struct upkg *upkg, unsigned long idx)
+{
+       const struct upkg_export *export;
+       const char *class, *package;
+       GObject *obj = NULL;
+       GType type;
+
+       class = upkg_export_class(upkg, idx, &package);
+
+       type = u_object_module_get_class(package, class);
+       if (type) {
+               obj = g_object_new(type, NULL);
+               if (u_object_deserialize(obj, upkg, idx) != 0) {
+                       g_object_unref(obj);
+                       return NULL;
+               }
+       }
+
+       return obj;
+}
+
 static void u_object_init(UObject *o)
 {
        o->pkg      = NULL;