Import proplib-0.6.1.

This commit is contained in:
Juan RP
2012-07-10 23:33:19 +02:00
parent 34697e8022
commit 11ecf5438f
18 changed files with 2101 additions and 1459 deletions

View File

@@ -1,29 +1,4 @@
/* $NetBSD: prop_dictionary.c,v 1.33 2008/11/30 00:17:07 haad Exp $ */
/*-
* Copyright (c) 2010 Juan Romero Pardines (zlib/gzip support).
* 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 ``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 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,
* DATA, 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.
*/
/* $NetBSD: prop_dictionary.c,v 1.37 2011/04/20 19:40:00 martin Exp $ */
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
@@ -54,12 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/proplib.h>
#include <prop/prop_array.h>
#include <prop/prop_dictionary.h>
#include <prop/prop_string.h>
#include "prop_object_impl.h"
#include "prop_rb_impl.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h>
#include <zlib.h>
#define __unused /* empty */
#endif
/*
* We implement these like arrays, but we keep them sorted by key.
@@ -88,10 +67,6 @@ struct _prop_dictionary_keysym {
/* actually variable length */
};
#define RBNODE_TO_PDK(n) \
((struct _prop_dictionary_keysym *) \
((uintptr_t)n - offsetof(struct _prop_dictionary_keysym, pdk_link)))
/* pdk_key[1] takes care of the NUL */
#define PDK_SIZE_16 (sizeof(struct _prop_dictionary_keysym) + 16)
#define PDK_SIZE_32 (sizeof(struct _prop_dictionary_keysym) + 32)
@@ -198,35 +173,49 @@ struct _prop_dictionary_iterator {
*/
static int
_prop_dict_keysym_rb_compare_nodes(const struct rb_node *n1,
const struct rb_node *n2)
/*ARGSUSED*/
_prop_dict_keysym_rb_compare_nodes(void *ctx __unused,
const void *n1, const void *n2)
{
const prop_dictionary_keysym_t pdk1 = RBNODE_TO_PDK(n1);
const prop_dictionary_keysym_t pdk2 = RBNODE_TO_PDK(n2);
const struct _prop_dictionary_keysym *pdk1 = n1;
const struct _prop_dictionary_keysym *pdk2 = n2;
return (strcmp(pdk1->pdk_key, pdk2->pdk_key));
return strcmp(pdk1->pdk_key, pdk2->pdk_key);
}
static int
_prop_dict_keysym_rb_compare_key(const struct rb_node *n,
const void *v)
/*ARGSUSED*/
_prop_dict_keysym_rb_compare_key(void *ctx __unused,
const void *n, const void *v)
{
const prop_dictionary_keysym_t pdk = RBNODE_TO_PDK(n);
const struct _prop_dictionary_keysym *pdk = n;
const char *cp = v;
return (strcmp(pdk->pdk_key, cp));
return strcmp(pdk->pdk_key, cp);
}
static const struct rb_tree_ops _prop_dict_keysym_rb_tree_ops = {
static const rb_tree_ops_t _prop_dict_keysym_rb_tree_ops = {
.rbto_compare_nodes = _prop_dict_keysym_rb_compare_nodes,
.rbto_compare_key = _prop_dict_keysym_rb_compare_key,
.rbto_compare_key = _prop_dict_keysym_rb_compare_key,
.rbto_node_offset = offsetof(struct _prop_dictionary_keysym, pdk_link),
.rbto_context = NULL
};
static struct rb_tree _prop_dict_keysym_tree;
static bool _prop_dict_keysym_tree_initialized;
_PROP_ONCE_DECL(_prop_dict_init_once)
_PROP_MUTEX_DECL_STATIC(_prop_dict_keysym_tree_mutex)
static int
_prop_dict_init(void)
{
_PROP_MUTEX_INIT(_prop_dict_keysym_tree_mutex);
_prop_rb_tree_init(&_prop_dict_keysym_tree,
&_prop_dict_keysym_rb_tree_ops);
return 0;
}
static void
_prop_dict_keysym_put(prop_dictionary_keysym_t pdk)
{
@@ -247,7 +236,7 @@ _prop_dict_keysym_free(prop_stack_t stack, prop_object_t *obj)
{
prop_dictionary_keysym_t pdk = *obj;
_prop_rb_tree_remove_node(&_prop_dict_keysym_tree, &pdk->pdk_link);
_prop_rb_tree_remove_node(&_prop_dict_keysym_tree, pdk);
_prop_dict_keysym_put(pdk);
return _PROP_OBJECT_FREE_DONE;
@@ -294,28 +283,21 @@ _prop_dict_keysym_equals(prop_object_t v1, prop_object_t v2,
static prop_dictionary_keysym_t
_prop_dict_keysym_alloc(const char *key)
{
prop_dictionary_keysym_t opdk, pdk;
const struct rb_node *n;
prop_dictionary_keysym_t opdk, pdk, rpdk;
size_t size;
bool rv;
_PROP_ONCE_RUN(_prop_dict_init_once, _prop_dict_init);
/*
* Check to see if this already exists in the tree. If it does,
* we just retain it and return it.
*/
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
if (! _prop_dict_keysym_tree_initialized) {
_prop_rb_tree_init(&_prop_dict_keysym_tree,
&_prop_dict_keysym_rb_tree_ops);
_prop_dict_keysym_tree_initialized = true;
} else {
n = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (n != NULL) {
opdk = RBNODE_TO_PDK(n);
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (opdk);
}
opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (opdk != NULL) {
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (opdk);
}
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
@@ -347,16 +329,15 @@ _prop_dict_keysym_alloc(const char *key)
* we have to check again if it is in the tree.
*/
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
n = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (n != NULL) {
opdk = RBNODE_TO_PDK(n);
opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (opdk != NULL) {
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
_prop_dict_keysym_put(pdk);
return (opdk);
}
rv = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, &pdk->pdk_link);
_PROP_ASSERT(rv == true);
rpdk = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, pdk);
_PROP_ASSERT(rpdk == pdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (pdk);
}
@@ -416,6 +397,9 @@ _prop_dictionary_free(prop_stack_t stack, prop_object_t *obj)
static void
_prop_dictionary_lock(void)
{
/* XXX: once necessary or paranoia? */
_PROP_ONCE_RUN(_prop_dict_init_once, _prop_dict_init);
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
}
@@ -540,8 +524,8 @@ _prop_dictionary_equals(prop_object_t v1, prop_object_t v2,
*stored_pointer1 = (void *)(idx + 1);
*stored_pointer2 = (void *)(idx + 1);
*next_obj1 = &dict1->pd_array[idx].pde_objref;
*next_obj2 = &dict2->pd_array[idx].pde_objref;
*next_obj1 = dict1->pd_array[idx].pde_objref;
*next_obj2 = dict2->pd_array[idx].pde_objref;
if (!prop_dictionary_keysym_equals(dict1->pd_array[idx].pde_key,
dict2->pd_array[idx].pde_key))
@@ -645,7 +629,7 @@ static prop_object_t
_prop_dictionary_iterator_next_object(void *v)
{
struct _prop_dictionary_iterator *pdi = v;
prop_dictionary_t pd = pdi->pdi_base.pi_obj;
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
prop_dictionary_keysym_t pdk;
_PROP_ASSERT(prop_object_is_dictionary(pd));
@@ -672,7 +656,7 @@ static void
_prop_dictionary_iterator_reset(void *v)
{
struct _prop_dictionary_iterator *pdi = v;
prop_dictionary_t pd = pdi->pdi_base.pi_obj;
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
_PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
_prop_dictionary_iterator_reset_locked(pdi);
@@ -949,7 +933,10 @@ _prop_dictionary_get(prop_dictionary_t pd, const char *key, bool locked)
prop_object_t
prop_dictionary_get(prop_dictionary_t pd, const char *key)
{
prop_object_t po;
prop_object_t po = NULL;
if (! prop_object_is_dictionary(pd))
return (NULL);
_PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
po = _prop_dictionary_get(pd, key, true);
@@ -1388,6 +1375,7 @@ prop_dictionary_internalize(const char *xml)
return _prop_generic_internalize(xml, "dict");
}
#if !defined(_KERNEL) && !defined(_STANDALONE)
/*
* prop_dictionary_externalize_to_file --
* Externalize a dictionary to the specified file.
@@ -1402,8 +1390,8 @@ prop_dictionary_externalize_to_file(prop_dictionary_t dict, const char *fname)
xml = prop_dictionary_externalize(dict);
if (xml == NULL)
return (false);
rv = _prop_object_externalize_write_file(fname, xml,
strlen(xml), false);
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml),
false);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
@@ -1413,31 +1401,6 @@ prop_dictionary_externalize_to_file(prop_dictionary_t dict, const char *fname)
return (rv);
}
/*
* prop_dictionary_externalize_to_zfile ---
* Externalize a dictionary to the specified file and on the fly
* compressing the result with gzip (via zlib).
*/
bool
prop_dictionary_externalize_to_zfile(prop_dictionary_t dict, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0;
xml = prop_dictionary_externalize(dict);
if (xml == NULL)
return false;
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
if (rv == false)
errno = save_errno;
return rv;
}
/*
* prop_dictionary_internalize_from_file --
* Internalize a dictionary from a file.
@@ -1456,87 +1419,4 @@ prop_dictionary_internalize_from_file(const char *fname)
return (dict);
}
#define _READ_CHUNK 512
/*
* prop_dictionary_internalize_from_zfile ---
* Internalize a dictionary from a compressed gzip file.
*/
prop_dictionary_t
prop_dictionary_internalize_from_zfile(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_dictionary_t dict;
z_stream strm;
unsigned char out[_READ_CHUNK];
char *uncomp_xml = NULL;
size_t have;
ssize_t totalsize = 0;
int rv = 0;
mf = _prop_object_internalize_map_file(fname);
if (mf == NULL)
return NULL;
/* Decompress the mmap'ed buffer with zlib */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
/* 15+16 to use gzip method */
if (inflateInit2(&strm, 15+16) != Z_OK) {
_prop_object_internalize_unmap_file(mf);
return NULL;
}
strm.avail_in = mf->poimf_mapsize;
strm.next_in = (unsigned char *)mf->poimf_xml;
/* Output buffer (uncompressed) */
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP);
if (uncomp_xml == NULL) {
(void)inflateEnd(&strm);
_prop_object_internalize_unmap_file(mf);
return NULL;
}
/* Inflate the input buffer and copy into 'uncomp_xml' */
do {
strm.avail_out = _READ_CHUNK;
strm.next_out = out;
rv = inflate(&strm, Z_NO_FLUSH);
switch (rv) {
case Z_DATA_ERROR:
/*
* Wrong compressed data or uncompressed, try
* normal method as last resort.
*/
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
dict = prop_dictionary_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return dict;
case Z_STREAM_ERROR:
case Z_NEED_DICT:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
errno = rv;
return NULL;
}
have = _READ_CHUNK - strm.avail_out;
totalsize += have;
uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP);
memcpy(uncomp_xml + totalsize - have, out, have);
} while (strm.avail_out == 0);
/* we are done */
(void)inflateEnd(&strm);
dict = prop_dictionary_internalize(uncomp_xml);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
return dict;
}
#endif /* !_KERNEL && !_STANDALONE */