1 |
/* |
2 |
The Malete project - the Z39.2/Z39.50 database framework of OpenIsis. |
3 |
Version 0.9.x (patchlevel see file Version) |
4 |
Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org |
5 |
|
6 |
This library is free software; you can redistribute it and/or |
7 |
modify it under the terms of the GNU Lesser General Public |
8 |
License as published by the Free Software Foundation; either |
9 |
version 2.1 of the License, or (at your option) any later version. |
10 |
|
11 |
This library is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
14 |
See the GNU Lesser General Public License for more details. |
15 |
|
16 |
You should have received a copy of the GNU Lesser General Public |
17 |
License along with this library; if not, write to the Free Software |
18 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
|
20 |
see README for more information |
21 |
EOH */ |
22 |
#ifndef PW_H |
23 |
|
24 |
/* |
25 |
$Id: pw.h,v 1.7 2004/03/16 22:17:52 kripke Exp $ |
26 |
interface of the Malete patchwork |
27 |
*/ |
28 |
|
29 |
#define PW_VERSION "0.9.9" |
30 |
|
31 |
|
32 |
#include "../core/core.h" |
33 |
|
34 |
|
35 |
typedef struct Obj Obj; |
36 |
|
37 |
|
38 |
/* ****************************************************************** */ |
39 |
/* */ |
40 |
/* HASH TABLE */ |
41 |
/* */ |
42 |
/* ****************************************************************** */ |
43 |
|
44 |
#define HEDEFKEYLEN 1 |
45 |
|
46 |
typedef struct HEntry HEntry; |
47 |
/* hmmm ... maybe this should become part of Obj */ |
48 |
struct HEntry { |
49 |
HEntry *nxt; |
50 |
Obj *obj; |
51 |
int hv; /* hash value of this entry */ |
52 |
#ifndef NDEBUG |
53 |
int dpt; |
54 |
#endif |
55 |
int len; |
56 |
char key[HEDEFKEYLEN]; /* not 0 terminated */ |
57 |
}; |
58 |
|
59 |
/* hmmm ... maybe this should become part of Struct */ |
60 |
typedef struct HTable { |
61 |
List *list; |
62 |
int mask; |
63 |
int nume; /* # of entries */ |
64 |
int dsize; /* # bytes of unlinked entries */ |
65 |
#ifndef NDEBUG |
66 |
int coll; /* # of collisions */ |
67 |
#endif |
68 |
} HTable; |
69 |
|
70 |
#define HSIZ(t) (-((t)->list->fld->tag)-1) /* number of buckets */ |
71 |
#define HSHIFT 1 /* rebuild factor: HSIZ(t) << HSHIFT */ |
72 |
#define HESIZ(he) (sizeof(HEntry)+(he)->len-HEDEFKEYLEN) /* entry size */ |
73 |
#define HINITIAL 32 /* initial # of buckets */ |
74 |
#define HMAXLOAD 75 /* max load factor */ |
75 |
#define HCURLOAD(t) ( (100*(t)->nume) / HSIZ(t) ) /* current load */ |
76 |
#define HSHRINKLOAD 25 /* shrink, if HCURLOAD(t) < HSHRINKLOAD */ |
77 |
#define HMAXFRAG 50 /* max fragmentation factor */ |
78 |
#define HCURFRAG(t) ( (100*((t)->dsize)) / LSIZ((t)->list) ) /* current frag */ |
79 |
|
80 |
|
81 |
extern HEntry* OPT_STDCALL hGet ( HTable *table, const char *key, int len ); |
82 |
extern HEntry* OPT_STDCALL hAdd ( HTable *table, const char *key, int len ); |
83 |
extern HEntry* OPT_STDCALL hSet ( HTable *t, const char *key, int len, Obj *o ); |
84 |
extern int OPT_STDCALL hDel ( HTable *table, const char *key, int len ); |
85 |
extern HTable* OPT_STDCALL hInit ( HTable *table, const char* header ); |
86 |
extern void OPT_STDCALL hFini ( HTable *table ); |
87 |
|
88 |
/* free al resources held by table */ |
89 |
#define HFREE( table ) do { \ |
90 |
hFini( (table) ); \ |
91 |
mFree( table ); \ |
92 |
} while (0) |
93 |
|
94 |
#ifndef NDEBUG |
95 |
/* debug statistics */ |
96 |
extern void OPT_STDCALL hstat ( HTable *table ); |
97 |
# define HSTAT(t) hstat(t); |
98 |
#else |
99 |
# define HSTAT(t) |
100 |
#endif |
101 |
|
102 |
|
103 |
|
104 |
/* ****************************************************************** */ |
105 |
/* */ |
106 |
/* OBJECTS AND MESSAGES */ |
107 |
/* */ |
108 |
/* ****************************************************************** */ |
109 |
|
110 |
typedef Fld * Msg; |
111 |
typedef struct Qry Qry; /* query implemented by dbo */ |
112 |
|
113 |
|
114 |
/* |
115 |
dispatch message "msg", starting at object obj. |
116 |
|
117 |
----------------------------------- |
118 |
Syntax and semantics of messages |
119 |
|
120 |
A message is basically an array of fields - usually of length 1. The leader |
121 |
of this array containes the messagename, denoting a method, and possibly |
122 |
options. The mesagename has to be given in the leader's primary value, the |
123 |
options in following subfields. Data to be processed is contained in the |
124 |
following fields - if any. The messagename may contain subobject specifiers, |
125 |
which have to be separated by a '.'. Besides this the evaluation of the |
126 |
given leader is solely in the responsibility of the method invoked. The |
127 |
message evaluation may change the given message. The significant length of a |
128 |
messagename may be limited to four bytes. A leader should not be longer |
129 |
than DEFBLKLEN bytes, though some messages may allow longer sizes. Some |
130 |
messagenames may use special characters denoting a special treatment of the |
131 |
given leader - thus such characters should not be used for ordinary |
132 |
messagenames. The result of the evaluation, if any, is always written to |
133 |
env.out. |
134 |
*/ |
135 |
typedef int OPT_STDCALL disp ( Obj *self, Msg msg ); |
136 |
|
137 |
/* |
138 |
the general form of an object |
139 |
send it a message using that->snd(msg) |
140 |
In general, snd must return <0 on error, >=0 else |
141 |
*/ |
142 |
struct Obj { |
143 |
disp *snd; /* method implementation */ |
144 |
}; |
145 |
/** |
146 |
base implementation for Obj handling pipes and such |
147 |
*/ |
148 |
extern int OPT_STDCALL oObj ( Obj *self, Msg msg ); |
149 |
|
150 |
|
151 |
typedef struct Struct Struct; |
152 |
|
153 |
typedef Obj* OPT_STDCALL factory ( Struct *self, const char *key, int len ); |
154 |
/* |
155 |
an object with variable number of childs |
156 |
*/ |
157 |
struct Struct { |
158 |
disp *snd; /* method implementation */ |
159 |
HTable *reg; /* child registry */ |
160 |
factory *fac; /* child factory */ |
161 |
}; |
162 |
/** |
163 |
base implementation for Struct handling child dispatching |
164 |
*/ |
165 |
extern int OPT_STDCALL oStruct ( Struct *self, Msg msg ); |
166 |
|
167 |
|
168 |
/** |
169 |
session -- the root object |
170 |
*/ |
171 |
typedef struct Ses { |
172 |
disp *snd; |
173 |
HTable *reg; /* main registry */ |
174 |
factory *fac; /* main factory */ |
175 |
Sink *out; /* main env.out for this session */ |
176 |
Sink *err; /* env.err for this session */ |
177 |
unsigned rid; /* last rid written */ |
178 |
Qry *qry; /* array of q queries */ |
179 |
lolo req; /* request counter */ |
180 |
/* options */ |
181 |
char *at; /* default target */ |
182 |
unsigned r; /* max # of records per read, 0 = unlimited */ |
183 |
unsigned q; /* max # of open query cursors != 0 */ |
184 |
unsigned s; /* max # of results in search set, 0 = unlimited */ |
185 |
} Ses; |
186 |
extern int OPT_STDCALL oSes ( Ses *self, Msg msg ); |
187 |
|
188 |
/* |
189 |
default main factory (i.e. for the session). |
190 |
scans the environment options for defined objects |
191 |
*/ |
192 |
extern Obj* OPT_STDCALL facMain ( Ses *self, const char *key, int len ); |
193 |
|
194 |
/* init session */ |
195 |
extern void sInit (Ses *s); |
196 |
|
197 |
|
198 |
extern Ses *ses; /* current session */ |
199 |
|
200 |
/* |
201 |
main dispatcher |
202 |
*/ |
203 |
#define dispatch( msg ) ses->snd((Obj*)ses, msg) |
204 |
|
205 |
|
206 |
/* |
207 |
object linked to a session on some remote server |
208 |
*/ |
209 |
typedef struct Srv { |
210 |
disp *snd; /* method implementation */ |
211 |
file *con; /* connection */ |
212 |
} Srv; |
213 |
/** |
214 |
interface a stream |
215 |
*/ |
216 |
extern int OPT_STDCALL oSrv ( Srv *self, Msg msg ); |
217 |
|
218 |
|
219 |
/* |
220 |
database object |
221 |
NOTE that these are childs of session, so all status is per session. |
222 |
*/ |
223 |
typedef struct Dbo { |
224 |
disp *snd; |
225 |
HTable *reg; /* views etc */ |
226 |
factory *fac; /* child factory */ |
227 |
Db *db; /* shared by the Dbos */ |
228 |
Qry *qry; /* chain of queries */ |
229 |
unsigned qid; /* number of last query, 0 = none */ |
230 |
unsigned rid; /* number of last written rec, 0 = none */ |
231 |
/* options */ |
232 |
unsigned p; /* position limit for snapshot read, 0 = none */ |
233 |
} Dbo; |
234 |
/** |
235 |
handle db access |
236 |
*/ |
237 |
extern int OPT_STDCALL oDbo ( Dbo *self, Msg msg ); |
238 |
|
239 |
extern Dbo *newDbo ( char *name ); /* constructor */ |
240 |
extern void delDbo ( Dbo *self ); /* destructor */ |
241 |
|
242 |
|
243 |
/* ****************************************************************** */ |
244 |
/* */ |
245 |
/* HANDLERS FOR VARIOUS STANDARD MESSAGES */ |
246 |
/* */ |
247 |
/* ****************************************************************** */ |
248 |
|
249 |
|
250 |
/* |
251 |
Process a pipe message '|'. |
252 |
The leader is parsed for the subfields '|'. Each of which should contain a |
253 |
valid messagename, options may be given in following subfields terminated by |
254 |
the next '|' subfield or the end of the leader. The output of the first |
255 |
method is used as data input for the next and so on. The first submessage |
256 |
may start directly after the primary field w/o the '|' identifier. |
257 |
*/ |
258 |
extern int OPT_STDCALL mPipe ( Obj *self, Msg msg ); |
259 |
|
260 |
/* |
261 |
Process a compound message ';'. |
262 |
The leader is parsed for the subfields ';'. Each of which should contain a |
263 |
valid messagename, options may be given in following subfields terminated by |
264 |
the next ';' subfield or the end of the leader. Each message is processed |
265 |
separately, given data is used for all messages. The first submessage may |
266 |
start directly after the primary field w/o the ';' identifier. |
267 |
*/ |
268 |
extern int OPT_STDCALL mComp ( Obj *self, Msg msg ); |
269 |
|
270 |
/* |
271 |
Process a comment message '#'. |
272 |
*/ |
273 |
extern int OPT_STDCALL mComm ( Obj *self, Msg msg ); |
274 |
|
275 |
|
276 |
#define PW_H |
277 |
#endif /* PW_H */ |