X-Git-Url: http://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/c49355663c73c1775c179ec6360d09ce0978bb97..7a9046e942bc1f880f121f0be7e05ef80a0270c8:/src/uobject/uobject.c diff --git a/src/uobject/uobject.c b/src/uobject/uobject.c index 4bc1655..a64cf17 100644 --- a/src/uobject/uobject.c +++ b/src/uobject/uobject.c @@ -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 @@ -23,11 +23,12 @@ #include #include +#include #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); } @@ -168,7 +203,7 @@ static int deserialize(UObject *uo) return -1; len = rc; - name = upkg_get_name(f->pkg, tmp); + name = upkg_get_name(uo->pkg, tmp); if (!name) { return -1; } else if (strcmp(name, "None") == 0) { @@ -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;