1 /* Copyright (C) 2003,2004,2005 MORIOKA Tomohiko
2 This file is part of the CONCORD Library.
4 The CONCORD Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The CONCORD Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the CONCORD Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 #include <sys/types.h>
29 #include "concord-name.h"
30 #include "concord-bdb.h"
34 CONCORD_String_size (const CONCORD_String s)
40 CONCORD_String_data (const CONCORD_String s)
46 concord_ds_open_genre (CONCORD_DS ds, const unsigned char* name);
48 int concord_close_genre (CONCORD_Genre genre);
52 concord_genre_open_feature (CONCORD_Genre genre, const unsigned char* name);
54 int concord_close_feature (CONCORD_Feature feature);
58 concord_genre_open_index (CONCORD_Genre genre, const unsigned char* index);
60 int concord_close_index (CONCORD_INDEX table);
64 concord_default_read_object (const unsigned char* string, size_t length);
67 struct CONCORD_DS_Table
69 CONCORD_Backend_Type type;
70 unsigned char *location;
71 CONCORD_NAME_TABLE* genre_names;
75 CONCORD_Object object_nil;
76 CONCORD_Object (*read_object) (const unsigned char* str, size_t length);
80 concord_default_read_object (const unsigned char* str, size_t length)
82 unsigned char* buf = malloc (length + 1);
86 strncpy (buf, str, length);
92 concord_open_ds (CONCORD_Backend_Type type, const unsigned char* location,
93 int subtype, int modemask)
95 CONCORD_DS ds = (CONCORD_DS)malloc (sizeof (CONCORD_DS_Table));
96 size_t len = strlen (location);
102 ds->subtype = ( (subtype != 0) ? subtype : DB_HASH );
103 ds->modemask = modemask;
104 ds->location = (unsigned char*)malloc (len + 1);
105 if (ds->location == NULL)
106 goto location_failure;
108 strcpy (ds->location, location);
110 ds->genre_names = concord_make_name_table ();
111 if (ds->genre_names == NULL)
119 ds->object_nil = NULL;
120 ds->read_object = &concord_default_read_object;
126 CONCORD_DS_close (CONCORD_DS ds)
128 if (ds->location != NULL)
130 if (ds->genre_names != NULL)
131 concord_destroy_name_table (ds->genre_names);
137 concord_ds_location (CONCORD_DS ds)
143 concord_ds_set_object_nil (CONCORD_DS ds, CONCORD_Object object_nil)
145 ds->object_nil = object_nil;
150 concord_ds_set_read_object_function (CONCORD_DS ds,
151 CONCORD_Object (*read_object)
152 (const unsigned char* str,
155 ds->read_object = read_object;
160 concord_ds_get_genre (CONCORD_DS ds, const unsigned char* name)
164 genre = concord_name_table_get (ds->genre_names, name);
168 genre = concord_ds_open_genre (ds, name);
172 if (concord_name_table_put (ds->genre_names, name, genre))
174 concord_close_genre (genre);
181 concord_ds_foreach_genre_name (CONCORD_DS ds,
182 int (*func) (CONCORD_DS ds,
183 unsigned char* name))
185 unsigned char* dname = ds->location;
189 if ( (dir = opendir (dname)) == NULL)
192 while ( (de = readdir (dir)) != NULL )
194 if ( (strcmp (de->d_name, ".") != 0) &&
195 (strcmp (de->d_name, "..") != 0) )
197 int i, need_to_decode = 0;
202 for (cp = de->d_name, i = 0; *cp != '\0'; i++)
213 name = (unsigned char *) alloca (i);
217 while ( (ch = *cp++) != '\0')
233 if ( ('0' <= ch) && (ch <= '9') )
234 hex[index++] = ch - '0';
235 else if ( ('A' <= ch) && (ch <= 'F') )
236 hex[index++] = ch - 'A' + 10;
237 else if ( ('a' <= ch) && (ch <= 'f') )
238 hex[index++] = ch - 'a' + 10;
250 *np++ = (hex[0] << 4) | hex[1];
264 return closedir (dir);
267 return closedir (dir);
271 struct CONCORD_Genre_Table
275 CONCORD_NAME_TABLE* feature_names;
276 CONCORD_NAME_TABLE* index_names;
280 concord_ds_open_genre (CONCORD_DS ds, const unsigned char* name)
283 size_t len = strlen (name);
288 genre = (CONCORD_Genre)malloc (sizeof (CONCORD_Genre_Table));
293 genre->name = (unsigned char*)malloc (len + 1);
294 if (genre->name == NULL)
299 strcpy (genre->name, name);
301 genre->feature_names = concord_make_name_table ();
302 if (genre->feature_names == NULL)
309 genre->index_names = concord_make_name_table ();
310 if (genre->index_names == NULL)
312 free (genre->feature_names);
321 concord_close_genre (CONCORD_Genre genre)
328 if (genre->name == NULL)
336 if (genre->feature_names != NULL)
337 concord_destroy_name_table (genre->feature_names);
339 if (genre->index_names != NULL)
340 concord_destroy_name_table (genre->index_names);
347 concord_genre_get_data_source (CONCORD_Genre genre)
353 concord_genre_foreach_feature_name (CONCORD_Genre genre,
354 int (*func) (CONCORD_Genre genre,
355 unsigned char* name))
358 = alloca (strlen (genre->ds->location)
359 + 1 + strlen (genre->name) + sizeof ("/feature") + 1);
363 strcpy (dname, genre->ds->location);
365 strcat (dname, genre->name);
366 strcat (dname, "/feature");
368 if ( (dir = opendir (dname)) == NULL)
371 while ( (de = readdir (dir)) != NULL )
373 if ( (strcmp (de->d_name, ".") != 0) &&
374 (strcmp (de->d_name, "..") != 0) )
376 int i, need_to_decode = 0;
381 for (cp = de->d_name, i = 0; *cp != '\0'; i++)
392 name = (unsigned char *) alloca (i);
396 while ( (ch = *cp++) != '\0')
412 if ( ('0' <= ch) && (ch <= '9') )
413 hex[index++] = ch - '0';
414 else if ( ('A' <= ch) && (ch <= 'F') )
415 hex[index++] = ch - 'A' + 10;
416 else if ( ('a' <= ch) && (ch <= 'f') )
417 hex[index++] = ch - 'a' + 10;
429 *np++ = (hex[0] << 4) | hex[1];
442 if (func (genre, name))
443 return closedir (dir);
446 return closedir (dir);
450 concord_genre_get_feature (CONCORD_Genre genre, const unsigned char* name)
452 CONCORD_Feature feature;
454 feature = concord_name_table_get (genre->feature_names, name);
458 feature = concord_genre_open_feature (genre, name);
462 if (concord_name_table_put (genre->feature_names, name, feature))
464 concord_close_feature (feature);
471 concord_genre_get_index (CONCORD_Genre genre, const unsigned char* name)
475 index = concord_name_table_get (genre->index_names, name);
479 index = concord_genre_open_index (genre, name);
483 if (concord_name_table_put (genre->index_names, name, index))
485 concord_close_index (index);
492 struct CONCORD_Feature_Table
501 concord_genre_open_feature (CONCORD_Genre genre, const unsigned char* feature)
503 CONCORD_Feature table;
504 size_t len = strlen (feature);
509 table = (CONCORD_Feature)malloc (sizeof (CONCORD_Feature_Table));
513 table->genre = genre;
516 table->name = (unsigned char*)malloc (len + 1);
517 if (table->name == NULL)
522 strcpy (table->name, feature);
527 concord_close_feature (CONCORD_Feature feature)
534 if (feature->db == NULL)
537 status = CONCORD_BDB_close (feature->db);
539 if (feature->name == NULL)
543 free (feature->name);
551 concord_feature_get_name (CONCORD_Feature feature)
553 return feature->name;
557 concord_feature_setup_db (CONCORD_Feature feature, int writable)
566 if ((feature->access & DB_CREATE) == 0)
568 if (feature->db != NULL)
570 CONCORD_BDB_close (feature->db);
580 if (feature->db == NULL)
582 CONCORD_Genre genre = feature->genre;
585 = CONCORD_BDB_open (genre->ds->location, genre->name,
586 "feature", feature->name,
588 access, genre->ds->modemask);
589 if (feature->db == NULL)
591 feature->access = access;
597 concord_feature_sync (CONCORD_Feature feature)
601 if (feature->db == NULL)
604 status = CONCORD_BDB_close (feature->db);
611 concord_stroid_set_feature_str (const unsigned char* object_id,
612 CONCORD_Feature feature,
613 unsigned char* value)
617 if (concord_feature_setup_db (feature, 1))
619 return CONCORD_BDB_put (feature->db, object_id, value);
623 concord_stroid_get_feature_string (const unsigned char* object_id,
624 CONCORD_Feature feature,
625 CONCORD_String value)
629 if (concord_feature_setup_db (feature, 0))
631 status = CONCORD_BDB_get (feature->db, object_id, value);
636 concord_stroid_get_feature_object (const unsigned char* object_id,
637 CONCORD_Feature feature)
642 if (concord_feature_setup_db (feature, 0))
643 return feature->genre->ds->object_nil;
644 status = CONCORD_BDB_get (feature->db, object_id, &valdatum);
646 return feature->genre->ds->object_nil;
647 return (*feature->genre->ds->read_object)(valdatum.data, valdatum.size);
651 concord_stroid_gets_feature (const unsigned char* object_id,
652 CONCORD_Feature feature,
653 unsigned char* dst, size_t size)
658 if (concord_feature_setup_db (feature, 0))
660 status = CONCORD_BDB_get (feature->db, object_id, &valdatum);
663 if (size < valdatum.size)
665 strncpy (dst, valdatum.data, valdatum.size);
666 dst[valdatum.size] = '\0';
671 concord_feature_foreach_object_string (CONCORD_Feature feature,
672 int (*func)(CONCORD_String object_id,
673 CONCORD_Feature feature,
674 CONCORD_String value))
676 CONCORD_String_Tank key, value;
680 if (concord_feature_setup_db (feature, 0))
685 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
686 for (status = dbcp->c_get (dbcp, &key, &value, DB_FIRST);
688 status = dbcp->c_get (dbcp, &key, &value, DB_NEXT))
690 int ret = func (&key, feature, &value);
695 dbcp->c_close (dbcp);
700 struct CONCORD_INDEX_Table
709 concord_genre_open_index (CONCORD_Genre genre, const unsigned char* index)
712 size_t len = strlen (index);
717 table = (CONCORD_INDEX)malloc (sizeof (CONCORD_INDEX_Table));
721 table->genre = genre;
724 table->name = (unsigned char*)malloc (len + 1);
725 if (table->name == NULL)
730 strcpy (table->name, index);
735 concord_close_index (CONCORD_INDEX table)
742 if (table->db == NULL)
745 status = CONCORD_BDB_close (table->db);
747 if (table->name == NULL)
759 concord_index_setup_db (CONCORD_INDEX index, int writable)
768 if ((index->access & DB_CREATE) == 0)
770 if (index->db != NULL)
772 CONCORD_BDB_close (index->db);
782 if (index->db == NULL)
784 CONCORD_Genre genre = index->genre;
787 = CONCORD_BDB_open (genre->ds->location, genre->name,
788 "index", index->name,
790 access, genre->ds->modemask);
791 if (index->db == NULL)
793 index->access = access;
799 concord_index_sync (CONCORD_INDEX index)
803 if (index->db == NULL)
806 status = CONCORD_BDB_close (index->db);
813 concord_index_strid_get_object_string (CONCORD_INDEX index,
814 const unsigned char* strid,
815 CONCORD_String object_id)
820 if (concord_index_setup_db (index, 0))
823 return CONCORD_BDB_get (index->db, strid, object_id);
827 concord_index_strid_set_object_str (CONCORD_INDEX index,
828 const unsigned char* strid,
829 unsigned char* object_id)
834 if (concord_index_setup_db (index, 1))
837 return CONCORD_BDB_put (index->db, strid, object_id);