source: trunk/gsdl/src/colservr/infodbclass.cpp@ 308

Last change on this file since 308 was 259, checked in by sjboddie, 25 years ago

lots of changes to lots of files - getting document action going

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