6 #include "primitives.h"
11 //----------------------------------------------------------------------------
13 typedef struct _TagObject {
15 tag_internals_t internals;
18 //----------------------------------------------------------------------------
19 static PyMethodDef generic_methods[] =
23 static tag_internals_t generic_tag =
28 tagfunctions: generic_methods,
31 //----------------------------------------------------------------------------
33 static struct tag_parser {
36 struct tag_parser* next;
38 static char parsers_initialized = 0;
40 void register_tag(int id, tag_internals_t*spec)
42 assert(id>=0 && id<1024);
43 if(!parsers_initialized) {
44 memset(tag_parsers, 0, sizeof(tag_parsers));
45 parsers_initialized = 1;
47 tag_parsers[id].id = id;
48 tag_parsers[id].spec = spec;
51 static tag_internals_t* get_parser(int id)
53 if(parsers_initialized<2) {
55 struct tag_parser*last = &tag_parsers[0];
57 if(tag_parsers[t].spec) {
58 last->next = &tag_parsers[t];
59 last = &tag_parsers[t];
62 parsers_initialized = 2;
64 assert(id>=0 && id<1024);
65 return tag_parsers[id].spec;
68 //----------------------------------------------------------------------------
69 static void tag_dealloc(PyObject * self)
71 TagObject*tag = (TagObject*)self;
72 if(tag->internals.tag)
73 mylog("-%08x(%d) tag_dealoc [%s]\n", (int)self, self->ob_refcnt, swf_TagGetName(tag->internals.tag));
75 mylog("-%08x(%d) tag_dealoc [?]\n", (int)self, self->ob_refcnt);
76 if(tag->internals.dealloc) {
77 if(!tag->internals.data)
78 mylog("-%08x(%d) tag_dealoc: Warning: calling dealloc without any data(?)\n", (int)self, self->ob_refcnt);
79 tag->internals.dealloc(&tag->internals);
81 if(tag->internals.data) {
82 free(tag->internals.data);
83 tag->internals.data = 0;
85 if(tag->internals.tag) {
86 swf_DeleteTag(0, tag->internals.tag);
87 tag->internals.tag = 0;
89 Py_DECREF(tag->internals.tagmap);
90 tag->internals.tagmap = 0;
93 //----------------------------------------------------------------------------
94 static int fillTAG(PyObject*self)
96 TagObject*tag = (TagObject*)self;
97 if(tag->internals.tag)
99 if(!tag->internals.fillTAG) {
100 PyErr_SetString(PyExc_Exception, setError("No way to fill TAG with data"));
103 if(!tag->internals.fillTAG(&tag->internals)) {
104 return 0; // pass through exception
106 if(!tag->internals.tag) {
107 PyErr_SetString(PyExc_Exception, setError("Couldn't fill tag"));
112 //----------------------------------------------------------------------------
113 static PyObject* tag_isShape(PyObject * _self, PyObject*args)
115 TagObject*self = (TagObject*)_self;
116 if(!PyArg_ParseTuple(args, "")) return NULL;
117 if(!fillTAG((PyObject*)self)) return NULL;
118 return PyInt_FromLong(swf_isShapeTag(self->internals.tag));
120 static PyObject* tag_isFont(PyObject * _self, PyObject*args)
122 TagObject*self = (TagObject*)_self;
123 if(!PyArg_ParseTuple(args, "")) return NULL;
124 if(!fillTAG((PyObject*)self)) return NULL;
125 int id = self->internals.tag->id;
127 if(id == ST_DEFINEFONT || id == ST_DEFINEFONT2)
129 return PyInt_FromLong(isfont);
131 static PyObject* tag_isImage(PyObject * _self, PyObject*args)
133 TagObject*self = (TagObject*)_self;
134 if(!PyArg_ParseTuple(args, "")) return NULL;
135 if(!fillTAG((PyObject*)self)) return NULL;
136 return PyInt_FromLong(swf_isImageTag(self->internals.tag));
138 static PyObject* tag_isDefiningTag(PyObject * _self, PyObject*args)
140 TagObject*self = (TagObject*)_self;
141 if(!PyArg_ParseTuple(args, "")) return NULL;
142 if(!fillTAG((PyObject*)self)) return NULL;
143 return PyInt_FromLong(swf_isDefiningTag(self->internals.tag));
145 static PyObject* tag_isPlacement(PyObject * _self, PyObject*args)
147 TagObject*self = (TagObject*)_self;
148 if(!PyArg_ParseTuple(args, "")) return NULL;
149 if(!fillTAG((PyObject*)self)) return NULL;
150 return PyInt_FromLong((self->internals.tag->id == ST_PLACEOBJECT ||
151 self->internals.tag->id == ST_PLACEOBJECT2));
153 static PyObject* tag_getBBox(PyObject * _self, PyObject*args)
155 TagObject*self = (TagObject*)_self;
156 if(!PyArg_ParseTuple(args, "")) return NULL;
157 if(!fillTAG((PyObject*)self)) return NULL;
158 return f_BBox2(swf_GetDefineBBox(self->internals.tag));
160 static PyObject* tag_setBBox(PyObject * _self, PyObject*args)
162 TagObject*self = (TagObject*)_self;
164 if(!PyArg_ParseTuple(args, "O!", &BBoxClass, &bbox)) return NULL;
165 if(!fillTAG((PyObject*)self)) return NULL;
166 swf_SetDefineBBox(self->internals.tag, bbox_getSRECT(bbox));
169 //----------------------------------------------------------------------------
170 static PyMethodDef common_tagfunctions[] =
171 {{"isShape", tag_isShape, METH_VARARGS, "tests whether the tag is a shape tag"},
172 {"isImage", tag_isImage, METH_VARARGS, "tests whether the tag is an image"},
173 {"isFont", tag_isFont, METH_VARARGS, "tests whether the tag is a font"},
174 {"isDefiningTag", tag_isDefiningTag, METH_VARARGS, "tests whether the tag is a defining tag"},
175 {"isPlacement", tag_isPlacement, METH_VARARGS, "tests whether the tag is a placement"},
176 {"getBBox", tag_getBBox, METH_VARARGS, "get's the tags bounding box"},
177 {"setBBox", tag_setBBox, METH_VARARGS, "set's the tags bounding box"},
178 {NULL, NULL, 0, NULL}
181 static PyObject* tag_getattr(PyObject * self, char* a)
183 TagObject*tag = (TagObject*)self;
184 PyObject* ret = NULL;
188 if(!strcmp(a, "tagid")) {
191 return Py_BuildValue("i", tag->internals.tag->id);
193 if(!strcmp(a, "name")) {
196 char* name = swf_TagGetName(tag->internals.tag);
197 return Py_BuildValue("s", name);
199 if(!strcmp(a, "data")) {
202 return Py_BuildValue("s#", tag->internals.tag->data, tag->internals.tag->len);
204 if(tag->internals.getattr) {
205 PyObject* ret = tag->internals.getattr(&tag->internals, a);
209 /* search for a tag specific function */
210 if(tag->internals.tagfunctions) {
211 mylog(" %08x(%d) tag_getattr: tag has specific functions\n", (int)self, self->ob_refcnt);
212 ret = Py_FindMethod(tag->internals.tagfunctions, self, a);
215 ret = FindMethodMore(ret, common_tagfunctions, self, a);
216 mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
221 ret = Py_FindMethod(common_tagfunctions, self, a);
223 mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
226 static int tag_setattr(PyObject * _self, char* a, PyObject * o)
228 TagObject*self= (TagObject*)_self;
229 /* a setattr will almost certainly change the tag data,
231 if(self->internals.tag) {
232 swf_DeleteTag(0, self->internals.tag);
233 self->internals.tag = 0;
235 if(self->internals.setattr) {
236 int ret = self->internals.setattr(&self->internals, a, o);
241 //----------------------------------------------------------------------------
243 //----------------------------------------------------------------------------
244 PyObject* tag_new(tag_internals_t*tag_internals)
246 TagObject*tag = PyObject_New(TagObject, &TagClass);
247 mylog("+%08x(%d) tag_new\n", (int)tag, tag->ob_refcnt);
248 memcpy(&tag->internals, tag_internals, sizeof(tag_internals_t));
249 if(tag->internals.datasize) {
250 tag->internals.data = malloc(tag->internals.datasize);
251 memset(tag->internals.data , 0, tag->internals.datasize);
253 tag->internals.data = 0;
255 tag->internals.tag = 0;
256 tag->internals.tagmap = tagmap_new();
258 return (PyObject*)tag;
260 PyObject* tag_new2(TAG*t, PyObject* tagmap)
262 TagObject*tag = PyObject_New(TagObject, &TagClass);
263 mylog("+%08x(%d) tag_new2 tag=%08x id=%d (%s)\n", (int)tag, tag->ob_refcnt, t, t->id, swf_TagGetName(t));
265 PyObject*mytagmap = tagmap_new();
267 int num = swf_GetNumUsedIDs(t);
268 if(num) { // tag has dependencies
269 int * positions = malloc(num*sizeof(int));
270 swf_GetUsedIDs(t, positions);
273 int id = GET16(&t->data[positions[i]]);
274 PyObject*obj = tagmap_id2obj(tagmap, id);
276 PyErr_SetString(PyExc_Exception, setError("TagID %d not defined", id));
279 //mylog("+%08x(%d) tag_new2 handling id %d at %d/%d\n", (int)tag, tag->ob_refcnt, id, positions[i], t->len);
280 //mylog("+%08x(%d) tag_new2 add dependency %d to id %d, object %08x(%d)\n", (int)tag, tag->ob_refcnt, i, id, obj, obj->ob_refcnt);
281 tagmap_addMapping(mytagmap, id, obj);
286 tag_internals_t*spec = get_parser(t->id);
288 memcpy(&tag->internals, spec, sizeof(tag_internals_t));
290 memcpy(&tag->internals, &generic_tag, sizeof(tag_internals_t));
292 if(tag->internals.datasize) {
293 tag->internals.data = malloc(tag->internals.datasize);
294 memset(tag->internals.data, 0, tag->internals.datasize);
296 tag->internals.data = 0;
298 tag->internals.tag = swf_InsertTag(0, t->id);
299 swf_SetBlock(tag->internals.tag, t->data, t->len);
300 tag->internals.tagmap = mytagmap;
302 // call tag->internals.init()?
304 return (PyObject*)tag;
306 //----------------------------------------------------------------------------
308 TAG* tag_getTAG(PyObject*self, TAG*prevTag, PyObject*tagmap)
310 TagObject*tag = (TagObject*)self;
314 mylog(" %08x(%d) tag_getTAG: tag=%08x id=%d (%s)", (int)self, self->ob_refcnt, tag->internals.tag, tag->internals.tag->id, swf_TagGetName(tag->internals.tag));
316 TAG* t = swf_InsertTag(prevTag, tag->internals.tag->id);
317 swf_SetBlock(t, tag->internals.tag->data, tag->internals.tag->len);
319 if(swf_isDefiningTag(t)) {
320 int newid = tagmap_add(tagmap, self);
321 swf_SetDefineID(t, newid);
324 int num = swf_GetNumUsedIDs(t);
325 if(num) { // tag has dependencies
326 int * positions = malloc(num*sizeof(int));
327 swf_GetUsedIDs(t, positions);
330 int id = GET16(&t->data[positions[i]]);
331 PyObject* obj = tagmap_id2obj(tag->internals.tagmap, id);
333 PyErr_SetString(PyExc_Exception, setError("Internal error: id %d not known in taglist:"));
337 //int newid = tagmap_obj2id(tag->internals.tagmap, obj);
338 int newid = tagmap_obj2id(tagmap, obj);
340 mylog(" %08x(%d) tag_getTAG: dependency %d) %d->%08x -> assigning(%08x) id %d", (int)self, self->ob_refcnt, i, id, obj, tagmap, newid);
342 /* TODO: this is only needed for sprites, so maybe it should throw an
343 exception otherwise */
344 newid = tagmap_add(tagmap, obj);
345 mylog(" %08x(%d) tag_getTAG: added dependency %d) %d->%08x -> assigning(%08x) id %d", (int)self, self->ob_refcnt, i, id, obj, tagmap, newid);
347 PUT16(&t->data[positions[i]], newid);
353 //----------------------------------------------------------------------------
354 tag_internals_t* tag_getinternals(PyObject*self)
356 TagObject*tag = (TagObject*)self;
357 mylog(" %08x(%d) tag_getInternals\n", (int)self, self->ob_refcnt);
358 return &tag->internals;
360 //----------------------------------------------------------------------------
361 PyObject* tag_getDependencies(PyObject*self)
363 TagObject*tag = (TagObject*)self;
364 mylog(" %08x(%d) tag_getDependencies\n", (int)self, self->ob_refcnt);
365 return tagmap_getObjectList(tag->internals.tagmap);
367 //----------------------------------------------------------------------------
368 int tag_print(PyObject * self, FILE * fi, int flags)
370 TagObject*tag = (TagObject*)self;
371 mylog(" %08x(%d) tag_print flags=%08x\n", (int)self, self->ob_refcnt, flags);
374 //fprintf(fi, "tag-%08x-%d-%s", (int)tag->internals.tag, tag->internals.tag->id, swf_TagGetName(tag->internals.tag));
375 fprintf(fi, "%s", swf_TagGetName(tag->internals.tag));
378 //----------------------------------------------------------------------------
379 PyTypeObject TagClass =
381 PyObject_HEAD_INIT(NULL)
384 tp_basicsize: sizeof(TagObject),
386 tp_dealloc: tag_dealloc,
388 tp_getattr: tag_getattr,
389 tp_setattr: tag_setattr,