Use a UBYTE rather than a BYTE for the buffer passed to FWriteChars(), since
[AROS.git] / test / OOPDemos / sysdep / hashed_ifs.c
blob62f3c2dc87420fa1ed51129ce970485eb588507f
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 "oop.h"
10 #include "sysdep/hashed_ifs.h"
11 #include "hash.h"
12 #include <stdlib.h>
14 #define SDEBUG 0
15 #define DEBUG 0
16 #include "debug.h"
18 #define UB(x) ((UBYTE *)x)
20 #define ClassID ClassNode.ln_Name
21 /* Hooks */
22 VOID FreeBucket(struct Bucket *b);
23 struct Bucket *CopyBucket(struct Bucket *old_b, APTR data);
25 /* Internal */
26 static struct InterfaceBucket *CreateBucket(struct InterfaceDescr *ifDescr);
28 /*******************
29 ** CalcHTSize() **
30 *******************/
32 static ULONG CalcHTEntries(Class *cl, struct InterfaceDescr *ifDescr)
34 ULONG num_if = 0;
35 Class *super = cl->SuperClass;
37 EnterFunc(bug("CalcHTEntries(cl=%s, ifDescr=%p)\n", cl->ClassID, ifDescr));
39 /* Count the number of interfaces of superclass */
41 if (super)
43 num_if = super->NumInterfaces;
45 /* Check if there are any new interfaces in this class */
46 for (; ifDescr->MethodTable; ifDescr ++)
48 if ( NULL == HashLookupULONG((struct Bucket **)super->HashTable, ifDescr->InterfaceID) )
50 num_if ++;
53 } /* for (each interface in the description for the class) */
56 else
58 /* This is rootclass, count the interfaces */
59 for (; ifDescr->MethodTable; ifDescr ++)
61 num_if ++;
63 } /* for (each interface in the description for the class) */
65 ReturnInt ("CalcHTEntries", ULONG, num_if);
70 /****************************
71 ** AllocDispatchTables() **
72 ****************************/
74 BOOL AllocDispatchTables(Class *cl, struct InterfaceDescr *ifDescr)
76 ULONG num_if;
78 EnterFunc(bug("AllocDispatchTables(cl=%s,ifDescr=%p)\n",
79 cl->ClassID, ifDescr));
81 /* Get hash table size */
82 num_if = CalcHTEntries(cl, ifDescr);
83 cl->NumInterfaces = num_if;
85 cl->HashTable = (struct InterfaceBucket **)NewHash(num_if);
86 if (cl->HashTable)
88 cl->HashMask = HashMask(cl->HashTable);
90 /* Copy parent interfaces into the new class */
91 if (cl->SuperClass) /* This test makes it work for initializong rootclass */
93 if (!CopyHash((struct Bucket **)cl->HashTable
94 ,(struct Bucket **)cl->SuperClass->HashTable
95 ,CopyBucket
96 ,(APTR)cl) )
98 goto failure;
102 /* Insert our own interfaces */
103 for (; ifDescr->MethodTable; ifDescr ++)
105 struct InterfaceBucket *ifb;
106 ULONG i;
109 ifb = (struct InterfaceBucket *)HashLookupULONG((struct Bucket **)cl->HashTable, ifDescr->InterfaceID);
110 if (!ifb)
111 /* Bucket doesn't exist, allocate it */
112 ifb = CreateBucket(ifDescr);
114 if (!ifb)
115 goto failure;
117 InsertBucket((struct Bucket **)cl->HashTable, (struct Bucket *)ifb);
119 for (i = 0; i < ifb->NumMethods; i ++)
121 if (ifDescr->MethodTable[i])
123 ifb->MethodTable[i].MethodFunc = ifDescr->MethodTable[i];
124 ifb->MethodTable[i].mClass = cl;
126 } /* for (each method in the interface) */
128 } /* for (each interface to add to class) */
130 ReturnBool ("AllocDispatchTables", TRUE);
132 failure:
133 FreeHash((struct Bucket **)cl->HashTable, FreeBucket);
134 ReturnBool ("AllocDispatchTables", FALSE);
137 /***************************
138 ** FreeDispatchTables() **
139 ***************************/
140 VOID FreeDispatchTables(Class *cl)
142 FreeHash((struct Bucket **)cl->HashTable, FreeBucket);
144 return;
148 /*********************
149 ** CreateBucket() **
150 *********************/
151 static struct InterfaceBucket *CreateBucket(struct InterfaceDescr *ifDescr)
153 struct IFMethod *ifm = NULL;
154 ULONG numentries = ifDescr->NumMethods;
155 ULONG mtab_size = UB (&ifm[numentries]) - UB( &ifm[0]);
157 /* Allocate bucket */
158 struct InterfaceBucket *ifb;
160 ifb = (struct InterfaceBucket *)malloc( sizeof (struct InterfaceBucket) );
161 if (ifb)
163 ifb->MethodTable = (struct IFMethod *)malloc(mtab_size);
164 if (ifb->MethodTable)
166 ifb->InterfaceID = ifDescr->InterfaceID;
167 ifb->NumMethods = ifDescr->NumMethods;
169 return (ifb);
171 free (ifb);
173 return (NULL);
177 /***********************
178 ** Hash table hooks **
179 ***********************/
180 #define IB(x) ((struct InterfaceBucket *)x)
182 VOID FreeBucket(struct Bucket *b)
184 // D(bug("FreeBucket(b=%p)\n", b));
185 free(IB(b)->MethodTable);
186 // D(bug("Freeing bucket\n"));
187 free(b);
189 // ReturnVoid("FreeBucket");
190 return;
193 struct Bucket *CopyBucket(struct Bucket *old_b, APTR data)
195 struct InterfaceBucket *new_b;
197 EnterFunc(bug("CopyBucket(old_b=%p)\n", old_b));
199 new_b = (struct InterfaceBucket *)malloc(sizeof (struct InterfaceBucket) );
200 if (new_b)
202 struct IFMethod *ifm = NULL;
203 ULONG mtab_size;
204 ULONG numentries = IB(old_b)->NumMethods;
206 mtab_size = UB(&ifm[numentries]) - UB(&ifm[0]);
208 new_b->MethodTable = (struct IFMethod *)malloc(mtab_size);
209 if (new_b->MethodTable)
211 /* Copy methodtable */
212 memcpy(new_b->MethodTable, IB(old_b)->MethodTable, mtab_size);
214 /* Initialize bucket */
215 new_b->InterfaceID = IB(old_b)->InterfaceID;
216 new_b->NumMethods = IB(old_b)->NumMethods;
218 ReturnPtr ("CopyBucket", struct Bucket *, (struct Bucket *)new_b );
220 free (new_b);
223 ReturnPtr ("CopyBucket", struct Bucket *, NULL);