1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #include "dthdr.h"
23 static char* Version = "\n@(#)$Id: cdt (AT&T Labs - Research) 2011-11-11 $\0\n";
24
25 /* Make a new dictionary
26 **
27 ** Written by Kiem-Phong Vo (5/25/96)
28 */
29
30 /* map operation bits from the 2005 version to the current version */
_dttype2005(Dt_t * dt,int type)31 static int _dttype2005(Dt_t* dt, int type)
32 {
33 if (type == DT_DELETE && (dt->meth->type&(DT_OBAG|DT_BAG)))
34 type = DT_REMOVE;
35 return type;
36 }
37
38 #if __STD_C
_dtopen(Dtdisc_t * disc,Dtmethod_t * meth,unsigned long version)39 Dt_t* _dtopen(Dtdisc_t* disc, Dtmethod_t* meth, unsigned long version)
40 #else
41 Dt_t* _dtopen(disc, meth, version)
42 Dtdisc_t* disc;
43 Dtmethod_t* meth;
44 unsigned long version;
45 #endif
46 {
47 Dtdata_t *data;
48 Dt_t *dt, pdt;
49 int ev, type;
50
51 if(!disc || !meth)
52 return NIL(Dt_t*);
53
54 dt = NIL(Dt_t*);
55 data = NIL(Dtdata_t*);
56 type = meth->type;
57
58 memset(&pdt, 0, sizeof(Dt_t));
59 pdt.searchf = meth->searchf;
60 pdt.meth = meth;
61 dtdisc(&pdt,disc,0); /* note that this sets pdt.memoryf */
62
63 if(disc->eventf)
64 { if((ev = (*disc->eventf)(&pdt,DT_OPEN,(Void_t*)(&data),disc)) < 0)
65 return NIL(Dt_t*); /* something bad happened */
66 else if(ev > 0)
67 { if(data) /* shared data are being restored */
68 { if((data->type & DT_METHODS) != meth->type)
69 { DTERROR(&pdt, "Error in matching methods to restore dictionary");
70 return NIL(Dt_t*);
71 }
72 pdt.data = data;
73 }
74 }
75 else
76 { if(data) /* dt should be allocated with dt->data */
77 type |= DT_INDATA;
78 }
79 }
80
81 if(!pdt.data) /* allocate method-specific data */
82 if((*meth->eventf)(&pdt, DT_OPEN, NIL(Void_t*)) < 0 || !pdt.data )
83 return NIL(Dt_t*);
84 pdt.data->type |= type;
85
86 /* now allocate/initialize the actual dictionary structure */
87 if(pdt.data->type&DT_INDATA)
88 dt = &pdt.data->dict;
89 else if(!(dt = (Dt_t*) malloc(sizeof(Dt_t))) )
90 { (void)(*meth->eventf)(&pdt, DT_CLOSE, NIL(Void_t*));
91 DTERROR(&pdt, "Error in allocating a new dictionary");
92 return NIL(Dt_t*);
93 }
94
95 *dt = pdt;
96
97 dt->user = &dt->data->user; /* space allocated for application usage */
98
99 if(disc->eventf) /* signal opening is done */
100 (void)(*disc->eventf)(dt, DT_ENDOPEN, (Void_t*)0, disc);
101
102 /* set mapping of operation bits between versions as needed */
103 if(version < 20111111L)
104 dt->typef = _dttype2005;
105
106 return dt;
107 }
108
109 #undef dtopen /* deal with binary upward compatibility for op bits */
110 #if __STD_C
dtopen(Dtdisc_t * disc,Dtmethod_t * meth)111 Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth)
112 #else
113 Dt_t* dtopen(disc, meth)
114 Dtdisc_t* disc;
115 Dtmethod_t* meth;
116 #endif
117 {
118 return _dtopen(disc, meth, 20050420L);
119 }
120
121 /* below are private functions used across CDT modules */
_dtmake(Dt_t * dt,Void_t * obj,int type)122 Dtlink_t* _dtmake(Dt_t* dt, Void_t* obj, int type)
123 {
124 Dthold_t *h;
125 Dtdisc_t *disc = dt->disc;
126
127 /* if obj is a prototype, make a real one */
128 if(!(type&DT_ATTACH) && disc->makef && !(obj = (*disc->makef)(dt, obj, disc)) )
129 return NIL(Dtlink_t*);
130
131 if(disc->link >= 0) /* holder is embedded in obj itself */
132 return _DTLNK(disc, obj);
133
134 /* create a holder to hold obj */
135 if((h = (Dthold_t*)(dt->memoryf)(dt, NIL(Void_t*), sizeof(Dthold_t), disc)) )
136 h->obj = obj;
137 else
138 { DTERROR(dt, "Error in allocating an object holder");
139 if(!(type&DT_ATTACH) && disc->makef && disc->freef)
140 (void)(*disc->freef)(dt, obj, disc); /* free just-made obj */
141 }
142
143 return (Dtlink_t*)h;
144 }
145
_dtfree(Dt_t * dt,Dtlink_t * l,int type)146 void _dtfree(Dt_t* dt, Dtlink_t* l, int type)
147 {
148 Dtdisc_t *disc = dt->disc;
149
150 if(!(type&DT_DETACH) && disc->freef) /* free object */
151 (void)(*disc->freef)(dt, _DTOBJ(disc,l), disc);
152
153 if(disc->link < 0) /* free holder */
154 (void)(*dt->memoryf)(dt, (Void_t*)l, 0, disc);
155 }
156
dtuserlock(Dt_t * dt,unsigned int key,int type)157 int dtuserlock(Dt_t* dt, unsigned int key, int type)
158 {
159 if(type > 0)
160 return asolock(&dt->data->user.lock, key, ASO_LOCK);
161 else if(type < 0)
162 return asolock(&dt->data->user.lock, key, ASO_UNLOCK);
163 else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK);
164 }
165
dtuserdata(Dt_t * dt,Void_t * data,unsigned int key)166 Void_t* dtuserdata(Dt_t* dt, Void_t* data, unsigned int key)
167 {
168 if(key == 0)
169 return dt->data->user.data;
170 else if(dtuserlock(dt, key, 1) < 0 )
171 return NIL(Void_t*);
172 else
173 { dt->data->user.data = data;
174 dtuserlock(dt, key, -1);
175 return data;
176 }
177 }
178