]>
Commit | Line | Data |
---|---|---|
c90f71dd RD |
1 | /***************************************************************************** |
2 | * $Header$ | |
3 | * | |
4 | * swigptr.swg | |
5 | * | |
6 | * This file contains supporting code for the SWIG run-time type checking | |
7 | * mechanism. The following functions are available : | |
8 | * | |
9 | * SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)); | |
10 | * | |
11 | * Registers a new type-mapping with the type-checker. origtype is the | |
12 | * original datatype and newtype is an equivalent type. cast is optional | |
13 | * pointer to a function to cast pointer values between types (this | |
14 | * is typically used to cast pointers from derived classes to base classes in C++) | |
15 | * | |
16 | * SWIG_MakePtr(char *buffer, void *ptr, char *typestring); | |
17 | * | |
18 | * Makes a pointer string from a pointer and typestring. The result is returned | |
19 | * in buffer which is assumed to hold enough space for the result. | |
20 | * | |
21 | * char * SWIG_GetPtr(char *buffer, void **ptr, char *type) | |
22 | * | |
23 | * Gets a pointer value from a string. If there is a type-mismatch, returns | |
24 | * a character string to the received type. On success, returns NULL. | |
25 | * | |
26 | * | |
27 | * You can remap these functions by making a file called "swigptr.swg" in | |
28 | * your the same directory as the interface file you are wrapping. | |
29 | * | |
30 | * These functions are normally declared static, but this file can be | |
31 | * can be used in a multi-module environment by redefining the symbol | |
32 | * SWIGSTATIC. | |
33 | *****************************************************************************/ | |
34 | ||
35 | #include <stdlib.h> | |
36 | ||
37 | #ifdef __cplusplus | |
38 | extern "C" { | |
39 | #endif | |
40 | ||
41 | #ifdef SWIG_GLOBAL | |
42 | #define SWIGSTATIC | |
43 | #endif | |
44 | ||
45 | #ifndef SWIGSTATIC | |
46 | #define SWIGSTATIC static | |
47 | #endif | |
48 | ||
49 | ||
50 | ||
51 | /* SWIG pointer structure */ | |
52 | ||
53 | typedef struct SwigPtrType { | |
54 | char *name; /* Datatype name */ | |
55 | int len; /* Length (used for optimization) */ | |
56 | void *(*cast)(void *); /* Pointer casting function */ | |
57 | struct SwigPtrType *next; /* Linked list pointer */ | |
58 | } SwigPtrType; | |
59 | ||
60 | /* Pointer cache structure */ | |
61 | ||
62 | typedef struct { | |
63 | int stat; /* Status (valid) bit */ | |
64 | SwigPtrType *tp; /* Pointer to type structure */ | |
65 | char name[256]; /* Given datatype name */ | |
66 | char mapped[256]; /* Equivalent name */ | |
67 | } SwigCacheType; | |
68 | ||
69 | /* Some variables */ | |
70 | ||
71 | static int SwigPtrMax = 64; /* Max entries that can be currently held */ | |
72 | /* This value may be adjusted dynamically */ | |
73 | static int SwigPtrN = 0; /* Current number of entries */ | |
74 | static int SwigPtrSort = 0; /* Status flag indicating sort */ | |
75 | static int SwigStart[256]; /* Starting positions of types */ | |
76 | ||
77 | /* Pointer table */ | |
78 | static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ | |
79 | ||
80 | /* Cached values */ | |
81 | ||
82 | #define SWIG_CACHESIZE 8 | |
83 | #define SWIG_CACHEMASK 0x7 | |
84 | static SwigCacheType SwigCache[SWIG_CACHESIZE]; | |
85 | static int SwigCacheIndex = 0; | |
86 | static int SwigLastCache = 0; | |
87 | ||
88 | /* Sort comparison function */ | |
89 | static int swigsort(const void *data1, const void *data2) { | |
90 | SwigPtrType *d1 = (SwigPtrType *) data1; | |
91 | SwigPtrType *d2 = (SwigPtrType *) data2; | |
92 | return strcmp(d1->name,d2->name); | |
93 | } | |
94 | ||
95 | /* Binary Search function */ | |
96 | static int swigcmp(const void *key, const void *data) { | |
97 | char *k = (char *) key; | |
98 | SwigPtrType *d = (SwigPtrType *) data; | |
99 | return strncmp(k,d->name,d->len); | |
100 | } | |
101 | ||
102 | /* Register a new datatype with the type-checker */ | |
103 | ||
104 | SWIGSTATIC | |
105 | void SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { | |
106 | ||
107 | int i; | |
108 | SwigPtrType *t = 0,*t1; | |
109 | ||
110 | /* Allocate the pointer table if necessary */ | |
111 | ||
112 | if (!SwigPtrTable) { | |
113 | SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); | |
114 | SwigPtrN = 0; | |
115 | } | |
116 | /* Grow the table */ | |
117 | if (SwigPtrN >= SwigPtrMax) { | |
118 | SwigPtrMax = 2*SwigPtrMax; | |
119 | SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); | |
120 | } | |
121 | for (i = 0; i < SwigPtrN; i++) | |
122 | if (strcmp(SwigPtrTable[i].name,origtype) == 0) { | |
123 | t = &SwigPtrTable[i]; | |
124 | break; | |
125 | } | |
126 | if (!t) { | |
127 | t = &SwigPtrTable[SwigPtrN]; | |
128 | t->name = origtype; | |
129 | t->len = strlen(t->name); | |
130 | t->cast = 0; | |
131 | t->next = 0; | |
132 | SwigPtrN++; | |
133 | } | |
134 | ||
135 | /* Check for existing entry */ | |
136 | ||
137 | while (t->next) { | |
138 | if ((strcmp(t->name,newtype) == 0)) { | |
139 | if (cast) t->cast = cast; | |
140 | return; | |
141 | } | |
142 | t = t->next; | |
143 | } | |
144 | ||
145 | /* Now place entry (in sorted order) */ | |
146 | ||
147 | t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); | |
148 | t1->name = newtype; | |
149 | t1->len = strlen(t1->name); | |
150 | t1->cast = cast; | |
151 | t1->next = 0; | |
152 | t->next = t1; | |
153 | SwigPtrSort = 0; | |
154 | } | |
155 | ||
156 | /* Make a pointer value string */ | |
157 | ||
158 | SWIGSTATIC | |
159 | void SWIG_MakePtr(char *_c, const void *_ptr, char *type) { | |
160 | static char _hex[16] = | |
161 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', | |
162 | 'a', 'b', 'c', 'd', 'e', 'f'}; | |
163 | unsigned long _p, _s; | |
164 | char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ | |
165 | _r = _result; | |
166 | _p = (unsigned long) _ptr; | |
167 | if (_p > 0) { | |
168 | while (_p > 0) { | |
169 | _s = _p & 0xf; | |
170 | *(_r++) = _hex[_s]; | |
171 | _p = _p >> 4; | |
172 | } | |
173 | *_r = '_'; | |
174 | while (_r >= _result) | |
175 | *(_c++) = *(_r--); | |
176 | } else { | |
177 | strcpy (_c, "NULL"); | |
178 | } | |
179 | if (_ptr) | |
180 | strcpy (_c, type); | |
181 | } | |
182 | ||
183 | /* Define for backwards compatibility */ | |
184 | ||
185 | #define _swig_make_hex SWIG_MakePtr | |
186 | ||
187 | /* Function for getting a pointer value */ | |
188 | ||
189 | SWIGSTATIC | |
190 | char *SWIG_GetPtr(char *_c, void **ptr, char *_t) | |
191 | { | |
192 | unsigned long _p; | |
193 | char temp_type[256]; | |
194 | char *name; | |
195 | int i, len; | |
196 | SwigPtrType *sp,*tp; | |
197 | SwigCacheType *cache; | |
198 | int start, end; | |
199 | _p = 0; | |
200 | ||
201 | /* Pointer values must start with leading underscore */ | |
202 | if (*_c == '_') { | |
203 | _c++; | |
204 | /* Extract hex value from pointer */ | |
205 | while (*_c) { | |
206 | if ((*_c >= '0') && (*_c <= '9')) | |
207 | _p = (_p << 4) + (*_c - '0'); | |
208 | else if ((*_c >= 'a') && (*_c <= 'f')) | |
209 | _p = (_p << 4) + ((*_c - 'a') + 10); | |
210 | else | |
211 | break; | |
212 | _c++; | |
213 | } | |
214 | ||
215 | if (_t) { | |
216 | if (strcmp(_t,_c)) { | |
217 | if (!SwigPtrSort) { | |
218 | qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); | |
219 | for (i = 0; i < 256; i++) { | |
220 | SwigStart[i] = SwigPtrN; | |
221 | } | |
222 | for (i = SwigPtrN-1; i >= 0; i--) { | |
223 | SwigStart[(int) (SwigPtrTable[i].name[1])] = i; | |
224 | } | |
225 | for (i = 255; i >= 1; i--) { | |
226 | if (SwigStart[i-1] > SwigStart[i]) | |
227 | SwigStart[i-1] = SwigStart[i]; | |
228 | } | |
229 | SwigPtrSort = 1; | |
230 | for (i = 0; i < SWIG_CACHESIZE; i++) | |
231 | SwigCache[i].stat = 0; | |
232 | } | |
233 | ||
234 | /* First check cache for matches. Uses last cache value as starting point */ | |
235 | cache = &SwigCache[SwigLastCache]; | |
236 | for (i = 0; i < SWIG_CACHESIZE; i++) { | |
237 | if (cache->stat) { | |
238 | if (strcmp(_t,cache->name) == 0) { | |
239 | if (strcmp(_c,cache->mapped) == 0) { | |
240 | cache->stat++; | |
241 | *ptr = (void *) _p; | |
242 | if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); | |
243 | return (char *) 0; | |
244 | } | |
245 | } | |
246 | } | |
247 | SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; | |
248 | if (!SwigLastCache) cache = SwigCache; | |
249 | else cache++; | |
250 | } | |
251 | /* We have a type mismatch. Will have to look through our type | |
252 | mapping table to figure out whether or not we can accept this datatype */ | |
253 | ||
254 | start = SwigStart[(int) _t[1]]; | |
255 | end = SwigStart[(int) _t[1]+1]; | |
256 | sp = &SwigPtrTable[start]; | |
257 | while (start < end) { | |
258 | if (swigcmp(_t,sp) == 0) break; | |
259 | sp++; | |
260 | start++; | |
261 | } | |
262 | if (start > end) sp = 0; | |
263 | /* Try to find a match for this */ | |
264 | while (start <= end) { | |
265 | if (swigcmp(_t,sp) == 0) { | |
266 | name = sp->name; | |
267 | len = sp->len; | |
268 | tp = sp->next; | |
269 | /* Try to find entry for our given datatype */ | |
270 | while(tp) { | |
271 | if (tp->len >= 255) { | |
272 | return _c; | |
273 | } | |
274 | strcpy(temp_type,tp->name); | |
275 | strncat(temp_type,_t+len,255-tp->len); | |
276 | if (strcmp(_c,temp_type) == 0) { | |
277 | ||
278 | strcpy(SwigCache[SwigCacheIndex].mapped,_c); | |
279 | strcpy(SwigCache[SwigCacheIndex].name,_t); | |
280 | SwigCache[SwigCacheIndex].stat = 1; | |
281 | SwigCache[SwigCacheIndex].tp = tp; | |
282 | SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; | |
283 | ||
284 | /* Get pointer value */ | |
285 | *ptr = (void *) _p; | |
286 | if (tp->cast) *ptr = (*(tp->cast))(*ptr); | |
287 | return (char *) 0; | |
288 | } | |
289 | tp = tp->next; | |
290 | } | |
291 | } | |
292 | sp++; | |
293 | start++; | |
294 | } | |
295 | /* Didn't find any sort of match for this data. | |
296 | Get the pointer value and return the received type */ | |
297 | *ptr = (void *) _p; | |
298 | return _c; | |
299 | } else { | |
300 | /* Found a match on the first try. Return pointer value */ | |
301 | *ptr = (void *) _p; | |
302 | return (char *) 0; | |
303 | } | |
304 | } else { | |
305 | /* No type specified. Good luck */ | |
306 | *ptr = (void *) _p; | |
307 | return (char *) 0; | |
308 | } | |
309 | } else { | |
310 | if (strcmp (_c, "NULL") == 0) { | |
311 | *ptr = (void *) 0; | |
312 | return (char *) 0; | |
313 | } | |
314 | *ptr = (void *) 0; | |
315 | return _c; | |
316 | } | |
317 | } | |
318 | ||
319 | /* Compatibility mode */ | |
320 | ||
321 | #define _swig_get_hex SWIG_GetPtr | |
322 | ||
323 | #ifdef __cplusplus | |
324 | } | |
325 | #endif | |
326 |