8 #define INTERNAL_ENCODING "UTF8"
9 #define ENCODING_CONF_FILE "gedcom.enc"
12 static iconv_t cd_to_internal = (iconv_t) -1;
13 static char int_buf[MAXGEDCLINELEN*2];
14 static void *encoding_mapping = NULL;
21 int node_compare(const void *node1, const void *node2)
23 return strcmp(((const struct node *) node1)->gedcom_name,
24 ((const struct node *) node2)->gedcom_name);
27 void add_encoding(char *gedcom_n, char *iconv_n)
30 struct node *nodeptr = (struct node *) malloc(sizeof *nodeptr);
31 nodeptr->gedcom_name = (char *) malloc(strlen(gedcom_n) + 1);
32 nodeptr->iconv_name = (char *) malloc(strlen(iconv_n) + 1);
33 strcpy(nodeptr->gedcom_name, gedcom_n);
34 strcpy(nodeptr->iconv_name, iconv_n);
35 datum = tsearch(nodeptr, &encoding_mapping, node_compare);
36 if ((datum == NULL) || (*datum != nodeptr)) {
37 gedcom_warning("Duplicate entry found for encoding '%s', ignoring",
42 char* get_encoding(char* gedcom_n)
45 struct node search_node;
46 search_node.gedcom_name = gedcom_n;
47 datum = tfind(&search_node, &encoding_mapping, node_compare);
49 gedcom_error("No encoding found for '%s'", gedcom_n);
53 return ((const struct node *) *datum)->iconv_name;
59 if (encoding_mapping == NULL) {
61 char buffer[MAXBUF + 1];
62 char gedcom_n[MAXBUF + 1];
63 char iconv_n[MAXBUF + 1];
64 in = fopen(ENCODING_CONF_FILE, "r");
66 while (fgets(buffer, sizeof(buffer), in) != NULL) {
67 if (buffer[strlen(buffer) - 1] != '\n') {
68 gedcom_error("Line too long in encoding configuration file '%s'",
72 else if (buffer[0] != '#') {
73 if (sscanf(buffer, "%s %s", gedcom_n, iconv_n) == 2) {
74 add_encoding(gedcom_n, iconv_n);
81 gedcom_warning("Could not open encoding configuration file '%s'",
87 int open_conv_to_internal(char* fromcode)
89 char *encoding = get_encoding(fromcode);
90 if (cd_to_internal != (iconv_t) -1)
91 iconv_close(cd_to_internal);
92 if (encoding == NULL) {
93 cd_to_internal = (iconv_t) -1;
96 cd_to_internal = iconv_open(INTERNAL_ENCODING, encoding);
98 return (cd_to_internal != (iconv_t) -1);
101 void close_conv_to_internal()
103 iconv_close(cd_to_internal);
104 cd_to_internal = (iconv_t) -1;
107 char* to_internal(char* str, size_t len)
110 size_t outsize = MAXGEDCLINELEN * 2;
111 char *wrptr = int_buf;
113 memset(int_buf, 0, sizeof(int_buf));
114 iconv(cd_to_internal, &rdptr, &insize, &wrptr, &outsize);