source: trunk/gsdl/src/recpt/infodbclass.cpp@ 373

Last change on this file since 373 was 368, checked in by rjmcnab, 25 years ago

Moved from src/colservr and added capability to write out data.

  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/**********************************************************************
2 *
3 * infodbclass.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * PUT COPYRIGHT NOTICE HERE
7 *
8 * $Id: infodbclass.cpp 368 1999-07-11 08:27:52Z rjmcnab $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.1 1999/07/11 08:27:52 rjmcnab
15 Moved from src/colservr and added capability to write out data.
16
17 Revision 1.4 1999/05/10 03:43:48 sjboddie
18 lots of changes to lots of files - getting document action going
19
20 Revision 1.3 1999/04/30 02:00:46 sjboddie
21 lots of stuff to do with getting documentaction working
22
23 Revision 1.2 1999/04/06 22:20:31 rjmcnab
24 Got browsefilter working.
25
26 Revision 1.1 1999/03/30 05:10:07 rjmcnab
27 Initial revision.
28
29 */
30
31
32#include "infodbclass.h"
33#include "unitool.h"
34#include "gsdlunicode.h"
35#include "fileutil.h"
36#include "OIDtools.h"
37
38// constructors
39infodbclass::infodbclass () {
40}
41
42void infodbclass::setinfo (const text_t &key, const text_t &value) {
43 info[key] = value;
44}
45
46void infodbclass::setintinfo (const text_t &key, int value) {
47 setinfo (key, value);
48}
49
50void infodbclass::setcinfo (const text_t &key, unsigned short c) {
51 text_t t;
52 t.push_back(c);
53 setinfo(key,t);
54}
55
56text_t *infodbclass::getinfo (const text_t &key) {
57 iterator here = info.find (key);
58 if (here == info.end()) return NULL;
59
60 return &((*here).second);
61}
62
63int infodbclass::getintinfo (const text_t &key) {
64 text_t *t = getinfo (key);
65 if (t == NULL) return 0;
66 return t->getint();
67}
68
69
70
71
72// returns true if opened
73bool gdbmclass::opendatabase (const text_t &filename, int mode, int num_retrys) {
74 text_t data_location;
75 int block_size = 512;
76
77 if (gdbmfile != NULL) {
78 if (openfile == filename) return true;
79 else closedatabase ();
80 }
81
82 openfile = filename;
83
84 char *namebuffer = filename.getcstr();
85 do {
86 gdbmfile = gdbm_open (namebuffer, block_size, mode, 00664, NULL);
87 num_retrys--;
88 } while (num_retrys>0 && gdbmfile==NULL &&
89 (gdbm_errno==GDBM_CANT_BE_READER || gdbm_errno==GDBM_CANT_BE_WRITER));
90 delete namebuffer;
91
92 if (gdbmfile == NULL && logout != NULL) {
93 outconvertclass text_t2ascii;
94 (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
95 }
96
97 return (gdbmfile != NULL);
98}
99
100void gdbmclass::closedatabase () {
101 if (gdbmfile == NULL) return;
102
103 gdbm_close (gdbmfile);
104 gdbmfile = NULL;
105 openfile.clear();
106}
107
108
109// returns true on success
110bool gdbmclass::setinfo (const text_t &key, const infodbclass &info) {
111 if (gdbmfile == NULL) return false;
112
113 text_t data;
114
115 // get all the keys and values
116 infodbclass::const_iterator info_here = info.begin();
117 infodbclass::const_iterator info_end = info.end();
118 while (info_here != info_end) {
119 // add the key
120 data.push_back('<');
121 text_t::const_iterator subkey_here = (*info_here).first.begin();
122 text_t::const_iterator subkey_end = (*info_here).first.end();
123 while (subkey_here != subkey_end) {
124 if (*subkey_here == '>') {
125 data.push_back('\\'); data.push_back('>');
126 } else if (*subkey_here == '\n') {
127 data.push_back('\\'); data.push_back('n');
128 } else if (*subkey_here == '\r') {
129 data.push_back('\\'); data.push_back('r');
130 } else {
131 data.push_back (*subkey_here);
132 }
133 subkey_here++;
134 }
135 data.push_back('>');
136
137 // add the value
138 text_t::const_iterator subvalue_here = (*info_here).second.begin();
139 text_t::const_iterator subvalue_end = (*info_here).second.end();
140 while (subvalue_here != subvalue_end) {
141 if (*subvalue_here == '>') {
142 data.push_back('\\'); data.push_back('>');
143 } else if (*subvalue_here == '\n') {
144 data.push_back('\\'); data.push_back('n');
145 } else if (*subvalue_here == '\r') {
146 data.push_back('\\'); data.push_back('r');
147 } else {
148 data.push_back (*subvalue_here);
149 }
150 subvalue_here++;
151 }
152 data.push_back('\n');
153
154 info_here++;
155 }
156
157 // store the value
158 datum key_data;
159 datum data_data;
160
161 // get a utf-8 encoded c string of the unicode key
162 key_data.dptr = (to_utf8(key)).getcstr();
163 if (key_data.dptr == NULL) {
164 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
165 return false;
166 }
167 key_data.dsize = strlen (key_data.dptr);
168
169 data_data.dptr = (to_utf8(data)).getcstr();
170 if (data_data.dptr == NULL) {
171 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
172 delete key_data.dptr;
173 }
174 data_data.dsize = strlen (data_data.dptr);
175
176 int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
177 delete key_data.dptr;
178 delete data_data.dptr;
179
180 return (ret == 0);
181}
182
183
184
185// replaces the .fc, .lc, .pr, .ns and .ps syntax (first child,
186// last child, parent, next sibling, previous sibling)
187// it expects child, parent, etc. to exist if syntax has been used
188// so you should test before using
189text_t gdbmclass::translate_OID (const text_t &inOID, infodbclass &info) {
190
191 if (inOID.size() < 4) return inOID;
192 if (findchar (inOID.begin(), inOID.end(), '.') == inOID.end()) return inOID;
193
194 text_t OID = inOID;
195 text_tarray tailarray;
196 text_t tail = substr (OID.end()-3, OID.end());
197 while (tail == ".fc" || tail == ".lc" || tail == ".pr" ||
198 tail == ".ns" || tail == ".ps") {
199 tailarray.push_back(tail);
200 OID.erase (OID.end()-3, OID.end());
201 tail = substr (OID.end()-3, OID.end());
202 }
203
204 if (!tailarray.size()) return inOID;
205 text_tarray::const_iterator begin = tailarray.begin();
206 text_tarray::const_iterator here = tailarray.end() - 1;
207
208 while (here >= begin) {
209
210 if (*here == ".fc")
211 get_first_child (OID, info);
212 else if (*here == ".lc")
213 get_last_child (OID, info);
214 else if (*here == ".pr")
215 OID = get_parent (OID);
216 else if (*here == ".ns")
217 get_next_sibling (OID, info);
218 else if (*here == ".ps")
219 get_previous_sibling (OID, info);
220
221 here --;
222 }
223 return OID;
224}
225
226void gdbmclass::get_first_child (text_t &OID, infodbclass &info) {
227
228 text_t firstchild;
229 if (getinfo (OID, info)) {
230 text_t &contains = info["contains"];
231 if (!contains.empty()) {
232 text_t parent = OID;
233 getdelimitstr (contains.begin(), contains.end(), ';', firstchild);
234 if (firstchild.empty()) OID = contains;
235 else OID = firstchild;
236 if (*(OID.begin()) == '"') translate_parent (OID, parent);
237 }
238 }
239}
240
241void gdbmclass::get_last_child (text_t &OID, infodbclass &info) {
242
243 text_tarray children;
244 if (getinfo (OID, info)) {
245 text_t &contains = info["contains"];
246 if (!contains.empty()) {
247 text_t parent = OID;
248 splitchar (contains.begin(), contains.end(), ';', children);
249 OID = children.back();
250 if (*(OID.begin()) == '"') translate_parent (OID, parent);
251 }
252 }
253}
254
255void gdbmclass::get_next_sibling (text_t &OID, infodbclass &info) {
256
257 text_tarray siblings;
258 text_t parent = get_parent (OID);
259
260 if (getinfo (parent, info)) {
261 text_t &contains = info["contains"];
262 if (!contains.empty()) {
263 splitchar (contains.begin(), contains.end(), ';', siblings);
264 text_tarray::const_iterator here = siblings.begin();
265 text_tarray::const_iterator end = siblings.end();
266 text_t shrunk_OID = OID;
267 shrink_parent (shrunk_OID);
268 while (here != end) {
269 if (*here == shrunk_OID && (here+1 != end)) {
270 OID = *(here+1);
271 if (*(OID.begin()) == '"') translate_parent (OID, parent);
272 break;
273 }
274 here ++;
275 }
276 }
277 }
278}
279
280void gdbmclass::get_previous_sibling (text_t &OID, infodbclass &info) {
281
282 text_tarray siblings;
283 text_t parent = get_parent (OID);
284
285 if (getinfo (parent, info)) {
286 text_t &contains = info["contains"];
287 if (!contains.empty()) {
288 splitchar (contains.begin(), contains.end(), ';', siblings);
289 text_tarray::const_iterator here = siblings.begin();
290 text_tarray::const_iterator end = siblings.end();
291 text_t shrunk_OID = OID;
292 shrink_parent (shrunk_OID);
293 while (here != end) {
294 if (*here == shrunk_OID && (here != siblings.begin())) {
295 OID = *(here-1);
296 if (*(OID.begin()) == '"') translate_parent (OID, parent);
297 break;
298 }
299 here ++;
300 }
301 }
302 }
303}
304
305// returns true on success
306bool gdbmclass::getinfo (text_t key, infodbclass &info) {
307 text_t data;
308
309 if (!getkeydata (key, data)) return false;
310 text_t::iterator here = data.begin ();
311 text_t::iterator end = data.end ();
312
313 text_t ikey, ivalue;
314 info.clear (); // reset info
315
316 while (getinfoline(here, end, ikey, ivalue)) {
317 info[ikey] = ivalue;
318 }
319
320 return true;
321}
322
323// returns true if exists
324bool gdbmclass::exists (text_t key) {
325 text_t data;
326 return getkeydata (key, data);
327}
328
329// returns true on success
330bool gdbmclass::getkeydata (text_t key, text_t &data) {
331 datum key_data;
332 datum return_data;
333
334 if (gdbmfile == NULL) return false;
335
336 // get a utf-8 encoded c string of the unicode key
337 key_data.dptr = (to_utf8(key)).getcstr();
338 if (key_data.dptr == NULL) {
339 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
340 return false;
341 }
342 key_data.dsize = strlen (key_data.dptr);
343
344 // fetch the result
345 return_data = gdbm_fetch (gdbmfile, key_data);
346 delete key_data.dptr;
347
348 if (return_data.dptr == NULL) return false;
349
350 data.setcarr (return_data.dptr, return_data.dsize);
351 free (return_data.dptr);
352 data = to_uni(data); // convert to unicode
353
354 return true;
355}
356
357// returns true on success
358bool gdbmclass::getinfoline (text_t::iterator &here, text_t::iterator end,
359 text_t &key, text_t &value) {
360 key.clear();
361 value.clear();
362
363 // ignore white space
364 while (here != end && is_unicode_space (*here)) here++;
365
366 // get the '<'
367 if (here == end || *here != '<') return false;
368 here++;
369
370 // get the key
371 while (here != end && *here != '>') {
372 key.push_back(*here);
373 here++;
374 }
375
376 // get the '>'
377 if (here == end || *here != '>') return false;
378 here++;
379
380 // get the value
381 while (here != end && *here != '\n') {
382 if (*here == '\\') {
383 // found escape character
384 here++;
385 if (here != end) {
386 if (*here == 'n') value.push_back ('\n');
387 else if (*here == 'r') value.push_back ('\r');
388 else value.push_back(*here);
389 }
390
391 } else {
392 // a normal character
393 value.push_back(*here);
394 }
395
396 here++;
397 }
398
399 return true;
400}
401
Note: See TracBrowser for help on using the repository browser.