Trust uboot's device list only if it does not look suspicious.
[AROS.git] / test / OOPDemos / sysdep / hashed_methods.c
blob1f96d05907d2629ffcde52ae7910d33f9003400b
1 /*
2 Copyright © 1997-98, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Demo of new OOP system
6 Lang: english
7 */
9 #include <stdlib.h>
11 #define SDEBUG 1
12 #define DEBUG 1
13 #include "debug.h"
15 #include "oop.h"
16 #include "hash.h"
17 #include "sysdep/hashed_methods.h"
19 static struct Bucket *CopyBucket(struct Bucket *old_b);
20 static VOID FreeBucket(struct Bucket *b);
22 /**********************
23 ** NumNewMethods() **
24 **********************/
26 static ULONG NumNewMethods(Class *cl, struct InterfaceDescr *ifDescr)
28 struct Bucket **ht;
29 ULONG numnewmethods = 0;
31 if (cl->SuperClass)
33 ht = (struct Bucket **)cl->SuperClass->HashTable;
34 for (; ifDescr->MethodTable; ifDescr ++)
36 ULONG i;
38 for (i = 0; i < ifDescr->NumMethods; i ++)
40 ULONG mid;
41 mid = (ifDescr->InterfaceID << NUM_METHOD_BITS) + i;
43 if (!HashLookupULONG(ht, mid))
45 numnewmethods ++;
53 else
55 /* This is rootclass, count the methods */
56 ht = (struct Bucket **)cl->HashTable;
57 for (; ifDescr->MethodTable; ifDescr ++)
59 numnewmethods += ifDescr->NumMethods;
62 return (numnewmethods);
65 /***************************
66 ** AllocDispatchTales() **
67 ***************************/
69 BOOL AllocDispatchTables(Class *cl, struct InterfaceDescr *ifDescr)
71 ULONG entries;
73 entries = NumNewMethods(cl, ifDescr);
75 cl->HashTable = (struct MethodBucket **)NewHash(entries);
76 if (cl->HashTable)
78 /* Save hashtable mask for speed */
79 cl->HashMask = HashMask(cl->HashTable);
81 if (cl->SuperClass)
83 /* Copy the superclass hash table */
84 if ( !CopyHash((struct Bucket **)cl->HashTable
85 ,(struct Bucket **)cl->SuperClass->HashTable
86 ,CopyBucket
87 ,NULL))
89 goto failure;
93 /* Insert our own methods */
94 for (; ifDescr->MethodTable; ifDescr ++)
96 IPTR (**mtab)() = ifDescr->MethodTable;
97 ULONG i;
99 for (i = 0; i < ifDescr->NumMethods; i ++)
101 struct MethodBucket *b;
102 ULONG mid;
104 mid = (ifDescr->InterfaceID << NUM_METHOD_BITS) + i;
107 /* Method existed in superclass ? */
108 b = (struct MethodBucket *)HashLookupULONG((struct Bucket **)cl->HashTable, mid);
109 if (b)
111 b->MethodFunc = mtab[i];
112 b->mClass = cl;
114 else
116 /* Must allocate new bucket */
117 struct MethodBucket *new_b;
118 new_b = (struct MethodBucket *)malloc( sizeof (struct MethodBucket) );
119 if (!new_b)
121 goto failure;
123 /* Initialize bucket */
124 new_b->MethodID = mid;
125 new_b->MethodFunc = mtab[i];
126 new_b->mClass = cl;
128 /* Add bucket to hashtable */
129 InsertBucket((struct Bucket **)cl->HashTable, (struct Bucket *)new_b);
132 } /* for (each method in methodtable) */
134 } /* for (each interface) */
137 ReturnBool ("AllocDispatchTables", TRUE);
138 failure:
139 FreeHash((struct Bucket **)cl->HashTable, FreeBucket);
140 ReturnBool ("AllocDispatchTables", FALSE);
144 VOID FreeDispatchTables(Class *cl)
146 FreeHash((struct Bucket **)cl->HashTable, FreeBucket);
148 return;
152 /**************************
153 ** Hash handling hooks **
154 **************************/
155 #define MB(x) ((struct MethodBucket *)x)
156 static struct Bucket *CopyBucket(struct Bucket *old_b)
158 struct MethodBucket *new_b;
160 new_b = (struct MethodBucket *)malloc(sizeof (struct MethodBucket) );
161 if (new_b)
163 new_b->MethodID = MB(old_b)->MethodID;
164 new_b->MethodFunc = MB(old_b)->MethodFunc;
165 new_b->mClass = MB(old_b)->mClass;
166 return ((struct Bucket *)new_b);
168 return (NULL);
171 static VOID FreeBucket(struct Bucket *b)
173 free(b);