0dbad9f7526252808ca4c8535367ad950e7ccc5e
[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     mylog("+%08x(%d) tagmap_new", (int)self, self->ob_refcnt);
41     TagMapObject*tagmap = (TagMapObject*)self;
42     tagmap->obj2id = PyDict_New();
43     tagmap->id2obj = PyDict_New();
44     tagmap->objlist = PyList_New(0);
45     tagmap->currentID = 0; //IDs start at 1
46     return self;
47 }
48
49 //----------------------------------------------------------------------------
50 int tagmap_obj2id(PyObject* self, PyObject* obj)
51 {
52     TagMapObject*tagmap = (TagMapObject*)self;
53     PyObject*id = PyDict_GetItem(tagmap->obj2id, obj);
54     if(id == 0)
55         return -1;
56     int _id = PyLong_AsLong(id);
57     Py_DECREF(id);
58     return _id;
59 }
60
61 //----------------------------------------------------------------------------
62 PyObject* tagmap_id2obj(PyObject* self, int _id)
63 {
64     TagMapObject*tagmap = (TagMapObject*)self;
65     PyObject*id = PyLong_FromLong(_id);
66     PyObject*obj = PyDict_GetItem(tagmap->id2obj, id);
67     Py_DECREF(id);
68     return obj;
69 }
70 //----------------------------------------------------------------------------
71 int tagmap_getFreeID(PyObject*self)
72 {
73     TagMapObject*tagmap = (TagMapObject*)self;
74     int last = tagmap->currentID;
75     do {
76         tagmap->currentID++;
77         PyObject*id = PyLong_FromLong(tagmap->currentID);
78         PyObject*test = PyDict_GetItem(tagmap->id2obj,id);
79         Py_DECREF(id);
80         if(test == 0) {
81             PyErr_Clear();
82             mylog(" %08x(%d) tagmap_getFreeID -> %d", (int)self, self->ob_refcnt, tagmap->currentID);
83             return tagmap->currentID;
84         }
85     } while(last != tagmap->currentID);
86     mylog(" %08x(%d) tagmap_getFreeID -> -1", (int)self, self->ob_refcnt);
87     return -1;
88 }
89 //----------------------------------------------------------------------------
90 static void tagmap_add_mapping(PyObject*self, int id, PyObject* obj)
91 {
92     TagMapObject*tagmap = (TagMapObject*)self;
93     PyList_Append(tagmap->objlist, obj);//Py_INCREF(obj); done by PyList_Append
94     PyObject*id_obj = PyLong_FromLong(id);
95     PyDict_SetItem(tagmap->obj2id, obj, id_obj);//Py_INCREF(id_obj);Py_INCREF(obj); done by PyDict_SetItem
96     PyDict_SetItem(tagmap->id2obj, id_obj, obj);//Py_INCREF(id_obj);Py_INCREF(obj); done by PyDict_SetItem
97     Py_DECREF(id_obj);
98 }
99 //----------------------------------------------------------------------------
100 void tagmap_addMapping(PyObject*self, int id, PyObject* obj)
101 {
102     TagMapObject*tagmap = (TagMapObject*)self;
103     int id2 = tagmap_obj2id(self, obj);
104     if(id2>=0) {
105         assert(id==id2);
106         return;
107     }
108     tagmap_add_mapping(self, id, obj);
109 }
110 //----------------------------------------------------------------------------
111 int tagmap_add(PyObject* self, PyObject* obj)
112 {
113     TagMapObject*tagmap = (TagMapObject*)self;
114     int id = tagmap_obj2id(self, obj);
115     if(id>=0) {
116         mylog(" %08x(%d) tagmap_add %08x->%d (again)", (int)self, self->ob_refcnt, (int)obj, id);
117         return id;
118     }
119     id = tagmap_getFreeID(self);
120     
121     tagmap_add_mapping(self, id, obj);
122
123     mylog(" %08x(%d) tagmap_add %08x->%d", (int)self, self->ob_refcnt, (int)obj, id);
124     return id;
125 }
126
127 //----------------------------------------------------------------------------
128 void tagmap_dealloc(PyObject* self)
129 {
130     TagMapObject*tagmap = (TagMapObject*)self;
131     mylog("-%08x(%d) tagmap_dealloc %08x(%d) %08x(%d), %08x(%d)", (int)self, self->ob_refcnt,
132             tagmap->obj2id, tagmap->obj2id->ob_refcnt ,
133             tagmap->id2obj, tagmap->id2obj->ob_refcnt ,
134             tagmap->objlist, tagmap->objlist->ob_refcnt);
135
136     Py_DECREF(tagmap->obj2id);
137     tagmap->obj2id = 0;
138     Py_DECREF(tagmap->id2obj);
139     tagmap->id2obj = 0;
140     Py_DECREF(tagmap->objlist);
141     tagmap->objlist = 0;
142     PyObject_Del(self);
143 }
144 //----------------------------------------------------------------------------
145 PyObject* tagmap_getObjectList(PyObject* self)
146 {
147     mylog(" %08x(%d) tagmap_getObjectList", (int)self, self->ob_refcnt);
148     TagMapObject*tagmap = (TagMapObject*)self;
149     return tagmap->objlist;
150 }
151 //----------------------------------------------------------------------------
152 PyTypeObject TagMapClass = 
153 {
154     PyObject_HEAD_INIT(NULL)
155     0,
156     tp_name: "TagMap",
157     tp_basicsize: sizeof(TagMapObject),
158     tp_itemsize: 0,
159     tp_dealloc: tagmap_dealloc,
160     tp_print: 0,
161     tp_getattr: 0,
162     tp_setattr: 0,
163 };