Date: Fri, 8 Aug 2014 00:20:09 GMT From: ghostmansd@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272063 - in soc2014/ghostmansd/head: lib/libc/locale lib/libc/string lib/libc/unicode lib/libcolldb share/colldb Message-ID: <201408080020.s780K9Z7063066@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ghostmansd Date: Fri Aug 8 00:20:09 2014 New Revision: 272063 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272063 Log: initial colldb adoption Added: soc2014/ghostmansd/head/lib/libc/unicode/coll.h soc2014/ghostmansd/head/share/colldb/ soc2014/ghostmansd/head/share/colldb/root.src - copied unchanged from r271972, soc2014/ghostmansd/head/lib/libcolldb/CLDR.src Deleted: soc2014/ghostmansd/head/lib/libcolldb/CLDR.src soc2014/ghostmansd/head/lib/libcolldb/DUCET.src Modified: soc2014/ghostmansd/head/lib/libc/locale/collate.c soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h soc2014/ghostmansd/head/lib/libc/string/wcscoll.c soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c soc2014/ghostmansd/head/lib/libcolldb/colldb.c soc2014/ghostmansd/head/lib/libcolldb/colldb.h soc2014/ghostmansd/head/lib/libcolldb/colldb.py Modified: soc2014/ghostmansd/head/lib/libc/locale/collate.c ============================================================================== --- soc2014/ghostmansd/head/lib/libc/locale/collate.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/locale/collate.c Fri Aug 8 00:20:09 2014 (r272063) @@ -49,6 +49,316 @@ #include "libc_private.h" + +#ifdef _UNICODE_SOURCE +__colldb_t * +__colldb_create(const char *path, int mode) +{ + DBT key; + DBT value; + DB *db = NULL; + int error = 0; + uint32_t version = 0; + int flags = (O_RDWR | O_CREAT | O_TRUNC); + __colldb_t *colldb = NULL; + + colldb = calloc(1, sizeof(*colldb)); + if (colldb == NULL) + { + errno = ENOMEM; + return (NULL); + } + db = dbopen(path, flags, mode, DB_HASH, NULL); + if (db == NULL) + { + error = errno; + free(colldb); + errno = error; + return (NULL); + } + colldb->version = __COLLATION_VERSION; + + key.data = "TYPE"; + value.data = "COLLATION"; + key.size = (strlen("TYPE") + 1); + value.size = (strlen("COLLATION") + 1); + if (db->put(db, &key, &value, 0) == -1) + { + error = errno; + goto failure; + } + + key.data = "VERSION"; + version = htonl(colldb->version); + value.data = &version; + key.size = (strlen("VERSION") + 1); + value.size = sizeof(colldb->version); + if (db->put(db, &key, &value, 0) == -1) + { + error = errno; + goto failure; + } + + colldb->handle = db; + return (colldb); + +failure: + (void) db->close(db); + free(colldb); + errno = error; + return (NULL); +} + + +__colldb_t * +__colldb_open(const char *path) +{ + DBT key; + DBT value; + DB *db = NULL; + int error = 0; + int state = 0; + int flags = O_RDONLY; + __colldb_t *colldb = NULL; + + colldb = calloc(1, sizeof(*colldb)); + if (colldb == NULL) + { + errno = ENOMEM; + return (NULL); + } + db = dbopen(path, flags, 0, DB_HASH, NULL); + if (db == NULL) + { + error = errno; + free(colldb); + errno = error; + return (NULL); + } + + key.data = "TYPE"; + key.size = (strlen("TYPE") + 1); + state = db->get(db, &key, &value, 0); + if (state != 0) + { + if (state < 0) + error = errno; + else + error = EFTYPE; + goto failure; + } + if (strcmp(value.data, "COLLATION") != 0) + { + error = EFTYPE; + goto failure; + } + + key.data = "VERSION"; + key.size = (strlen("VERSION") + 1); + state = db->get(db, &key, &value, 0); + if (state != 0) + { + if (state < 0) + error = errno; + else + error = EFTYPE; + goto failure; + } + colldb->version = ntohl(*(const uint32_t*)value.data); + + colldb->handle = db; + return (colldb); + +failure: + (void) db->close(db); + free(colldb); + errno = error; + return (NULL); +} + + +int +__colldb_close(__colldb_t *colldb) +{ + DB *db = NULL; + int error = 0; + + if (colldb == NULL) + { + errno = EINVAL; + return (-1); + } + db = colldb->handle; + if (db == NULL) + { + errno = EINVAL; + return (-1); + } + if (db->close(db) == -1) + { + error = errno; + free(colldb); + errno = error; + return (-1); + } + free(colldb); + return (0); +} + + +int +__colldb_sync(__colldb_t *colldb) +{ + DB *db = NULL; + + if (colldb == NULL) + { + errno = EINVAL; + return (-1); + } + db = colldb->handle; + if (db == NULL) + { + errno = EINVAL; + return (-1); + } + return db->sync(db, 0); +} + + +int +__colldb_get(__colldb_t *colldb, + struct __colldb_key *key, + struct __colldb_value *value) +{ + DBT dbkey; + DBT dbvalue; + DB *db = NULL; + size_t i = 0; + int state = 0; + uint32_t *keybuf = NULL; + struct __colldb_weight *weights = NULL; + + if ((colldb == NULL) || (key == NULL) || (value == NULL)) + { + errno = EINVAL; + return (-1); + } + db = colldb->handle; + if ((db == NULL) || (key->chars == NULL) || (key->count == 0)) + { + errno = EINVAL; + return (-1); + } + + keybuf = key->chars; + if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + { + keybuf = malloc(key->count * sizeof(*key->chars)); + if (keybuf == NULL) + { + errno = ENOMEM; + return (-1); + } + for (i = 0; i < key->count; ++i) + keybuf[i] = htonl(key->chars[i]); + } + + dbkey.data = keybuf; + dbkey.size = (key->count * sizeof(*key->chars)); + state = db->get(db, &dbkey, &dbvalue, 0); + if (state != 0) + return (state); + + weights = dbvalue.data; + if ((dbvalue.size / sizeof(*weights)) > value->count) + { + if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + free(keybuf); + errno = ERANGE; + return (-1); + } + value->count = (dbvalue.size / sizeof(*weights)); + for (i = 0; i < value->count; ++i) + { + value->weights[i].alternate = weights[i].alternate; + value->weights[i].level1 = ntohl(weights[i].level1); + value->weights[i].level2 = ntohl(weights[i].level2); + value->weights[i].level3 = ntohl(weights[i].level3); + value->weights[i].level4 = ntohl(weights[i].level4); + } + if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + free(keybuf); + return (0); +} + + +int +__colldb_put(__colldb_t *colldb, + struct __colldb_key *key, + struct __colldb_value *value) +{ + DBT dbkey; + DBT dbvalue; + DB *db = NULL; + size_t i = 0; + int state = 0; + int error = 0; + uint32_t *keybuf = NULL; + struct __colldb_weight *valuebuf = NULL; + + if ((colldb == NULL) || (key == NULL) || (value == NULL)) + { + errno = EINVAL; + return (-1); + } + db = colldb->handle; + if ((db == NULL) || (key->chars == NULL) || (key->count == 0)) + { + errno = EINVAL; + return (-1); + } + + keybuf = key->chars; + valuebuf = value->weights; + if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + { + keybuf = malloc(key->count * sizeof(*key->chars)); + valuebuf = malloc(value->count * sizeof(*value->weights)); + if ((keybuf == NULL) || (valuebuf == NULL)) + { + errno = ENOMEM; + return (-1); + } + for (i = 0; i < key->count; ++i) + keybuf[i] = htonl(key->chars[i]); + for (i = 0; i < value->count; ++i) + { + valuebuf[i].alternate = value->weights[i].alternate; + valuebuf[i].level1 = htonl(value->weights[i].level1); + valuebuf[i].level2 = htonl(value->weights[i].level2); + valuebuf[i].level3 = htonl(value->weights[i].level3); + valuebuf[i].level4 = htonl(value->weights[i].level4); + } + } + + dbkey.data = keybuf; + dbvalue.data = valuebuf; + dbkey.size = (key->count * sizeof(*key->chars)); + dbvalue.size = (value->count * sizeof(*value->weights)); + state = db->put(db, &dbkey, &dbvalue, 0); + if (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__) + { + error = errno; + free(keybuf); + free(valuebuf); + errno = error; + } + return state; +} +#endif + + /* * To avoid modifying the original (single-threaded) code too much, we'll just * define the old globals as fields inside the table. Modified: soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h ============================================================================== --- soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/locale/xlocale_private.h Fri Aug 8 00:20:09 2014 (r272063) @@ -42,7 +42,6 @@ #ifdef _UNICODE_SOURCE -#include <colldb.h> #include <stdint.h> #include <unistd.h> @@ -57,8 +56,39 @@ #define __UC_NFKC 4 size_t __ucsnorm(uint32_t*, const uint32_t*, size_t, int); -size_t __ucsxfrm(uint32_t*, const uint32_t*, size_t, struct __collation*); -int __ucscoll(const uint32_t*, const uint32_t*, struct __collation*); +#define COLLDB_VERSION 0x00000001 +#define COLLDB_WEIGHTS_MAX 10 +struct __colldb_weight { + uint8_t alternate; + uint32_t level1; + uint32_t level2; + uint32_t level3; + uint32_t level4; +}; +struct __colldb_key { + size_t count; + uint32_t *chars; +}; +struct __colldb_value { + size_t count; + struct __colldb_weight *weights; +}; +typedef struct __colldb __colldb_t; +#define __colldb_root (__colldb_root_handle()) + +__colldb_t* __colldb_create(const char*, int mode); +__colldb_t* __colldb_open(const char*); +int __colldb_close(__colldb_t*); +int __colldb_sync(__colldb_t*); +int __colldb_get(__colldb_t*, + struct __colldb_key*, + struct __colldb_value*); +int __colldb_put(__colldb_t*, + struct __colldb_key*, + struct __colldb_value*); + +size_t __ucsxfrm(uint32_t*, const uint32_t*, size_t, const __colldb_t*); +int __ucscoll(const uint32_t*, const uint32_t*, const __colldb_t*); #endif Modified: soc2014/ghostmansd/head/lib/libc/string/wcscoll.c ============================================================================== --- soc2014/ghostmansd/head/lib/libc/string/wcscoll.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/string/wcscoll.c Fri Aug 8 00:20:09 2014 (r272063) @@ -70,11 +70,8 @@ #ifdef _UNICODE_SOURCE const uint32_t *ucs1 = (const uint32_t*)ws1; const uint32_t *ucs2 = (const uint32_t*)ws2; - const struct __collation *colltable = - (const struct __collation*)locale->colltable; - size_t collsize = locale->collsize; - return __ucscoll(ucs1, ucs2, colltable, collsize); + return __ucscoll(ucs1, ucs2, locale->colldb); #else /* !_UNICODE_SOURCE */ char *mbs1, *mbs2; Modified: soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c ============================================================================== --- soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/string/wcsxfrm.c Fri Aug 8 00:20:09 2014 (r272063) @@ -50,11 +50,8 @@ #ifdef _UNICODE_SOURCE uint32_t *udst = (uint32_t*)dest; const uint32_t *usrc = (const uint32_t*)src; - const struct __collation *colltable = - (const struct __collation*)locale->colltable; - size_t collsize = locale->collsize; - return __ucsxfrm(udst, usrc, len, colltable, collsize); + return __ucsxfrm(udst, usrc, len, locale->colldb); #else int prim, sec, l; size_t slen; Added: soc2014/ghostmansd/head/lib/libc/unicode/coll.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2014/ghostmansd/head/lib/libc/unicode/coll.h Fri Aug 8 00:20:09 2014 (r272063) @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 2014 Dmitry Selyutin. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DECOMPOSITION, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <pthread.h> +#include "xlocale_private.h" +static __colldb_t *handle = NULL; +static pthread_once_t once = PTHREAD_ONCE_INIT; + + +static __colldb_t +__colldb_root_init(void) +{ + handle = __colldb_open("/usr/share/colldb/root.db"); +} + + +__colldb_t * +__colldb_root_handle(void) +{ + pthread_once(&once, &__colldb_root_init); + return handle; +} + + +static size_t +__coll_iter(const uint32_t *iter, __colldb_t *colldb, struct __colldb_value *val, + struct __colldb_weight *default_weights[2]) +{ + int state = 0; + size_t shift = 0; + struct __colldb_key key; + + for (shift = 1; shift != 18; ++shift) + { + if (*(iter + shift - 1) == 0) + break; + key.count = shift; + key.chars = norm; + state = __colldb_get(colldb, &key, val); + if (state == -1) + return (0); + if (state == 0) + break; + } + + if ((state != 0) && (colldb != __colldb_root)) + { + for (shift = 1; shift != 18; ++shift) + { + if (*(iter + shift - 1) == 0) + break; + key.count = shift; + key.chars = norm; + state = __colldb_get(__colldb_root, &key, val); + if (state == -1) + return (0); + if (state == 0) + break; + } + } + + if (state != 0) + { + shift = 1; + (*default_weights)[0].level1 = 0xFBC0; + if (((0x4E00 <= *iter) && (*iter <= 0x9FCC)) || + (*iter == 0xFA0E) || (*iter == 0xFA0F) || + (*iter == 0xFA11) || (*iter == 0xFA13) || + (*iter == 0xFA14) || (*iter == 0xFA1F) || + (*iter == 0xFA21) || (*iter == 0xFA23) || + (*iter == 0xFA24) || (*iter == 0xFA27) || + (*iter == 0xFA28) || (*iter == 0xFA29)) + (*default_weights)[0].level1 = 0xFB40; + else if (((0x3400 <= *iter) && (*iter <= 0x4DB5)) || + ((0x20000 <= *iter) && (*iter <= 0x2A6D6)) || + ((0x2A700 <= *iter) && (*iter <= 0x2B734)) || + ((0x2B740 <= *iter) && (*iter <= 0x2B81D))) + (*default_weights)[0].level1 = 0xFB80; + (*default_weights)[0].level1 = ((*default_weights)[0].level1 + (*iter >> 15)); + (*default_weights)[1].level1 = ((*iter & 0x7FFF) | 0x8000); + val->weights = *default_weights; + val->count = 2; + } + + return (shift); +} Modified: soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c ============================================================================== --- soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/unicode/ucscoll.c Fri Aug 8 00:20:09 2014 (r272063) @@ -30,33 +30,96 @@ int -__ucscoll(const uint32_t *lhs, const uint32_t *rhs, - const struct __collation_data *colldata, size_t collsize) +__ucscoll(const uint32_t *lstr, const uint32_t *rstr, __colldb_t *colldb) { + int cmp = 0; + size_t i = 0; + int state = 0; int error = 0; - int result = 0; - size_t lsize = 0; - size_t rsize = 0; - uint32_t *lcoll = NULL; - uint32_t *rcoll = NULL; + size_t index = 0; + size_t size[2] = {0, 0}; + size_t count[2] = {0, 0}; + struct __colldb_value val[2]; + uint32_t (*str)[2] = {NULL, NULL}; + uint32_t (*norm)[2] = {NULL, NULL}; + uint32_t (*iter)[2] = {NULL, NULL}; + struct __colldb_weight default_weights[2][2]; + struct __colldb_weight weights[2][__COLLATION_WEIGHTS_MAX]; + const int init_error = errno; - error = errno; - lsize = __ucsxfrm(NULL, lhs, 0, colldata, collsize); - rsize = __ucsxfrm(NULL, rhs, 0, colldata, collsize); - errno = error; - lcoll = malloc(lsize * sizeof(uint32_t)); - rcoll = malloc(rsize * sizeof(uint32_t)); - if ((lcoll == NULL) || (rcoll == NULL)) + if ((lstr == NULL) || (rstr == NULL)) { - free(lcoll); - free(rcoll); - errno = ENOMEM; + errno = EINVAL; return (0); } - result = wcscmp((const wchar_t*)lcoll, (const wchar_t*)rcoll); - error = errno; - free(lcoll); - free(rcoll); - errno = error; - return (result); + for (i = 0; i < 2; ++i) + { + size[i] = __ucsnorm(NULL, str[i], 0, __UC_NFD); + norm[i] = malloc(size[i] * sizeof(uint32_t)); + if (__ucsnorm(norm[i], str[i], size[i], __UC_NFD) > lsize) + { + error = errno; + free(norm[0]); + free(norm[1]); + errno = error; + return (0); + } + iter[i] = norm[i]; + } + memset(generic, 0, sizeof(generic)); + generic[0].level2 = 0x20; + generic[0].level3 = 0x02; + generic[1].level2 = 0x02; + generic[1].level3 = 0x01; + + if (colldb == NULL) + colldb = __colldb_root; + while (*iter[0] != 0) + { + if (*iter[1] == 0) + { + free(norm[0]); + free(norm[1]); + return (+1); + } + for (i = 0; i < 2; ++i) + { + val[i].weights = weights[i]; + val[i].count = __COLLATION_WEIGHTS_MAX; + shift = __coll_iter(iter[0], colldb, &val[i], + &default_weights[i]); + if (shift == 0) + { + error = errno; + free(norm[0]); + free(norm[1]); + errno = error; + return (0); + } + } + iter[i] += shift; + if (val[0].count < val[1].count) + cmp = val[0].count; + else + cmp = val[1].count; + for (i = 0; i < cmp; ++i) + { + state = memcmp(val[0].weights[i], val[1].weights[i], + sizeof(struct __colldb_weight)); + if (state != 0) + { + free(norm[0]); + free(norm[1]); + errno = init_error; + return (state); + } + } + if (val[0].count < val[1].count) + state = -1; + else if (val[0].count > val[1].count) + state = +1; + } + if (*iter[1] != 0) + return (-1); + return (0); } Modified: soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c ============================================================================== --- soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libc/unicode/ucsxfrm.c Fri Aug 8 00:20:09 2014 (r272063) @@ -26,159 +26,96 @@ #include <errno.h> #include <string.h> -#include "xlocale_private.h" +#include "coll.h" size_t -__ucsxfrm(uint32_t *buffer, const uint32_t *str, size_t size, - const struct __collation *colldata, size_t collsize) +__ucsxfrm(uint32_t *buffer, const uint32_t *str, size_t size, __colldb_t *colldb) { + size_t i = 0; + int state = 0; int error = 0; - size_t mid = 0; - size_t low = 0; - size_t high = 0; - size_t count = 0; size_t shift = 0; - uint32_t hash = 0; + size_t count = 0; size_t reqsize = 0; - size_t normsize = 0; - uint32_t *normstr = NULL; - const uint32_t *iter = str; + uint32_t *iter = NULL; + uint32_t *elements = NULL; + struct __colldb_value value; + struct __colldb_weight default_weights[2]; + struct __colldb_weight weights[__COLLATION_WEIGHTS_MAX]; const int init_error = errno; - const uint32_t *elements = NULL; - size_t seqmax = 18; /* maximal decomposition length */ - uint32_t generic[6] = {0x00, 0x00, 0x20, 0x01, 0x02, 0x01}; if ((str == NULL) || ((buffer != NULL) && (size == 0))) { errno = EINVAL; - return 0; - } - if (colldata == NULL) - { - colldata = __DUCET_COLLDATA; - collsize = __DUCET_COLLSIZE; - seqmax = 3; /* max DUCET sequence length */ + return (SIZE_MAX); } - error = errno; normsize = __ucsnorm(NULL, str, 0, __UC_NFD); - errno = error; - normstr = malloc(normsize * sizeof(uint32_t)); - if (normstr == NULL) + norm = malloc(normsize * sizeof(uint32_t)); + if (norm == NULL) { errno = ENOMEM; return (SIZE_MAX); } - if (__ucsnorm(normstr, str, normsize, __UC_NFD) > normsize) + if (__ucsnorm(norm, str, normsize, __UC_NFD) > normsize) { error = errno; - free(normstr); + free(norm); errno = error; return (SIZE_MAX); } - + memset(generic, 0, sizeof(generic)); + generic[0].level2 = 0x20; + generic[0].level3 = 0x02; + generic[1].level2 = 0x02; + generic[1].level3 = 0x01; + memset(match, 0, sizeof(match)); + + iter = norm; + if (colldb == NULL) + colldb = __colldb_root; while (*iter != 0) { - - /* - * Try to determine if collation table contains a sequence - * which consists from 1 to 18 characters. - * If DUCET is used, maximal count of characters is 3. - */ - for (shift = 1; shift != seqmax; ++shift) + value.weights = weights; + value.count = __COLLATION_WEIGHTS_MAX; + shift = __coll_iter(iter, colldb, &value, &default_weights); + if (shift == 0) { - low = 0; - elements = NULL; - high = collsize; - if (*(iter + shift - 1) == 0) - break; - hash = __uchash(iter, shift); - while (low <= high) - { - mid = (low + ((high - low) / 2)); - if (hash < colldata[mid].hash) - high = (mid - 1); - else if (hash > colldata[mid].hash) - low = (mid + 1); - else - { - count = colldata[mid].count; - elements = colldata[mid].elements; - break; - } - } - if (elements != NULL) - break; + error = errno; + free(elements); + free(norm); + errno = error; + return (SIZE_MAX); } - /* - * If collation table does not contain a sequence and - * current collation table is not DUCET, repeat the algorithm - * for DUCET with limit up to 3 characters. - */ - if ((elements == NULL) && (colldata != __DUCET_COLLDATA)) + free(elements); + count = (value.count * 4); + elements = malloc(count * sizeof(uint32_t)); + if (elements == NULL) { - for (shift = 1; shift != 3; ++shift) - { - low = 0; - elements = NULL; - collsize = __DUCET_COLLSIZE; - if (*(iter + shift - 1) == 0) - break; - hash = __uchash(iter, shift); - while (low <= high) - { - mid = (low + ((high - low) / 2)); - if (hash < __DUCET_COLLDATA[mid].hash) - high = (mid - 1); - else if (hash > __DUCET_COLLDATA[mid].hash) - low = (mid + 1); - else - { - count = __DUCET_COLLDATA[mid].count; - elements = __DUCET_COLLDATA[mid].elements; - break; - } - } - if (elements != NULL) - break; - } + free(elements); + free(norm); + errno = ENOMEM; + return (SIZE_MAX); } - - /* If no sequence was matched, generate default collation. */ - if (elements == NULL) + for (i = 0; i < value.count; ++i) { - shift = 1; - generic[0] = 0xFBC0; - if (((0x4E00 <= *str) && (*str <= 0x9FCC)) || - (*str == 0xFA0E) || (*str == 0xFA0F) || - (*str == 0xFA11) || (*str == 0xFA13) || - (*str == 0xFA14) || (*str == 0xFA1F) || - (*str == 0xFA21) || (*str == 0xFA23) || - (*str == 0xFA24) || (*str == 0xFA27) || - (*str == 0xFA28) || (*str == 0xFA29)) - generic[0] = 0xFB40; - else if (((0x3400 <= *str) && (*str <= 0x4DB5)) || - ((0x20000 <= *str) && (*str <= 0x2A6D6)) || - ((0x2A700 <= *str) && (*str <= 0x2B734)) || - ((0x2B740 <= *str) && (*str <= 0x2B81D))) - generic[0] = 0xFB80; - generic[0] = (generic[0] + (*str >> 15)); - generic[1] = ((*str & 0x7FFF) | 0x8000); - elements = generic; - count = 6; + elements[(count * 0) + i] = value.weights[i].level1; + elements[(count * 1) + i] = value.weights[i].level2; + elements[(count * 2) + i] = value.weights[i].level3; + elements[(count * 3) + i] = value.weights[i].level4; } - else - count *= 3; + for (i = 0; i < count; ++i) + elements[i] = (elements[i] ? elements[i] : 1); - /* Write found or generated sequence into the buffer. */ if (((reqsize + count) > size) && (buffer != NULL)) { - size = (size - reqsize - 1); - memcpy(buffer, elements, (size * sizeof(uint32_t))); - *(buffer + size) = 0; - free(normstr); - return __ucsxfrm(NULL, str, 0, colldata, collsize); + count = (size - reqsize - 1); + memcpy(buffer, elements, (count * sizeof(uint32_t))); + *(buffer + count) = 0; + free(elements); + free(norm); + return __ucsxfrm(NULL, str, 0, colldb); } if (buffer != NULL) { @@ -186,13 +123,14 @@ buffer += count; } reqsize += count; + iter += shift; } if (buffer == NULL) ++reqsize; else *buffer = 0; - free(normstr); + free(norm); errno = init_error; return (reqsize); } Modified: soc2014/ghostmansd/head/lib/libcolldb/colldb.c ============================================================================== --- soc2014/ghostmansd/head/lib/libcolldb/colldb.c Thu Aug 7 22:14:37 2014 (r272062) +++ soc2014/ghostmansd/head/lib/libcolldb/colldb.c Fri Aug 8 00:20:09 2014 (r272063) @@ -30,8 +30,8 @@ #include "colldb.h" -struct collation * -collation_create(const char *path, int mode) +colldb_t * +colldb_create(const char *path, int mode) { DBT key; DBT value; @@ -39,10 +39,10 @@ int error = 0; uint32_t version = 0; int flags = (O_RDWR | O_CREAT | O_TRUNC); - struct collation *collation = NULL; + colldb_t *colldb = NULL; - collation = calloc(1, sizeof(*collation)); - if (collation == NULL) + colldb = calloc(1, sizeof(*colldb)); + if (colldb == NULL) { errno = ENOMEM; return (NULL); @@ -51,11 +51,11 @@ if (db == NULL) { error = errno; - free(collation); + free(colldb); errno = error; return (NULL); } - collation->version = __COLLATION_VERSION; + colldb->version = __COLLATION_VERSION; key.data = "TYPE"; value.data = "COLLATION"; @@ -68,29 +68,29 @@ } key.data = "VERSION"; - version = htonl(collation->version); + version = htonl(colldb->version); value.data = &version; key.size = (strlen("VERSION") + 1); - value.size = sizeof(collation->version); + value.size = sizeof(colldb->version); if (db->put(db, &key, &value, 0) == -1) { error = errno; goto failure; } - collation->handle = db; - return (collation); + colldb->handle = db; + return (colldb); failure: (void) db->close(db); - free(collation); + free(colldb); errno = error; return (NULL); } -struct collation * -collation_open(const char *path) +colldb_t * +colldb_open(const char *path) { DBT key; DBT value; @@ -98,10 +98,10 @@ int error = 0; int state = 0; int flags = O_RDONLY; - struct collation *collation = NULL; + colldb_t *colldb = NULL; - collation = calloc(1, sizeof(*collation)); - if (collation == NULL) + colldb = calloc(1, sizeof(*colldb)); + if (colldb == NULL) { errno = ENOMEM; return (NULL); @@ -110,7 +110,7 @@ if (db == NULL) { error = errno; - free(collation); + free(colldb); errno = error; return (NULL); } @@ -143,31 +143,31 @@ error = EFTYPE; goto failure; } - collation->version = ntohl(*(const uint32_t*)value.data); + colldb->version = ntohl(*(const uint32_t*)value.data); - collation->handle = db; - return (collation); + colldb->handle = db; + return (colldb); failure: (void) db->close(db); - free(collation); + free(colldb); errno = error; return (NULL); } int -collation_close(struct collation *collation) +colldb_close(colldb_t *colldb) { DB *db = NULL; int error = 0; - if (collation == NULL) + if (colldb == NULL) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408080020.s780K9Z7063066>
