5 #include <glib-object.h>
11 #define U_OBJECT_GET_PRIV(o) \
12 G_TYPE_INSTANCE_GET_PRIVATE(o, U_OBJECT_TYPE, struct uobject_priv)
32 struct uobject_property {
41 unsigned char buf[2048];
46 get_real_size(unsigned long *real, unsigned size, unsigned char *buf, size_t n)
52 case 0: *real = 1; return 0;
53 case 1: *real = 2; return 0;
54 case 2: *real = 4; return 0;
55 case 3: *real = 12; return 0;
56 case 4: *real = 16; return 0;
63 *real = unpack_16_le(buf);
67 *real = unpack_32_le(buf);
75 decode_property(UObject *o, const char *name, struct upkg_file *f, unsigned long len)
77 struct uobject_priv *priv = U_OBJECT_GET_PRIV(o);
78 unsigned long real_size, rc;
82 if (priv->nbuf-len < 1)
85 type = (priv->buf[len] >> 0) & 0x0f;
86 size = (priv->buf[len] >> 4) & 0x07;
87 top = (priv->buf[len] >> 7) & 0x01;
90 rc = get_real_size(&real_size, size, priv->buf, priv->nbuf-len);
97 if (priv->nbuf-len < 1)
99 g_value_init(&val, G_TYPE_UCHAR);
100 g_value_set_uchar(&val, priv->buf[len]);
101 g_object_set_property(G_OBJECT(o), name, &val);
103 case PROPERTY_INTEGER:
104 if (priv->nbuf-len < 4)
106 g_value_init(&val, G_TYPE_ULONG);
107 g_value_set_ulong(&val, unpack_32_le(priv->buf+len));
108 g_object_set_property(G_OBJECT(o), name, &val);
111 fprintf(stderr, "Unhandled property type %x\n", (unsigned)type);
115 if (real_size + len <= priv->nbuf) {
116 priv->nbuf -= real_size;
117 memmove(priv->buf, priv->buf+real_size, priv->nbuf);
119 long skip = real_size - priv->nbuf;
120 if (upkg_export_seek(f, skip, SEEK_CUR) != 0)
128 /* Deserialize properties from an Unreal package. */
129 static int deserialize(UObject *o, struct upkg_file *f)
131 struct uobject_priv *priv = U_OBJECT_GET_PRIV(o);
132 unsigned long rc, tot_len = 0;
135 unsigned long len = 0;
139 /* Read some data into buffer. */
141 void *buf = priv->buf + priv->nbuf;
142 size_t amt = sizeof priv->buf - priv->nbuf;
143 rc = upkg_export_read(f, buf, amt);
149 /* Get the property name. */
150 rc = upkg_decode_index(&tmp, priv->buf+len, priv->nbuf-len);
155 name = upkg_get_name(f->pkg, tmp);
158 } else if (strcmp(name, "None") == 0) {
163 rc = decode_property(U_OBJECT(o), name, f, len);
173 upkg_export_seek(f, 0, SEEK_SET);
178 int u_object_deserialize(GObject *obj, struct upkg_file *f)
180 g_return_val_if_fail(IS_U_OBJECT(obj), -1);
181 return U_OBJECT_GET_CLASS(obj)->deserialize(U_OBJECT(obj), f);
184 static void u_object_init(UObject *o)
186 struct uobject_priv *priv = U_OBJECT_GET_PRIV(o);
189 static void u_object_class_init(UObjectClass *class)
191 g_type_class_add_private(class, sizeof (struct uobject_priv));
193 class->deserialize = deserialize;
196 G_DEFINE_TYPE(UObject, u_object, G_TYPE_OBJECT);