ARB
adsystem.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : adsystem.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include <sys/types.h>
12 #include <netinet/in.h>
13 
14 #include <arbdbt.h>
15 #include <ad_cb.h>
16 
17 #include "gb_key.h"
18 #include "gb_dict.h"
19 
20 static GB_CSTR gb_read_dict_data(GBDATA *gb_dict, long *size) {
21  GB_CSTR data = NULp;
22  if (gb_dict->flags.compressed_data) {
23  GB_internal_error("Dictionary is compressed");
24  data = GB_read_bytes(gb_dict);
25  }
26  else {
27  data = GB_read_bytes_pntr(gb_dict);
28  }
29  *size = GB_read_bytes_count(gb_dict);
30  return data;
31 }
32 
33 GB_ERROR gb_load_dictionary_data(GBDATA *gb_main, const char *key, char **dict_data, long *size) {
34  /* returns dictionary data (like saved in DB)
35  * in a block allocated by gbm_get_mem(.., GBM_DICT_INDEX)
36  */
37  GB_MAIN_TYPE *Main = GB_MAIN(gb_main);
39 
40  *dict_data = NULp;
41  *size = -1;
42  gb_main = Main->gb_main();
43 
44  if (key[0] == '@') {
45  error = GB_export_error("No dictionaries for system fields");
46  }
47  else {
48  GB_topSecurityLevel unsecured(gb_main);
49 
50  GBDATA *gb_key_data = Main->gb_key_data;
51  GBDATA *gb_name = GB_find_string(gb_key_data, "@name", key, GB_MIND_CASE, SEARCH_GRANDCHILD);
52 
53  if (gb_name) {
54  GBDATA *gb_key = GB_get_father(gb_name);
55  GBDATA *gb_dict = GB_entry(gb_key, "@dictionary");
56  if (gb_dict) {
57  const char *data = gb_read_dict_data(gb_dict, size);
58  char *copy = (char*)gbm_get_mem(*size, GBM_DICT_INDEX);
59  memcpy(copy, data, *size);
60  *dict_data = copy;
61  }
62  }
63  }
64  return error;
65 }
66 
67 static GB_DICTIONARY *gb_create_dict(GBDATA *gb_dict) {
68  GB_DICTIONARY *dict = ARB_calloc<GB_DICTIONARY>(1);
69 
70  long size;
71  const char *data = gb_read_dict_data(gb_dict, &size);
72  GB_write_security_write(gb_dict, 7);
73 
74  GB_NINT *idata = (GB_NINT *)data;
75  dict->words = ntohl(*idata++);
76  dict->textlen = (int)(size - sizeof(GB_NINT)*(1+dict->words*2));
77 
78  dict->offsets = idata;
79  dict->resort = idata+dict->words;
80  dict->text = (unsigned char*)(idata+2*dict->words);
81 
82  return dict;
83 }
84 
85 static void delete_gb_dictionary(GB_DICTIONARY *dict) {
86  free(dict);
87 }
88 
90  if (type == GB_CB_DELETE) {
92 
94  Main->keys[q].dictionary = NULp;
95  Main->keys[q].gb_key = NULp;
96  }
97  else {
99  }
100 }
101 
103  if (type == GB_CB_DELETE) {
105  Main->keys[q].gb_master_ali = NULp;
106  }
107  else {
108  gb_load_single_key_data(gbd, q);
109  }
110 }
111 
113  GB_MAIN_TYPE *Main = GB_MAIN(gb_main);
114  gb_Key *ks = &Main->keys[q];
115  const char *key = ks->key;
116 
117  if (!Main->gb_key_data) {
118  ks->compression_mask = -1;
119  return;
120  }
121 
122  gb_main = Main->gb_main();
123  if (key[0] == '@') {
124  ks->compression_mask = 0;
125  ks->dictionary = NULp;
126  ks->gb_key_disabled = 1;
127  ks->gb_master_ali = NULp;
128  }
129  else {
130  GB_topSecurityLevel unsecured(gb_main);
131 
132  GBCONTAINER *gb_key_data = Main->gb_key_data;
133  GBDATA *gb_name = GB_find_string(gb_key_data, "@name", key, GB_MIND_CASE, SEARCH_GRANDCHILD);
134  GBCONTAINER *gb_key;
135  if (gb_name) {
136  gb_key = GB_FATHER(gb_name);
137  }
138  else {
139  gb_key = gb_create_container(gb_key_data, "@key");
140  gb_name = gb_create(gb_key, "@name", GB_STRING);
141  GB_write_string(gb_name, key);
142  }
143 
144  GB_ensure_callback(gb_key, GB_CB_CHANGED_OR_DELETED, makeDatabaseCallback(gb_system_key_changed_cb, q));
145 
146  if (ks->dictionary) {
148  ks->dictionary = NULp;
149  }
150 
151  ks->compression_mask = *GBT_readOrCreate_int(gb_key, "compression_mask", -1);
152  GBDATA *gb_dict = GB_entry(gb_key, "@dictionary");
153  ks->dictionary = gb_dict ? gb_create_dict(gb_dict) : NULp;
154  ks->gb_key = gb_key;
155 
156  {
157  char buffer[256];
158  sprintf(buffer, "%s/@master_data/@%s", GB_SYSTEM_FOLDER, key);
159 
160  ks->gb_master_ali = GBDATA::as_container(GB_search(gb_main, buffer, GB_FIND));
161  if (ks->gb_master_ali) {
163  }
164  }
165  }
166 }
167 
168 GB_ERROR gb_save_dictionary_data(GBDATA *gb_main, const char *key, const char *dict, int size) {
169  // if 'dict' is NULp, an existing directory gets deleted
170  GB_MAIN_TYPE *Main = GB_MAIN(gb_main);
171  GB_ERROR error = NULp;
172  gb_main = Main->gb_main();
173  if (key[0] == '@') {
174  error = GB_export_error("No dictionaries for system fields");
175  }
176  else {
177  GB_topSecurityLevel unsecured(gb_main);
178 
179  GBCONTAINER *gb_key_data = Main->gb_key_data;
180  GBDATA *gb_name = GB_find_string(gb_key_data, "@name", key, GB_MIND_CASE, SEARCH_GRANDCHILD);
181  GBCONTAINER *gb_key;
182  if (gb_name) {
183  gb_key = GB_FATHER(gb_name);
184  }
185  else {
186  gb_key = gb_create_container(gb_key_data, "@key");
187  gb_name = gb_create(gb_key, "@name", GB_STRING);
188  GB_write_string(gb_name, key);
189  }
190  GBDATA *gb_dict;
191  if (dict) {
192  gb_dict = gb_search(gb_key, "@dictionary", GB_BYTES, 1);
193  error = GB_write_bytes(gb_dict, dict, size);
194  }
195  else {
196  gb_dict = GB_entry(gb_key, "@dictionary");
197  if (gb_dict) {
198  GB_delete(gb_dict); // delete existing dictionary
199  }
200  }
201  }
202  if (!error) {
203  GBQUARK q = gb_find_or_create_quark(Main, key);
204  gb_load_single_key_data(gb_main, q);
205  }
206  return error;
207 }
208 
209 GB_ERROR gb_load_key_data_and_dictionaries(GB_MAIN_TYPE *Main) { // goes to header: __ATTR__USERESULT
211  GB_ERROR error = NULp;
212 
214  if (!gb_key_data) {
215  error = GB_await_error();
216  }
217  else {
218  Main->gb_key_data = gb_key_data;
219  if (Main->is_server()) { // do not create anything at the client side
220  GB_topSecurityLevel unsecured(gb_main);
221 
222  // search unused keys and delete them
223  for (GBDATA *gb_key = GB_entry(gb_key_data, "@key"); gb_key && !error;) {
224  GBDATA *gb_next_key = GB_nextEntry(gb_key);
225  GBDATA *gb_name = GB_entry(gb_key, "@name");
226  if (!gb_name) error = GB_await_error();
227  else {
228  const char *name = GB_read_char_pntr(gb_name);
229  if (!name) error = GB_await_error();
230  else {
231  if (!name[0]) {
232  error = GB_delete(gb_key); // delete invalid empty key
233  }
234  else {
235  GBQUARK quark = gb_find_or_create_quark(Main, name);
236  if (quark<=0 || quark >= Main->sizeofkeys || !quark2key(Main, quark)) {
237  error = GB_delete(gb_key); // delete unused key
238  }
239  }
240  }
241  }
242  gb_key = gb_next_key;
243  }
244 
245  if (!error) error = GB_create_index(gb_key_data, "@name", GB_MIND_CASE, Main->sizeofkeys*2); // create key index
246  if (!error) {
250  ASSERT_RESULT_PREDICATE(isAbove<int>(0), gb_find_or_create_quark(Main, "compression_mask"));
251 
252  for (int key=1; key<Main->sizeofkeys; key++) {
253  if (quark2key(Main, key)) {
254  gb_load_single_key_data(gb_main, key);
255  }
256  }
257  }
258  }
259  }
260  RETURN_ERROR(error);
261 }
262 
263 /* gain access to allow repair of broken compression
264  * (see NT_fix_dict_compress)
265  */
266 
267 struct DictData {
268  char *data;
269  long size;
270 };
271 
272 static void GB_free_dictionary(DictData *dd) {
273  if (dd) {
274  if (dd->data) gbm_free_mem(dd->data, dd->size, GBM_DICT_INDEX);
275  free(dd);
276  }
277 }
278 
280  /* return DictData or
281  * NULp if no dictionary or error occurred
282  */
283  DictData *dd = ARB_calloc<DictData>(1);
284  GB_ERROR error = gb_load_dictionary_data(gb_main, key, &dd->data, &dd->size);
285 
286  if (error || !dd->data) {
287  GB_free_dictionary(dd);
288  dd = NULp;
289  if (error) GB_export_error(error);
290  }
291 
292  return dd;
293 }
294 
295 GB_ERROR GB_set_dictionary(GBDATA *gb_main, const char *key, const DictData *dd) {
296  // if 'dd' == NULp -> delete dictionary
297  GB_ERROR error;
298  if (dd) {
299  error = gb_save_dictionary_data(gb_main, key, dd->data, dd->size);
300  }
301  else {
302  error = gb_save_dictionary_data(gb_main, key, NULp, 0);
303  }
304  return error;
305 }
306 
GB_MAIN_TYPE * gb_get_main_during_cb()
Definition: ad_cb.cxx:108
const char * GB_ERROR
Definition: arb_core.h:25
#define GB_SYSTEM_FOLDER
Definition: arbdb.h:27
static void gb_system_master_changed_cb(GBDATA *gbd, GBQUARK q, GB_CB_TYPE type)
Definition: adsystem.cxx:102
GB_TYPES type
static void GB_free_dictionary(DictData *dd)
Definition: adsystem.cxx:272
static GB_DICTIONARY * gb_create_dict(GBDATA *gb_dict)
Definition: adsystem.cxx:67
GB_ERROR GB_write_bytes(GBDATA *gbd, const char *s, long size)
Definition: arbdb.cxx:1408
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
Definition: arbdb.cxx:1361
const char * quark2key(GB_MAIN_TYPE *Main, GBQUARK key_quark)
Definition: gb_key.h:45
GBDATA * gb_key
Definition: gb_key.h:35
GB_MAIN_TYPE * GB_MAIN(GBDATA *gbd)
Definition: gb_data.h:291
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
unsigned char * text
Definition: gb_dict.h:19
GBCONTAINER * gb_create_container(GBCONTAINER *father, const char *key)
Definition: arbdb.cxx:1747
char * data
Definition: adsystem.cxx:268
GBCONTAINER * gb_master_ali
Definition: gb_key.h:36
long GB_read_bytes_count(GBDATA *gbd)
Definition: arbdb.cxx:939
NOT4PERL long * GBT_readOrCreate_int(GBDATA *gb_container, const char *fieldpath, long default_value)
Definition: adtools.cxx:402
GBQUARK gb_find_or_create_quark(GB_MAIN_TYPE *Main, const char *key)
Definition: arbdb.cxx:1642
GBCONTAINER * root_container
Definition: gb_main.h:120
Definition: gb_key.h:28
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
GBDATA * GB_get_father(GBDATA *gbd)
Definition: arbdb.cxx:1696
GBENTRY * gb_create(GBCONTAINER *father, const char *key, GB_TYPES type)
Definition: arbdb.cxx:1737
GB_ERROR GB_delete(GBDATA *&source)
Definition: arbdb.cxx:1880
char * GB_read_bytes(GBDATA *gbd)
Definition: arbdb.cxx:944
GB_NINT * offsets
Definition: gb_dict.h:20
static void delete_gb_dictionary(GB_DICTIONARY *dict)
Definition: adsystem.cxx:85
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:259
GB_CSTR GB_read_bytes_pntr(GBDATA *gbd)
Definition: arbdb.cxx:934
GB_DICTIONARY * dictionary
Definition: gb_key.h:39
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
gb_flag_types flags
Definition: gb_data.h:134
static void gb_system_key_changed_cb(GBDATA *gbd, GBQUARK q, GB_CB_TYPE type)
Definition: adsystem.cxx:89
#define ASSERT_RESULT_PREDICATE(Pred, Expr)
Definition: arb_assert.h:341
bool is_server() const
Definition: gb_main.h:203
GBCONTAINER * gb_key_data
Definition: gb_main.h:121
#define RETURN_ERROR(err)
Definition: arb_msg.h:27
static void error(const char *msg)
Definition: mkptypes.cxx:96
GB_ERROR gb_load_dictionary_data(GBDATA *gb_main, const char *key, char **dict_data, long *size)
Definition: adsystem.cxx:33
GB_ERROR gb_save_dictionary_data(GBDATA *gb_main, const char *key, const char *dict, int size)
Definition: adsystem.cxx:168
long size
Definition: adsystem.cxx:269
int gb_key_disabled
Definition: gb_key.h:37
GBCONTAINER * as_container() const
Definition: gb_data.h:155
void * gbm_get_mem(size_t size, long index)
Definition: gb_memory.h:130
int compression_mask
Definition: gb_key.h:38
CONSTEXPR_INLINE GBCONTAINER * GB_FATHER(GBDATA *gbd)
Definition: gb_data.h:271
GB_ERROR GB_write_security_write(GBDATA *gbd, unsigned long level)
Definition: arbdb.cxx:1558
char * key
Definition: gb_key.h:29
GBDATA * gb_main() const
Definition: gb_main.h:179
Definition: arbdb.h:86
GB_ERROR GB_set_dictionary(GBDATA *gb_main, const char *key, const DictData *dd)
Definition: adsystem.cxx:295
GB_ERROR GB_create_index(GBDATA *gbd, const char *key, GB_CASE case_sens, long estimated_size) __ATTR__USERESULT
Definition: adindex.cxx:117
static void copy(double **i, double **j)
Definition: trnsprob.cxx:32
void GB_internal_error(const char *message)
Definition: arb_msg.cxx:435
DictData * GB_get_dictionary(GBDATA *gb_main, const char *key)
Definition: adsystem.cxx:279
long sizeofkeys
Definition: gb_main.h:132
GBDATA * GB_find_string(GBDATA *gbd, const char *key, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
Definition: adquery.cxx:302
gb_Key * keys
Definition: gb_main.h:134
#define NULp
Definition: cxxforward.h:97
#define GB_SYSTEM_KEY_DATA
Definition: arbdb.h:28
int textlen
Definition: gb_dict.h:18
GBDATA * gb_search(GBCONTAINER *gbc, const char *key, GB_TYPES create, int internflag)
Definition: adquery.cxx:445
GB_ERROR GB_ensure_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
Definition: ad_cb.cxx:445
GB_NINT * resort
Definition: gb_dict.h:21
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
Definition: arbdb.cxx:874
GBDATA * gb_main
Definition: adname.cxx:33
void gbm_free_mem(void *block, size_t size, long index)
Definition: gb_memory.h:131
Definition: arbdb.h:71
static GB_CSTR gb_read_dict_data(GBDATA *gb_dict, long *size)
Definition: adsystem.cxx:20
void gb_load_single_key_data(GBDATA *gb_main, GBQUARK q)
Definition: adsystem.cxx:112
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
GB_CB_TYPE
Definition: arbdb_base.h:46
const char * GB_CSTR
Definition: arbdb_base.h:25
int GBQUARK
Definition: arbdb_base.h:30
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
unsigned int compressed_data
Definition: gb_data.h:70
GB_ERROR gb_load_key_data_and_dictionaries(GB_MAIN_TYPE *Main)
Definition: adsystem.cxx:209