more fiddling with edgestyles
[swftools.git] / lib / python / tagmap.c
1 /* tagmap.c
2
3    Python wrapper for librfxswf.
4
5    Part of the swftools package.
6
7    Copyright (c) 2003 Matthias Kramm <kramm@quiss.org>
8  
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
22
23 #include <Python.h>
24 #undef HAVE_STAT
25 #include "pyutils.h"
26 #include "tagmap.h"
27
28 typedef struct {
29     PyObject_HEAD
30     PyObject* obj2id;
31     PyObject* id2obj;
32     PyObject* objlist;
33     int currentID;
34 } TagMapObject;
35
36 //----------------------------------------------------------------------------
37 PyObject* tagmap_new()
38 {
39     PyObject* self = (PyObject*)PyObject_New(TagMapObject, &TagMapClass);
40     TagMapObject*tagmap = (TagMapObject*)self;
41     tagmap->obj2id = PyDict_New();
42     tagmap->id2obj = PyDict_New();
43     tagmap->objlist = PyList_New(0);
44     tagmap->currentID = 0; //IDs start at 1
45 /*    mylog("+%08x(%d) tagmap_new %08x(%d) %08x(%d), %08x(%d)", (int)self, self->ob_refcnt,
46             tagmap->obj2id, tagmap->obj2id->ob_refcnt ,
47             tagmap->id2obj, tagmap->id2obj->ob_refcnt ,
48             tagmap->objlist, tagmap->objlist->ob_refcnt);*/
49     return self;
50 }
51
52 //----------------------------------------------------------------------------
53 int tagmap_obj2id(PyObject* self, PyObject* obj)
54 {
55     TagMapObject*tagmap = (TagMapObject*)self;
56     PyObject*id = PyDict_GetItem(tagmap->obj2id, obj);
57     if(id == 0)
58         return -1;
59     int _id = PyLong_AsLong(id);
60     return _id;
61 }
62
63 //----------------------------------------------------------------------------
64 PyObject* tagmap_id2obj(PyObject* self, int _id)
65 {
66     TagMapObject*tagmap = (TagMapObject*)self;
67     PyObject*id = PyLong_FromLong(_id);
68     PyObject*obj = PyDict_GetItem(tagmap->id2obj, id);
69     Py_DECREF(id);
70     return obj;
71 }
72 //----------------------------------------------------------------------------
73 int tagmap_getFreeID(PyObject*self)
74 {
75     TagMapObject*tagmap = (TagMapObject*)self;
76     int last = tagmap->currentID;
77     do {
78         tagmap->currentID++;
79         PyObject*id = PyLong_FromLong(tagmap->currentID);
80         PyObject*test = PyDict_GetItem(tagmap->id2obj,id);
81         Py_DECREF(id);
82         if(test == 0) {
83             PyErr_Clear();
84             mylog(" %08x(%d) tagmap_getFreeID -> %d", (int)self, self->ob_refcnt, tagmap->currentID);
85             return tagmap->currentID;
86         }
87     } while(last != tagmap->currentID);
88     mylog(" %08x(%d) tagmap_getFreeID -> -1", (int)self, self->ob_refcnt);
89     return -1;
90 }
91 //----------------------------------------------------------------------------
92 static void tagmap_add_mapping(PyObject*self, int id, PyObject* obj)
93 {
94     TagMapObject*tagmap = (TagMapObject*)self;
95     PyList_Append(tagmap->objlist, obj);//Py_INCREF(obj); done by PyList_Append
96     PyObject*id_obj = PyLong_FromLong(id);
97     PyDict_SetItem(tagmap->obj2id, obj, id_obj);//Py_INCREF(id_obj);Py_INCREF(obj); done by PyDict_SetItem
98     PyDict_SetItem(tagmap->id2obj, id_obj, obj);//Py_INCREF(id_obj);Py_INCREF(obj); done by PyDict_SetItem
99     Py_DECREF(id_obj);
100 }
101 //----------------------------------------------------------------------------
102 void tagmap_addMapping(PyObject*self, int id, PyObject* obj)
103 {
104     TagMapObject*tagmap = (TagMapObject*)self;
105     int id2 = tagmap_obj2id(self, obj);
106     if(id2>=0) {
107         assert(id==id2);
108         return;
109     }
110     tagmap_add_mapping(self, id, obj);
111 }
112 //----------------------------------------------------------------------------
113 int tagmap_add(PyObject* self, PyObject* obj)
114 {
115     TagMapObject*tagmap = (TagMapObject*)self;
116     int id = tagmap_obj2id(self, obj);
117     if(id>=0) {
118         mylog(" %08x(%d) tagmap_add %08x->%d (again)", (int)self, self->ob_refcnt, (int)obj, id);
119         return id;
120     }
121     id = tagmap_getFreeID(self);
122     
123     tagmap_add_mapping(self, id, obj);
124
125     mylog(" %08x(%d) tagmap_add %08x->%d", (int)self, self->ob_refcnt, (int)obj, id);
126     return id;
127 }
128
129 //----------------------------------------------------------------------------
130 void tagmap_dealloc(PyObject* self)
131 {
132     TagMapObject*tagmap = (TagMapObject*)self;
133     mylog("-%08x(%d) tagmap_dealloc %08x(%d) %08x(%d), %08x(%d)", (int)self, self->ob_refcnt,
134             tagmap->obj2id, tagmap->obj2id->ob_refcnt ,
135             tagmap->id2obj, tagmap->id2obj->ob_refcnt ,
136             tagmap->objlist, tagmap->objlist->ob_refcnt);
137
138     Py_DECREF(tagmap->obj2id);
139     tagmap->obj2id = 0;
140     Py_DECREF(tagmap->id2obj);
141     tagmap->id2obj = 0;
142     Py_DECREF(tagmap->objlist);
143     tagmap->objlist = 0;
144     PyObject_Del(self);
145 }
146 //----------------------------------------------------------------------------
147 PyObject* tagmap_getObjectList(PyObject* self)
148 {
149     mylog(" %08x(%d) tagmap_getObjectList", (int)self, self->ob_refcnt);
150     TagMapObject*tagmap = (TagMapObject*)self;
151     return tagmap->objlist;
152 }
153 //----------------------------------------------------------------------------
154 PyTypeObject TagMapClass = 
155 {
156     PyObject_HEAD_INIT(NULL)
157     0,
158     tp_name: "TagMap",
159     tp_basicsize: sizeof(TagMapObject),
160     tp_itemsize: 0,
161     tp_dealloc: tagmap_dealloc,
162     tp_print: 0,
163     tp_getattr: 0,
164     tp_setattr: 0,
165 };