/*
* 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,
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)
{
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);
}
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;