summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2016-02-24 19:57:18 +0900
committerAkira TAGOH <akira@tagoh.org>2016-02-24 20:00:50 +0900
commit417a24859a29c7b0e8f2062e480a995171b8747f (patch)
treeda1ded6011bbfabaea8787ad746f540002c9ace8
parentfeb0c1f5f0610b39668baff4978a6a926af78965 (diff)
Improve the bootup time
Delay-loading the database when it is needed.
-rw-r--r--liblangtag/lt-database.c10
-rw-r--r--liblangtag/lt-extlang-db.c89
-rw-r--r--liblangtag/lt-grandfathered-db.c59
-rw-r--r--liblangtag/lt-lang-db.c76
-rw-r--r--liblangtag/lt-redundant-db.c59
-rw-r--r--liblangtag/lt-region-db.c90
-rw-r--r--liblangtag/lt-relation-db.c64
-rw-r--r--liblangtag/lt-script-db.c90
-rw-r--r--liblangtag/lt-variant-db.c90
-rw-r--r--liblangtag/lt-xml.c154
10 files changed, 394 insertions, 387 deletions
diff --git a/liblangtag/lt-database.c b/liblangtag/lt-database.c
index 424f309..6532c6b 100644
--- a/liblangtag/lt-database.c
+++ b/liblangtag/lt-database.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-database.c
- * Copyright (C) 2011-2015 Akira TAGOH
+ * Copyright (C) 2011-2016 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -18,6 +18,7 @@
#include "lt-mem.h"
#include "lt-ext-module.h"
#include "lt-utils.h"
+#include "lt-xml.h"
#include "lt-database.h"
@@ -31,6 +32,7 @@
static lt_db_val_t __dbval;
static lt_db_val_t *__db_master = &__dbval;
+static lt_xml_t *__db_xml = NULL;
static char __lt_db_datadir[LT_PATH_MAX] = { 0 };
@@ -114,6 +116,11 @@ lt_db_initialize(void)
lt_db_get_redundant();
if (!__db_master->relation)
lt_db_get_relation();
+ if (!__db_xml) {
+ __db_xml = lt_xml_new();
+ lt_mem_add_weak_pointer((lt_mem_t *)__db_xml,
+ (lt_pointer_t *)&__db_xml);
+ }
lt_ext_modules_load();
}
@@ -134,6 +141,7 @@ lt_db_finalize(void)
lt_grandfathered_db_unref(__db_master->grandfathered);
lt_redundant_db_unref(__db_master->redundant);
lt_relation_db_unref(__db_master->relation);
+ lt_xml_unref(__db_xml);
lt_ext_modules_unload();
}
diff --git a/liblangtag/lt-extlang-db.c b/liblangtag/lt-extlang-db.c
index 3905757..b50d92f 100644
--- a/liblangtag/lt-extlang-db.c
+++ b/liblangtag/lt-extlang-db.c
@@ -20,6 +20,7 @@
#include "lt-extlang.h"
#include "lt-extlang-private.h"
#include "lt-iter-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -38,7 +39,6 @@
*/
struct _lt_extlang_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *extlang_entries;
};
typedef struct _lt_extlang_db_iter_t {
@@ -46,21 +46,44 @@ typedef struct _lt_extlang_db_iter_t {
lt_iter_t *iter;
} lt_extlang_db_iter_t;
+LT_LOCK_DEFINE_STATIC (edb);
+
/*< private >*/
static lt_bool_t
lt_extlang_db_parse(lt_extlang_db_t *extlangdb,
lt_error_t **error)
{
+ lt_xml_t *xml;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
xmlXPathObjectPtr xobj = NULL;
lt_error_t *err = NULL;
int i, n;
+ lt_extlang_t *le;
lt_return_val_if_fail (extlangdb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(extlangdb->xml);
+ extlangdb->extlang_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)extlangdb, extlangdb->extlang_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ le = lt_extlang_create();
+ lt_extlang_set_tag(le, "*");
+ lt_extlang_set_name(le, "Wildcard entry");
+ lt_trie_replace(extlangdb->extlang_entries,
+ lt_extlang_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_extlang_unref);
+ le = lt_extlang_create();
+ lt_extlang_set_tag(le, "");
+ lt_extlang_set_name(le, "Empty entry");
+ lt_trie_replace(extlangdb->extlang_entries,
+ lt_extlang_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_extlang_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -189,6 +212,8 @@ lt_extlang_db_parse(lt_extlang_db_t *extlangdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -199,6 +224,15 @@ _lt_extlang_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_extlang_db_iter_t *retval;
lt_extlang_db_t *extlangdb = (lt_extlang_db_t *)tmpl;
+ LT_LOCK (edb);
+ if (!extlangdb->extlang_entries) {
+ if (!lt_extlang_db_parse(extlangdb, NULL)) {
+ LT_UNLOCK (edb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (edb);
+
retval = malloc(sizeof (lt_extlang_db_iter_t));
if (!retval)
return NULL;
@@ -242,49 +276,9 @@ lt_extlang_db_new(void)
{
lt_extlang_db_t *retval = lt_mem_alloc_object(sizeof (lt_extlang_db_t));
- if (retval) {
- lt_error_t *err = NULL;
- lt_extlang_t *le;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_extlang_db);
- retval->extlang_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->extlang_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- le = lt_extlang_create();
- lt_extlang_set_tag(le, "*");
- lt_extlang_set_name(le, "Wildcard entry");
- lt_trie_replace(retval->extlang_entries,
- lt_extlang_get_tag(le),
- le,
- (lt_destroy_func_t)lt_extlang_unref);
- le = lt_extlang_create();
- lt_extlang_set_tag(le, "");
- lt_extlang_set_name(le, "Empty entry");
- lt_trie_replace(retval->extlang_entries,
- lt_extlang_get_tag(le),
- le,
- (lt_destroy_func_t)lt_extlang_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_extlang_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
- lt_extlang_db_parse(retval, &err);
- if (err) {
- lt_error_print(err, LT_ERR_ANY);
- lt_extlang_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -338,6 +332,15 @@ lt_extlang_db_lookup(lt_extlang_db_t *extlangdb,
lt_return_val_if_fail (extlangdb != NULL, NULL);
lt_return_val_if_fail (subtag != NULL, NULL);
+ LT_LOCK (edb);
+ if (!extlangdb->extlang_entries) {
+ if (!lt_extlang_db_parse(extlangdb, NULL)) {
+ LT_UNLOCK (edb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (edb);
+
s = strdup(subtag);
retval = lt_trie_lookup(extlangdb->extlang_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-grandfathered-db.c b/liblangtag/lt-grandfathered-db.c
index 03cae56..494f641 100644
--- a/liblangtag/lt-grandfathered-db.c
+++ b/liblangtag/lt-grandfathered-db.c
@@ -20,6 +20,7 @@
#include "lt-grandfathered.h"
#include "lt-grandfathered-private.h"
#include "lt-iter-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -38,7 +39,6 @@
*/
struct _lt_grandfathered_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *grandfathered_entries;
};
typedef struct _lt_grandfathered_db_iter_t {
@@ -46,11 +46,14 @@ typedef struct _lt_grandfathered_db_iter_t {
lt_iter_t *iter;
} lt_grandfathered_db_iter_t;
+LT_LOCK_DEFINE_STATIC (gdb);
+
/*< private >*/
static lt_bool_t
lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb,
lt_error_t **error)
{
+ lt_xml_t *xml;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -60,7 +63,12 @@ lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb,
lt_return_val_if_fail (grandfathereddb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(grandfathereddb->xml);
+ xml = lt_xml_new();
+ grandfathereddb->grandfathered_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)grandfathereddb, grandfathereddb->grandfathered_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -168,6 +176,8 @@ lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -178,6 +188,15 @@ _lt_grandfathered_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_grandfathered_db_iter_t *retval;
lt_grandfathered_db_t *db = (lt_grandfathered_db_t *)tmpl;
+ LT_LOCK (gdb);
+ if (!db->grandfathered_entries) {
+ if (!lt_grandfathered_db_parse(db, NULL)) {
+ LT_UNLOCK (gdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (gdb);
+
retval = malloc(sizeof (lt_grandfathered_db_iter_t));
if (!retval)
return NULL;
@@ -221,34 +240,9 @@ lt_grandfathered_db_new(void)
{
lt_grandfathered_db_t *retval = lt_mem_alloc_object(sizeof (lt_grandfathered_db_t));
- if (retval) {
- lt_error_t *err = NULL;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_grandfathered_db);
- retval->grandfathered_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->grandfathered_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_grandfathered_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_grandfathered_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_grandfathered_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -302,6 +296,15 @@ lt_grandfathered_db_lookup(lt_grandfathered_db_t *grandfathereddb,
lt_return_val_if_fail (grandfathereddb != NULL, NULL);
lt_return_val_if_fail (tag != NULL, NULL);
+ LT_LOCK (gdb);
+ if (!grandfathereddb->grandfathered_entries) {
+ if (!lt_grandfathered_db_parse(grandfathereddb, NULL)) {
+ LT_UNLOCK (gdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (gdb);
+
s = strdup(tag);
retval = lt_trie_lookup(grandfathereddb->grandfathered_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-lang-db.c b/liblangtag/lt-lang-db.c
index 37b59ab..43391ed 100644
--- a/liblangtag/lt-lang-db.c
+++ b/liblangtag/lt-lang-db.c
@@ -18,6 +18,7 @@
#include <libxml/xpath.h>
#include "lt-error.h"
#include "lt-iter-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -37,7 +38,6 @@
*/
struct _lt_lang_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *lang_entries;
};
typedef struct _lt_lang_db_iter_t {
@@ -45,11 +45,15 @@ typedef struct _lt_lang_db_iter_t {
lt_iter_t *iter;
} lt_lang_db_iter_t;
+LT_LOCK_DEFINE_STATIC (ldb);
+
/*< private >*/
static lt_bool_t
lt_lang_db_parse(lt_lang_db_t *langdb,
lt_error_t **error)
{
+ lt_xml_t *xml;
+ lt_lang_t *le;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -59,7 +63,19 @@ lt_lang_db_parse(lt_lang_db_t *langdb,
lt_return_val_if_fail (langdb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(langdb->xml);
+ langdb->lang_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)langdb, langdb->lang_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ le = lt_lang_create();
+ lt_lang_set_tag(le, "*");
+ lt_lang_set_name(le, "Wildcard entry");
+ lt_trie_replace(langdb->lang_entries,
+ lt_lang_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_lang_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -201,6 +217,8 @@ lt_lang_db_parse(lt_lang_db_t *langdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -211,6 +229,15 @@ _lt_lang_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_lang_db_iter_t *retval;
lt_lang_db_t *langdb = (lt_lang_db_t *)tmpl;
+ LT_LOCK (ldb);
+ if (!langdb->lang_entries) {
+ if (!lt_lang_db_parse(langdb, NULL)) {
+ LT_UNLOCK (ldb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (ldb);
+
retval = malloc(sizeof (lt_lang_db_iter_t));
if (!retval)
return NULL;
@@ -254,43 +281,9 @@ lt_lang_db_new(void)
{
lt_lang_db_t *retval = lt_mem_alloc_object(sizeof (lt_lang_db_t));
- if (retval) {
- lt_error_t *err = NULL;
- lt_lang_t *le;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_lang_db);
- retval->lang_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->lang_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- le = lt_lang_create();
- lt_lang_set_tag(le, "*");
- lt_lang_set_name(le, "Wildcard entry");
- lt_trie_replace(retval->lang_entries,
- lt_lang_get_tag(le),
- le,
- (lt_destroy_func_t)lt_lang_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_lang_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_lang_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_lang_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -344,6 +337,15 @@ lt_lang_db_lookup(lt_lang_db_t *langdb,
lt_return_val_if_fail (langdb != NULL, NULL);
lt_return_val_if_fail (subtag != NULL, NULL);
+ LT_LOCK (ldb);
+ if (!langdb->lang_entries) {
+ if (!lt_lang_db_parse(langdb, NULL)) {
+ LT_UNLOCK (ldb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (ldb);
+
s = strdup(subtag);
retval = lt_trie_lookup(langdb->lang_entries, lt_strlower(s));
free(s);
diff --git a/liblangtag/lt-redundant-db.c b/liblangtag/lt-redundant-db.c
index 7fe7b92..3cfcb4a 100644
--- a/liblangtag/lt-redundant-db.c
+++ b/liblangtag/lt-redundant-db.c
@@ -21,6 +21,7 @@
#include "lt-error.h"
#include "lt-redundant.h"
#include "lt-redundant-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -40,7 +41,6 @@
*/
struct _lt_redundant_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *redundant_entries;
};
typedef struct _lt_redundant_db_iter_t {
@@ -48,11 +48,14 @@ typedef struct _lt_redundant_db_iter_t {
lt_iter_t *iter;
} lt_redundant_db_iter_t;
+LT_LOCK_DEFINE_STATIC (rdb);
+
/*< private >*/
static lt_bool_t
lt_redundant_db_parse(lt_redundant_db_t *redundantdb,
lt_error_t **error)
{
+ lt_xml_t *xml;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -62,7 +65,12 @@ lt_redundant_db_parse(lt_redundant_db_t *redundantdb,
lt_return_val_if_fail (redundantdb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(redundantdb->xml);
+ redundantdb->redundant_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)redundantdb, redundantdb->redundant_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -169,6 +177,8 @@ lt_redundant_db_parse(lt_redundant_db_t *redundantdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -179,6 +189,15 @@ _lt_redundant_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_redundant_db_iter_t *retval;
lt_redundant_db_t *db = (lt_redundant_db_t *)tmpl;
+ LT_LOCK (rdb);
+ if (!db->redundant_entries) {
+ if (!lt_redundant_db_parse(db, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
retval = malloc(sizeof (lt_redundant_db_iter_t));
if (!retval)
return NULL;
@@ -222,34 +241,9 @@ lt_redundant_db_new(void)
{
lt_redundant_db_t *retval = lt_mem_alloc_object(sizeof (lt_redundant_db_t));
- if (retval) {
- lt_error_t *err = NULL;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_redundant_db);
- retval->redundant_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->redundant_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_redundant_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_redundant_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_redundant_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -303,6 +297,15 @@ lt_redundant_db_lookup(lt_redundant_db_t *redundantdb,
lt_return_val_if_fail (redundantdb != NULL, NULL);
lt_return_val_if_fail (tag != NULL, NULL);
+ LT_LOCK (rdb);
+ if (!redundantdb->redundant_entries) {
+ if (!lt_redundant_db_parse(redundantdb, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
s = strdup(tag);
retval = lt_trie_lookup(redundantdb->redundant_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-region-db.c b/liblangtag/lt-region-db.c
index 44b4558..9faae42 100644
--- a/liblangtag/lt-region-db.c
+++ b/liblangtag/lt-region-db.c
@@ -19,6 +19,7 @@
#include <libxml/xpath.h>
#include "lt-error.h"
#include "lt-iter-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -39,7 +40,6 @@
*/
struct _lt_region_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *region_entries;
};
typedef struct _lt_region_db_iter_t {
@@ -47,11 +47,15 @@ typedef struct _lt_region_db_iter_t {
lt_iter_t *iter;
} lt_region_db_iter_t;
+LT_LOCK_DEFINE_STATIC (rdb);
+
/*< private >*/
static lt_bool_t
lt_region_db_parse(lt_region_db_t *regiondb,
lt_error_t **error)
{
+ lt_xml_t *xml;
+ lt_region_t *le;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -61,7 +65,26 @@ lt_region_db_parse(lt_region_db_t *regiondb,
lt_return_val_if_fail (regiondb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(regiondb->xml);
+ regiondb->region_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)regiondb, regiondb->region_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ le = lt_region_create();
+ lt_region_set_tag(le, "*");
+ lt_region_set_name(le, "Wildcard entry");
+ lt_trie_replace(regiondb->region_entries,
+ lt_region_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_region_unref);
+ le = lt_region_create();
+ lt_region_set_tag(le, "");
+ lt_region_set_name(le, "Empty entry");
+ lt_trie_replace(regiondb->region_entries,
+ lt_region_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_region_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -169,6 +192,8 @@ lt_region_db_parse(lt_region_db_t *regiondb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -179,6 +204,15 @@ _lt_region_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_region_db_iter_t *retval;
lt_region_db_t *db = (lt_region_db_t *)tmpl;
+ LT_LOCK (rdb);
+ if (!db->region_entries) {
+ if (!lt_region_db_parse(db, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
retval = malloc(sizeof (lt_region_db_iter_t));
if (!retval)
return NULL;
@@ -222,50 +256,9 @@ lt_region_db_new(void)
{
lt_region_db_t *retval = lt_mem_alloc_object(sizeof (lt_region_db_t));
- if (retval) {
- lt_error_t *err = NULL;
- lt_region_t *le;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_region_db);
- retval->region_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->region_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- le = lt_region_create();
- lt_region_set_tag(le, "*");
- lt_region_set_name(le, "Wildcard entry");
- lt_trie_replace(retval->region_entries,
- lt_region_get_tag(le),
- le,
- (lt_destroy_func_t)lt_region_unref);
- le = lt_region_create();
- lt_region_set_tag(le, "");
- lt_region_set_name(le, "Empty entry");
- lt_trie_replace(retval->region_entries,
- lt_region_get_tag(le),
- le,
- (lt_destroy_func_t)lt_region_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_region_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_region_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_region_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -320,6 +313,15 @@ lt_region_db_lookup(lt_region_db_t *regiondb,
lt_return_val_if_fail (regiondb != NULL, NULL);
lt_return_val_if_fail (language_or_code != NULL, NULL);
+ LT_LOCK (rdb);
+ if (!regiondb->region_entries) {
+ if (!lt_region_db_parse(regiondb, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
s = strdup(language_or_code);
retval = lt_trie_lookup(regiondb->region_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-relation-db.c b/liblangtag/lt-relation-db.c
index 8aa1b31..f3badfd 100644
--- a/liblangtag/lt-relation-db.c
+++ b/liblangtag/lt-relation-db.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-relation-db.c
- * Copyright (C) 2015 Akira TAGOH
+ * Copyright (C) 2015-2016 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -20,6 +20,7 @@
#include "lt-database.h"
#include "lt-error.h"
#include "lt-list.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -36,11 +37,12 @@
*/
struct _lt_relation_db_t {
lt_mem_t parent;
- lt_xml_t *xml;
lt_trie_t *relation_l_s_entries;
lt_trie_t *relation_s_l_entries;
};
+LT_LOCK_DEFINE_STATIC (rdb);
+
/*< private >*/
static lt_bool_t
lt_relation_db_parse(lt_relation_db_t *relationdb,
@@ -54,10 +56,19 @@ lt_relation_db_parse(lt_relation_db_t *relationdb,
int i, n;
lt_lang_db_t *langdb = NULL;
lt_script_db_t *scriptdb = NULL;
+ lt_xml_t *xml;
lt_return_val_if_fail (relationdb != NULL, FALSE);
- doc = lt_xml_get_cldr(relationdb->xml, LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA);
+ relationdb->relation_l_s_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)relationdb, relationdb->relation_l_s_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ relationdb->relation_s_l_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)relationdb, relationdb->relation_s_l_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_cldr(xml, LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -153,6 +164,8 @@ lt_relation_db_parse(lt_relation_db_t *relationdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -170,33 +183,6 @@ lt_relation_db_new(void)
{
lt_relation_db_t *retval = lt_mem_alloc_object(sizeof (lt_relation_db_t));
- if (retval) {
- lt_error_t *err = NULL;
-
- retval->relation_l_s_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->relation_l_s_entries,
- (lt_destroy_func_t)lt_trie_unref);
- retval->relation_s_l_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->relation_s_l_entries,
- (lt_destroy_func_t)lt_trie_unref);
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_relation_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_relation_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_relation_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
return retval;
}
@@ -244,6 +230,15 @@ lt_relation_db_lookup_lang_from_script(lt_relation_db_t *relationdb,
lt_return_val_if_fail (relationdb != NULL, NULL);
lt_return_val_if_fail (script != NULL, NULL);
+ LT_LOCK (rdb);
+ if (!relationdb->relation_s_l_entries) {
+ if (!lt_relation_db_parse(relationdb, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
key = strdup(lt_script_get_name(script));
l = lt_trie_lookup(relationdb->relation_s_l_entries,
lt_strlower(key));
@@ -272,6 +267,15 @@ lt_relation_db_lookup_script_from_lang(lt_relation_db_t *relationdb,
lt_return_val_if_fail (relationdb != NULL, NULL);
lt_return_val_if_fail (lang != NULL, NULL);
+ LT_LOCK (rdb);
+ if (!relationdb->relation_l_s_entries) {
+ if (!lt_relation_db_parse(relationdb, NULL)) {
+ LT_UNLOCK (rdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (rdb);
+
key = strdup(lt_lang_get_tag(lang));
l = lt_trie_lookup(relationdb->relation_l_s_entries,
lt_strlower(key));
diff --git a/liblangtag/lt-script-db.c b/liblangtag/lt-script-db.c
index 34b0c3b..8278078 100644
--- a/liblangtag/lt-script-db.c
+++ b/liblangtag/lt-script-db.c
@@ -19,6 +19,7 @@
#include <libxml/xpath.h>
#include "lt-error.h"
#include "lt-iter-private.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -38,7 +39,6 @@
*/
struct _lt_script_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *script_entries;
};
typedef struct _lt_script_db_iter_t {
@@ -46,11 +46,15 @@ typedef struct _lt_script_db_iter_t {
lt_iter_t *iter;
} lt_script_db_iter_t;
+LT_LOCK_DEFINE_STATIC (sdb);
+
/*< private >*/
static lt_bool_t
lt_script_db_parse(lt_script_db_t *scriptdb,
lt_error_t **error)
{
+ lt_xml_t *xml;
+ lt_script_t *le;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -60,7 +64,26 @@ lt_script_db_parse(lt_script_db_t *scriptdb,
lt_return_val_if_fail (scriptdb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(scriptdb->xml);
+ scriptdb->script_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)scriptdb, scriptdb->script_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ le = lt_script_create();
+ lt_script_set_tag(le, "*");
+ lt_script_set_name(le, "Wildcard entry");
+ lt_trie_replace(scriptdb->script_entries,
+ lt_script_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_script_unref);
+ le = lt_script_create();
+ lt_script_set_tag(le, "");
+ lt_script_set_name(le, "Empty entry");
+ lt_trie_replace(scriptdb->script_entries,
+ lt_script_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_script_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -156,6 +179,8 @@ lt_script_db_parse(lt_script_db_t *scriptdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -166,6 +191,15 @@ _lt_script_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_script_db_iter_t *retval;
lt_script_db_t *db = (lt_script_db_t *)tmpl;
+ LT_LOCK (sdb);
+ if (!db->script_entries) {
+ if (!lt_script_db_parse(db, NULL)) {
+ LT_UNLOCK (sdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (sdb);
+
retval = malloc(sizeof (lt_script_db_iter_t));
if (!retval)
return NULL;
@@ -209,50 +243,9 @@ lt_script_db_new(void)
{
lt_script_db_t *retval = lt_mem_alloc_object(sizeof (lt_script_db_t));
- if (retval) {
- lt_error_t *err = NULL;
- lt_script_t *le;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_script_db);
- retval->script_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->script_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- le = lt_script_create();
- lt_script_set_tag(le, "*");
- lt_script_set_name(le, "Wildcard entry");
- lt_trie_replace(retval->script_entries,
- lt_script_get_tag(le),
- le,
- (lt_destroy_func_t)lt_script_unref);
- le = lt_script_create();
- lt_script_set_tag(le, "");
- lt_script_set_name(le, "Empty entry");
- lt_trie_replace(retval->script_entries,
- lt_script_get_tag(le),
- le,
- (lt_destroy_func_t)lt_script_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_script_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_script_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_script_db_unref(retval);
- retval = NULL;
- lt_error_unref(err);
- }
- }
- bail:
-
return retval;
}
@@ -306,6 +299,15 @@ lt_script_db_lookup(lt_script_db_t *scriptdb,
lt_return_val_if_fail (scriptdb != NULL, NULL);
lt_return_val_if_fail (subtag != NULL, NULL);
+ LT_LOCK (sdb);
+ if (!scriptdb->script_entries) {
+ if (!lt_script_db_parse(scriptdb, NULL)) {
+ LT_UNLOCK (sdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (sdb);
+
s = strdup(subtag);
retval = lt_trie_lookup(scriptdb->script_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-variant-db.c b/liblangtag/lt-variant-db.c
index eb2e1ae..7717d66 100644
--- a/liblangtag/lt-variant-db.c
+++ b/liblangtag/lt-variant-db.c
@@ -22,6 +22,7 @@
#include "lt-variant.h"
#include "lt-variant-private.h"
#include "lt-list.h"
+#include "lt-lock.h"
#include "lt-mem.h"
#include "lt-messages.h"
#include "lt-trie.h"
@@ -40,7 +41,6 @@
*/
struct _lt_variant_db_t {
lt_iter_tmpl_t parent;
- lt_xml_t *xml;
lt_trie_t *variant_entries;
};
typedef struct _lt_variant_db_iter_t {
@@ -48,11 +48,15 @@ typedef struct _lt_variant_db_iter_t {
lt_iter_t *iter;
} lt_variant_db_iter_t;
+LT_LOCK_DEFINE_STATIC (vdb);
+
/*< private >*/
static lt_bool_t
lt_variant_db_parse(lt_variant_db_t *variantdb,
lt_error_t **error)
{
+ lt_xml_t *xml;
+ lt_variant_t *le;
lt_bool_t retval = TRUE;
xmlDocPtr doc = NULL;
xmlXPathContextPtr xctxt = NULL;
@@ -62,7 +66,26 @@ lt_variant_db_parse(lt_variant_db_t *variantdb,
lt_return_val_if_fail (variantdb != NULL, FALSE);
- doc = lt_xml_get_subtag_registry(variantdb->xml);
+ variantdb->variant_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)variantdb, variantdb->variant_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ le = lt_variant_create();
+ lt_variant_set_tag(le, "*");
+ lt_variant_set_name(le, "Wildcard entry");
+ lt_trie_replace(variantdb->variant_entries,
+ lt_variant_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_variant_unref);
+ le = lt_variant_create();
+ lt_variant_set_tag(le, "");
+ lt_variant_set_name(le, "Empty entry");
+ lt_trie_replace(variantdb->variant_entries,
+ lt_variant_get_tag(le),
+ le,
+ (lt_destroy_func_t)lt_variant_unref);
+
+ xml = lt_xml_new();
+ doc = lt_xml_get_subtag_registry(xml);
xctxt = xmlXPathNewContext(doc);
if (!xctxt) {
lt_error_set(&err, LT_ERR_OOM,
@@ -179,6 +202,8 @@ lt_variant_db_parse(lt_variant_db_t *variantdb,
xmlXPathFreeObject(xobj);
if (xctxt)
xmlXPathFreeContext(xctxt);
+ if (xml)
+ lt_xml_unref(xml);
return retval;
}
@@ -189,6 +214,15 @@ _lt_variant_db_iter_init(lt_iter_tmpl_t *tmpl)
lt_variant_db_iter_t *retval;
lt_variant_db_t *db = (lt_variant_db_t *)tmpl;
+ LT_LOCK (vdb);
+ if (!db->variant_entries) {
+ if (!lt_variant_db_parse(db, NULL)) {
+ LT_UNLOCK (vdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (vdb);
+
retval = malloc(sizeof (lt_variant_db_iter_t));
if (!retval)
return NULL;
@@ -232,50 +266,9 @@ lt_variant_db_new(void)
{
lt_variant_db_t *retval = lt_mem_alloc_object(sizeof (lt_variant_db_t));
- if (retval) {
- lt_error_t *err = NULL;
- lt_variant_t *le;
-
+ if (retval)
LT_ITER_TMPL_INIT (&retval->parent, _lt_variant_db);
- retval->variant_entries = lt_trie_new();
- lt_mem_add_ref((lt_mem_t *)retval, retval->variant_entries,
- (lt_destroy_func_t)lt_trie_unref);
-
- le = lt_variant_create();
- lt_variant_set_tag(le, "*");
- lt_variant_set_name(le, "Wildcard entry");
- lt_trie_replace(retval->variant_entries,
- lt_variant_get_tag(le),
- le,
- (lt_destroy_func_t)lt_variant_unref);
- le = lt_variant_create();
- lt_variant_set_tag(le, "");
- lt_variant_set_name(le, "Empty entry");
- lt_trie_replace(retval->variant_entries,
- lt_variant_get_tag(le),
- le,
- (lt_destroy_func_t)lt_variant_unref);
-
- retval->xml = lt_xml_new();
- if (!retval->xml) {
- lt_variant_db_unref(retval);
- retval = NULL;
- goto bail;
- }
- lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
- (lt_destroy_func_t)lt_xml_unref);
-
- lt_variant_db_parse(retval, &err);
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_error_unref(err);
- lt_variant_db_unref(retval);
- retval = NULL;
- }
- }
- bail:
-
return retval;
}
@@ -329,6 +322,15 @@ lt_variant_db_lookup(lt_variant_db_t *variantdb,
lt_return_val_if_fail (variantdb != NULL, NULL);
lt_return_val_if_fail (subtag != NULL, NULL);
+ LT_LOCK (vdb);
+ if (!variantdb->variant_entries) {
+ if (!lt_variant_db_parse(variantdb, NULL)) {
+ LT_UNLOCK (vdb);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (vdb);
+
s = strdup(subtag);
retval = lt_trie_lookup(variantdb->variant_entries,
lt_strlower(s));
diff --git a/liblangtag/lt-xml.c b/liblangtag/lt-xml.c
index 3baab53..46f0ece 100644
--- a/liblangtag/lt-xml.c
+++ b/liblangtag/lt-xml.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-xml.c
- * Copyright (C) 2011-2015 Akira TAGOH
+ * Copyright (C) 2011-2016 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -15,6 +15,7 @@
#endif
#include <stddef.h>
+#include <string.h>
#include <sys/stat.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
@@ -24,6 +25,7 @@
#include "lt-messages.h"
#include "lt-database.h"
#include "lt-string.h"
+#include "lt-utils.h"
#include "lt-xml.h"
@@ -323,97 +325,12 @@ _lt_xml_merge_keys(lt_xml_t *xml,
lt_xml_t *
lt_xml_new(void)
{
- lt_error_t *err = NULL;
-
- LT_LOCK (xml);
-
- if (__xml) {
- LT_UNLOCK (xml);
-
+ if (__xml)
return lt_xml_ref(__xml);
- }
__xml = lt_mem_alloc_object(sizeof (lt_xml_t));
- if (__xml) {
- xmlDocPtr doc = NULL;
-
+ if (__xml)
lt_mem_add_weak_pointer(&__xml->parent, (lt_pointer_t *)&__xml);
- if (!lt_xml_read_subtag_registry(__xml, &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "calendar.xml",
- &__xml->cldr_bcp47_calendar,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "collation.xml",
- &__xml->cldr_bcp47_collation,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "currency.xml",
- &__xml->cldr_bcp47_currency,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "number.xml",
- &__xml->cldr_bcp47_number,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "timezone.xml",
- &__xml->cldr_bcp47_timezone,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "transform.xml",
- &__xml->cldr_bcp47_transform,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "transform_ime.xml",
- &doc,
- &err))
- goto bail;
- if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "transform_keyboard.xml",
- &doc,
- &err))
- goto bail;
- if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "transform_mt.xml",
- &doc,
- &err))
- goto bail;
- if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "transform_private_use.xml",
- &doc,
- &err))
- goto bail;
- if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err))
- goto bail;
- if (!lt_xml_read_cldr_bcp47(__xml, "variant.xml",
- &__xml->cldr_bcp47_variant,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_supplemental(__xml, "likelySubtags.xml",
- &__xml->cldr_supplemental_likelysubtags,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_supplemental(__xml, "supplementalData.xml",
- &__xml->cldr_supplemental_supplementaldata,
- &err))
- goto bail;
- if (!lt_xml_read_cldr_supplemental(__xml, "supplementalMetadata.xml",
- &__xml->cldr_supplemental_supplementalmetadata,
- &err))
- goto bail;
- }
-
- bail:
- if (lt_error_is_set(err, LT_ERR_ANY)) {
- lt_error_print(err, LT_ERR_ANY);
- lt_error_unref(err);
- lt_xml_unref(__xml);
- }
-
- LT_UNLOCK (xml);
return __xml;
}
@@ -436,8 +353,21 @@ lt_xml_unref(lt_xml_t *xml)
xmlDocPtr
lt_xml_get_subtag_registry(lt_xml_t *xml)
{
+ lt_error_t *err = NULL;
+
lt_return_val_if_fail (xml != NULL, NULL);
+ LT_LOCK (xml);
+ if (!xml->subtag_registry) {
+ if (!lt_xml_read_subtag_registry(xml, &err)) {
+ LT_UNLOCK (xml);
+ lt_error_print(err, LT_ERR_ANY);
+ lt_error_unref(err);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (xml);
+
return xml->subtag_registry;
}
@@ -445,19 +375,67 @@ xmlDocPtr
lt_xml_get_cldr(lt_xml_t *xml,
lt_xml_cldr_t type)
{
+ lt_error_t *err = NULL;
+ lt_bool_t ret = FALSE;
xmlDocPtr *pref;
int idx;
+ const char *xml_files[] = {
+ "calendar.xml", "collation.xml", "currency.xml", "number.xml", "timezone.xml", "transform.xml:transform_ime.xml:transform_keyboard.xml:transform_mt.xml:transform_private_use.xml", "variant.xml",
+ "likelySubtags.xml", "supplementalData.xml", "supplementalMetadata.xml",
+ NULL
+ };
LT_ASSERT_STATIC ((sizeof (lt_xml_t) - offsetof (lt_xml_t, cldr_bcp47_calendar)) == (sizeof (lt_pointer_t) * ((LT_XML_CLDR_BCP47_END - LT_XML_CLDR_BCP47_BEGIN + 1) + (LT_XML_CLDR_SUPPLEMENTAL_END - LT_XML_CLDR_SUPPLEMENTAL_BEGIN + 1))));
lt_return_val_if_fail (xml != NULL, NULL);
lt_return_val_if_fail (type > LT_XML_CLDR_BEGIN && type < LT_XML_CLDR_END, NULL);
+ LT_LOCK (xml);
pref = &xml->cldr_bcp47_calendar;
if (type >= LT_XML_CLDR_DUMMY1)
idx = type - LT_XML_CLDR_DUMMY1 + LT_XML_CLDR_BCP47_END;
else
idx = type;
+ if (!pref[idx - 1]) {
+ if (type >= LT_XML_CLDR_DUMMY1) {
+ ret = lt_xml_read_cldr_supplemental(xml, xml_files[idx - 1], &pref[idx - 1], &err);
+ } else if (type == LT_XML_CLDR_BCP47_TRANSFORM) {
+ const char *pp = xml_files[idx - 1];
+ char *p, *s;
+ xmlDocPtr *d = &pref[idx - 1], doc = NULL;
+
+ do {
+ p = index(pp, ':');
+ if (p)
+ s = lt_strndup(pp, p - pp);
+ else
+ s = strdup(pp);
+ if (!lt_xml_read_cldr_bcp47(xml, s, d, &err))
+ goto bail;
+ if (d == &doc) {
+ if (!_lt_xml_merge_keys(xml, pref[idx - 1], doc, &err))
+ goto bail;
+ } else {
+ d = &doc;
+ }
+ free(s);
+ if (p)
+ pp = ++p;
+ } while (p);
+ ret = TRUE;
+ } else {
+ ret = lt_xml_read_cldr_bcp47(xml, xml_files[idx - 1], &pref[idx - 1], &err);
+ }
+ bail:
+ if (!ret) {
+ LT_UNLOCK (xml);
+ lt_error_print(err, LT_ERR_ANY);
+ lt_error_unref(err);
+ return NULL;
+ }
+ }
+ LT_UNLOCK (xml);
+
return pref[idx - 1];
}