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

@ -17,5 +17,5 @@ internal use in the code:
- libfetch-2.31 from NetBSD: lib/fetch - libfetch-2.31 from NetBSD: lib/fetch
- portableproplib-0.4.1 (lib/portableproplib) from - portableproplib-0.6.1 (lib/portableproplib) from
http://code.google.com/p/portableproplib http://code.google.com/p/portableproplib

2
NEWS
View File

@ -1,5 +1,7 @@
xbps-0.16.4 (???): xbps-0.16.4 (???):
* Imported proplib 0.6.1 from http://code.google.com/p/portableproplib.
* libxbps: when finding obsolete files also match against sha256, not * libxbps: when finding obsolete files also match against sha256, not
just the filename. Also ignore symlinks found in rootfs to make just the filename. Also ignore symlinks found in rootfs to make
the system transition to /usr fully work. the system transition to /usr fully work.

View File

@ -9,10 +9,10 @@ LDFLAGS += $(LIBXBPS_LDFLAGS) -shared -Wl,-soname,libxbps.so.$(LIBXBPS_MAJOR)
# portableproplib # portableproplib
LIBPROP_OBJS = portableproplib/prop_array.o portableproplib/prop_bool.o LIBPROP_OBJS = portableproplib/prop_array.o portableproplib/prop_bool.o
LIBPROP_OBJS += portableproplib/prop_dictionary.o portableproplib/prop_ingest.o LIBPROP_OBJS += portableproplib/prop_dictionary.o portableproplib/prop_ingest.o
LIBPROP_OBJS += portableproplib/prop_object.o portableproplib/prop_rb.o LIBPROP_OBJS += portableproplib/prop_object.o portableproplib/rb.o
LIBPROP_OBJS += portableproplib/prop_stack.o portableproplib/prop_string.o LIBPROP_OBJS += portableproplib/prop_stack.o portableproplib/prop_string.o
LIBPROP_OBJS += portableproplib/prop_array_util.o portableproplib/prop_number.o LIBPROP_OBJS += portableproplib/prop_array_util.o portableproplib/prop_number.o
LIBPROP_OBJS += portableproplib/prop_dictionary_util.o LIBPROP_OBJS += portableproplib/prop_dictionary_util.o portableproplib/prop_zlib.o
LIBPROP_OBJS += portableproplib/prop_data.o LIBPROP_OBJS += portableproplib/prop_data.o
LIBPROP_CPPFLAGS = -D_GNU_SOURCE LIBPROP_CPPFLAGS = -D_GNU_SOURCE
LIBPROP_CFLAGS = -Wno-old-style-definition -Wno-cast-qual -Wno-unused-parameter LIBPROP_CFLAGS = -Wno-old-style-definition -Wno-cast-qual -Wno-unused-parameter

View File

@ -129,13 +129,16 @@ bool prop_array_get_cstring(prop_array_t, unsigned int,
char **); char **);
bool prop_array_set_cstring(prop_array_t, unsigned int, bool prop_array_set_cstring(prop_array_t, unsigned int,
const char *); const char *);
bool prop_array_add_cstring(prop_array_t, const char *);
bool prop_array_add_cstring_nocopy(prop_array_t,
const char *);
bool prop_array_get_cstring_nocopy(prop_array_t, bool prop_array_get_cstring_nocopy(prop_array_t,
unsigned int, unsigned int,
const char **); const char **);
bool prop_array_set_cstring_nocopy(prop_array_t, bool prop_array_set_cstring_nocopy(prop_array_t,
unsigned int, unsigned int,
const char *); const char *);
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
__END_DECLS __END_DECLS

View File

@ -90,6 +90,8 @@ bool prop_dictionary_keysym_equals(prop_dictionary_keysym_t,
* Utility routines to make it more convenient to work with values * Utility routines to make it more convenient to work with values
* stored in dictionaries. * stored in dictionaries.
*/ */
bool prop_dictionary_get_dict(prop_dictionary_t, const char *,
prop_dictionary_t *);
bool prop_dictionary_get_bool(prop_dictionary_t, const char *, bool prop_dictionary_get_bool(prop_dictionary_t, const char *,
bool *); bool *);
bool prop_dictionary_set_bool(prop_dictionary_t, const char *, bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
@ -142,6 +144,9 @@ bool prop_dictionary_get_cstring_nocopy(prop_dictionary_t,
bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t, bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
const char *, const char *,
const char *); const char *);
bool prop_dictionary_set_and_rel(prop_dictionary_t,
const char *,
prop_object_t);
__END_DECLS __END_DECLS

View File

@ -0,0 +1,210 @@
/* $NetBSD: rbtree.h,v 1.1 2010/09/25 01:42:40 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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, 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.
*/
#ifndef _SYS_RBTREE_H_
#define _SYS_RBTREE_H_
#if defined(_KERNEL) || defined(_STANDALONE)
#include <sys/types.h>
#else
#include <stdbool.h>
#include <inttypes.h>
#endif
#include <queue.h>
#if __GNUC_PREREQ(2, 96)
# ifndef __predict_true
# define __predict_true(exp) __builtin_expect((exp), 1)
# endif
# ifndef __predict_false
# define __predict_false(exp) __builtin_expect((exp), 0)
# endif
#else
# ifndef __predict_true
# define __predict_true(exp) (exp)
# endif
# ifndef __predict_false
# define __predict_false(exp) (exp)
# endif
#endif
__BEGIN_DECLS
typedef struct rb_node {
struct rb_node *rb_nodes[2];
#define RB_DIR_LEFT 0
#define RB_DIR_RIGHT 1
#define RB_DIR_OTHER 1
#define rb_left rb_nodes[RB_DIR_LEFT]
#define rb_right rb_nodes[RB_DIR_RIGHT]
/*
* rb_info contains the two flags and the parent back pointer.
* We put the two flags in the low two bits since we know that
* rb_node will have an alignment of 4 or 8 bytes.
*/
uintptr_t rb_info;
#define RB_FLAG_POSITION 0x2
#define RB_FLAG_RED 0x1
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
#define RB_FATHER(rb) \
((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
#define RB_SET_FATHER(rb, father) \
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
#define RB_SENTINEL_P(rb) ((rb) == NULL)
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
#define RB_CHILDLESS_P(rb) \
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
#define RB_TWOCHILDREN_P(rb) \
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
#define RB_POSITION(rb) \
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
#define RB_SET_POSITION(rb, position) \
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
((rb)->rb_info &= ~RB_FLAG_POSITION)))
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
#define RB_COPY_PROPERTIES(dst, src) \
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
#define RB_SWAP_PROPERTIES(a, b) do { \
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
(a)->rb_info ^= xorinfo; \
(b)->rb_info ^= xorinfo; \
} while (/*CONSTCOND*/ 0)
#ifdef RBDEBUG
TAILQ_ENTRY(rb_node) rb_link;
#endif
} rb_node_t;
#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT)
#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT)
#define RB_TREE_FOREACH(N, T) \
for ((N) = RB_TREE_MIN(T); (N); \
(N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT))
#define RB_TREE_FOREACH_REVERSE(N, T) \
for ((N) = RB_TREE_MAX(T); (N); \
(N) = rb_tree_iterate((T), (N), RB_DIR_LEFT))
#ifdef RBDEBUG
TAILQ_HEAD(rb_node_qh, rb_node);
#define RB_TAILQ_REMOVE(a, b, c) TAILQ_REMOVE(a, b, c)
#define RB_TAILQ_INIT(a) TAILQ_INIT(a)
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD(a, b, c)
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE(a, b, c)
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER(a, b, c, d)
#else
#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0)
#endif /* RBDEBUG */
/*
* rbto_compare_nodes_fn:
* return a positive value if the first node > the second node.
* return a negative value if the first node < the second node.
* return 0 if they are considered same.
*
* rbto_compare_key_fn:
* return a positive value if the node > the key.
* return a negative value if the node < the key.
* return 0 if they are considered same.
*/
typedef signed int (*const rbto_compare_nodes_fn)(void *,
const void *, const void *);
typedef signed int (*const rbto_compare_key_fn)(void *,
const void *, const void *);
typedef struct {
rbto_compare_nodes_fn rbto_compare_nodes;
rbto_compare_key_fn rbto_compare_key;
size_t rbto_node_offset;
void *rbto_context;
} rb_tree_ops_t;
typedef struct rb_tree {
struct rb_node *rbt_root;
const rb_tree_ops_t *rbt_ops;
struct rb_node *rbt_minmax[2];
#ifdef RBDEBUG
struct rb_node_qh rbt_nodes;
#endif
#ifdef RBSTATS
unsigned int rbt_count;
unsigned int rbt_insertions;
unsigned int rbt_removals;
unsigned int rbt_insertion_rebalance_calls;
unsigned int rbt_insertion_rebalance_passes;
unsigned int rbt_removal_rebalance_calls;
unsigned int rbt_removal_rebalance_passes;
#endif
} rb_tree_t;
#ifdef RBSTATS
#define RBSTAT_INC(v) ((void)((v)++))
#define RBSTAT_DEC(v) ((void)((v)--))
#else
#define RBSTAT_INC(v) do { } while (/*CONSTCOND*/0)
#define RBSTAT_DEC(v) do { } while (/*CONSTCOND*/0)
#endif
void rb_tree_init(rb_tree_t *, const rb_tree_ops_t *);
void * rb_tree_insert_node(rb_tree_t *, void *);
void * rb_tree_find_node(rb_tree_t *, const void *);
void * rb_tree_find_node_geq(rb_tree_t *, const void *);
void * rb_tree_find_node_leq(rb_tree_t *, const void *);
void rb_tree_remove_node(rb_tree_t *, void *);
void * rb_tree_iterate(rb_tree_t *, void *, const unsigned int);
#ifdef RBDEBUG
void rb_tree_check(const rb_tree_t *, bool);
#endif
#ifdef RBSTATS
void rb_tree_depths(const rb_tree_t *, size_t *);
#endif
__END_DECLS
#endif /* _SYS_RBTREE_H_*/

View File

@ -1,30 +1,5 @@
/* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos Exp $ */ /* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos 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.
*/
/*- /*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
@ -56,9 +31,11 @@
#include <prop/prop_array.h> #include <prop/prop_array.h>
#include "prop_object_impl.h" #include "prop_object_impl.h"
#include <errno.h>
#include <zlib.h> #if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h>
#define __unused /* empty */
#endif
struct _prop_array { struct _prop_array {
struct _prop_object pa_obj; struct _prop_object pa_obj;
@ -364,7 +341,7 @@ static prop_object_t
_prop_array_iterator_next_object(void *v) _prop_array_iterator_next_object(void *v)
{ {
struct _prop_array_iterator *pai = v; struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj; prop_array_t pa __unused = pai->pai_base.pi_obj;
prop_object_t po; prop_object_t po;
_PROP_ASSERT(prop_object_is_array(pa)); _PROP_ASSERT(prop_object_is_array(pa));
@ -391,7 +368,7 @@ static void
_prop_array_iterator_reset(void *v) _prop_array_iterator_reset(void *v)
{ {
struct _prop_array_iterator *pai = v; struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj; prop_array_t pa __unused = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa)); _PROP_ASSERT(prop_object_is_array(pa));
@ -889,6 +866,7 @@ prop_array_internalize(const char *xml)
return _prop_generic_internalize(xml, "array"); return _prop_generic_internalize(xml, "array");
} }
#if !defined(_KERNEL) && !defined(_STANDALONE)
/* /*
* prop_array_externalize_to_file -- * prop_array_externalize_to_file --
* Externalize an array to the specified file. * Externalize an array to the specified file.
@ -903,8 +881,7 @@ prop_array_externalize_to_file(prop_array_t array, const char *fname)
xml = prop_array_externalize(array); xml = prop_array_externalize(array);
if (xml == NULL) if (xml == NULL)
return (false); return (false);
rv = _prop_object_externalize_write_file(fname, xml, rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), false);
strlen(xml), false);
if (rv == false) if (rv == false)
save_errno = errno; save_errno = errno;
_PROP_FREE(xml, M_TEMP); _PROP_FREE(xml, M_TEMP);
@ -914,31 +891,6 @@ prop_array_externalize_to_file(prop_array_t array, const char *fname)
return (rv); return (rv);
} }
/*
* prop_array_externalize_to_zfile ---
* Externalize an array to the specified file, and on the fly
* compressing the result with gzip (via zlib).
*/
bool
prop_array_externalize_to_zfile(prop_array_t array, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0;
xml = prop_array_externalize(array);
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_array_internalize_from_file -- * prop_array_internalize_from_file --
* Internalize an array from a file. * Internalize an array from a file.
@ -957,88 +909,4 @@ prop_array_internalize_from_file(const char *fname)
return (array); return (array);
} }
#endif /* _KERNEL && !_STANDALONE */
#define _READ_CHUNK 512
/*
* prop_array_internalize_from_zfile ---
* Internalize an array from a compressed gzip file.
*/
prop_array_t
prop_array_internalize_from_zfile(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_array_t array;
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 (decompressed) */
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP);
if (uncomp_xml == NULL) {
_prop_object_internalize_unmap_file(mf);
(void)inflateEnd(&strm);
return NULL;
}
/* Inflate the input buffer and copy into 'dest' */
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);
array = prop_array_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return array;
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);
array = prop_array_internalize(uncomp_xml);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
return array;
}

View File

@ -218,6 +218,21 @@ prop_array_get_cstring ## variant (prop_array_t array, \
} \ } \
\ \
bool \ bool \
prop_array_add_cstring ## variant (prop_array_t array, \
const char *cp) \
{ \
prop_string_t str; \
bool rv; \
\
str = prop_string_create_cstring ## variant (cp); \
if (str == NULL) \
return false; \
rv = prop_array_add(array, str); \
prop_object_release(str); \
return rv; \
} \
\
bool \
prop_array_set_cstring ## variant (prop_array_t array, \ prop_array_set_cstring ## variant (prop_array_t array, \
unsigned int indx, \ unsigned int indx, \
const char *cp) \ const char *cp) \
@ -238,3 +253,14 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const) TEMPLATE(_nocopy,const)
#undef TEMPLATE #undef TEMPLATE
bool
prop_array_add_and_rel(prop_array_t array, prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_array_add(array, po);
prop_object_release(po);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_bool.c,v 1.16 2008/08/03 04:00:12 thorpej Exp $ */ /* $NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $ */
/*- /*-
* Copyright (c) 2006 The NetBSD Foundation, Inc. * Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -40,9 +40,6 @@ struct _prop_bool {
static struct _prop_bool _prop_bool_true; static struct _prop_bool _prop_bool_true;
static struct _prop_bool _prop_bool_false; static struct _prop_bool _prop_bool_false;
_PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex)
static bool _prop_bool_initialized;
static _prop_object_free_rv_t static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t, prop_object_t *); _prop_bool_free(prop_stack_t, prop_object_t *);
static bool _prop_bool_externalize( static bool _prop_bool_externalize(
@ -109,27 +106,29 @@ _prop_bool_equals(prop_object_t v1, prop_object_t v2,
return (_PROP_OBJECT_EQUALS_FALSE); return (_PROP_OBJECT_EQUALS_FALSE);
} }
_PROP_ONCE_DECL(_prop_bool_init_once)
static int
_prop_bool_init(void)
{
_prop_object_init(&_prop_bool_true.pb_obj,
&_prop_object_type_bool);
_prop_bool_true.pb_value = true;
_prop_object_init(&_prop_bool_false.pb_obj,
&_prop_object_type_bool);
_prop_bool_false.pb_value = false;
return 0;
}
static prop_bool_t static prop_bool_t
_prop_bool_alloc(bool val) _prop_bool_alloc(bool val)
{ {
prop_bool_t pb; prop_bool_t pb;
if (! _prop_bool_initialized) { _PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
_PROP_MUTEX_LOCK(_prop_bool_initialized_mutex);
if (! _prop_bool_initialized) {
_prop_object_init(&_prop_bool_true.pb_obj,
&_prop_object_type_bool);
_prop_bool_true.pb_value = true;
_prop_object_init(&_prop_bool_false.pb_obj,
&_prop_object_type_bool);
_prop_bool_false.pb_value = false;
_prop_bool_initialized = true;
}
_PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex);
}
pb = val ? &_prop_bool_true : &_prop_bool_false; pb = val ? &_prop_bool_true : &_prop_bool_false;
prop_object_retain(pb); prop_object_retain(pb);

View File

@ -1,29 +1,4 @@
/* $NetBSD: prop_dictionary.c,v 1.33 2008/11/30 00:17:07 haad Exp $ */ /* $NetBSD: prop_dictionary.c,v 1.37 2011/04/20 19:40:00 martin 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.
*/
/*- /*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
@ -54,12 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE. * 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_object_impl.h"
#include "prop_rb_impl.h" #include "prop_rb_impl.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h> #include <errno.h>
#include <zlib.h> #define __unused /* empty */
#endif
/* /*
* We implement these like arrays, but we keep them sorted by key. * We implement these like arrays, but we keep them sorted by key.
@ -88,10 +67,6 @@ struct _prop_dictionary_keysym {
/* actually variable length */ /* 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 */ /* pdk_key[1] takes care of the NUL */
#define PDK_SIZE_16 (sizeof(struct _prop_dictionary_keysym) + 16) #define PDK_SIZE_16 (sizeof(struct _prop_dictionary_keysym) + 16)
#define PDK_SIZE_32 (sizeof(struct _prop_dictionary_keysym) + 32) #define PDK_SIZE_32 (sizeof(struct _prop_dictionary_keysym) + 32)
@ -198,35 +173,49 @@ struct _prop_dictionary_iterator {
*/ */
static int static int
_prop_dict_keysym_rb_compare_nodes(const struct rb_node *n1, /*ARGSUSED*/
const struct rb_node *n2) _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 struct _prop_dictionary_keysym *pdk1 = n1;
const prop_dictionary_keysym_t pdk2 = RBNODE_TO_PDK(n2); 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 static int
_prop_dict_keysym_rb_compare_key(const struct rb_node *n, /*ARGSUSED*/
const void *v) _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; 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_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 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) _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 static void
_prop_dict_keysym_put(prop_dictionary_keysym_t pdk) _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_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); _prop_dict_keysym_put(pdk);
return _PROP_OBJECT_FREE_DONE; 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 static prop_dictionary_keysym_t
_prop_dict_keysym_alloc(const char *key) _prop_dict_keysym_alloc(const char *key)
{ {
prop_dictionary_keysym_t opdk, pdk; prop_dictionary_keysym_t opdk, pdk, rpdk;
const struct rb_node *n;
size_t size; 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, * Check to see if this already exists in the tree. If it does,
* we just retain it and return it. * we just retain it and return it.
*/ */
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex); _PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
if (! _prop_dict_keysym_tree_initialized) { opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
_prop_rb_tree_init(&_prop_dict_keysym_tree, if (opdk != NULL) {
&_prop_dict_keysym_rb_tree_ops); prop_object_retain(opdk);
_prop_dict_keysym_tree_initialized = true; _PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
} else { return (opdk);
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);
}
} }
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex); _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. * we have to check again if it is in the tree.
*/ */
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex); _PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
n = _prop_rb_tree_find(&_prop_dict_keysym_tree, key); opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (n != NULL) { if (opdk != NULL) {
opdk = RBNODE_TO_PDK(n);
prop_object_retain(opdk); prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
_prop_dict_keysym_put(pdk); _prop_dict_keysym_put(pdk);
return (opdk); return (opdk);
} }
rv = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, &pdk->pdk_link); rpdk = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, pdk);
_PROP_ASSERT(rv == true); _PROP_ASSERT(rpdk == pdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (pdk); return (pdk);
} }
@ -416,6 +397,9 @@ _prop_dictionary_free(prop_stack_t stack, prop_object_t *obj)
static void static void
_prop_dictionary_lock(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); _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_pointer1 = (void *)(idx + 1);
*stored_pointer2 = (void *)(idx + 1); *stored_pointer2 = (void *)(idx + 1);
*next_obj1 = &dict1->pd_array[idx].pde_objref; *next_obj1 = dict1->pd_array[idx].pde_objref;
*next_obj2 = &dict2->pd_array[idx].pde_objref; *next_obj2 = dict2->pd_array[idx].pde_objref;
if (!prop_dictionary_keysym_equals(dict1->pd_array[idx].pde_key, if (!prop_dictionary_keysym_equals(dict1->pd_array[idx].pde_key,
dict2->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) _prop_dictionary_iterator_next_object(void *v)
{ {
struct _prop_dictionary_iterator *pdi = 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_dictionary_keysym_t pdk;
_PROP_ASSERT(prop_object_is_dictionary(pd)); _PROP_ASSERT(prop_object_is_dictionary(pd));
@ -672,7 +656,7 @@ static void
_prop_dictionary_iterator_reset(void *v) _prop_dictionary_iterator_reset(void *v)
{ {
struct _prop_dictionary_iterator *pdi = 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_RWLOCK_RDLOCK(pd->pd_rwlock);
_prop_dictionary_iterator_reset_locked(pdi); _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_object_t
prop_dictionary_get(prop_dictionary_t pd, const char *key) 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); _PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
po = _prop_dictionary_get(pd, key, true); po = _prop_dictionary_get(pd, key, true);
@ -1388,6 +1375,7 @@ prop_dictionary_internalize(const char *xml)
return _prop_generic_internalize(xml, "dict"); return _prop_generic_internalize(xml, "dict");
} }
#if !defined(_KERNEL) && !defined(_STANDALONE)
/* /*
* prop_dictionary_externalize_to_file -- * prop_dictionary_externalize_to_file --
* Externalize a dictionary to the specified 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); xml = prop_dictionary_externalize(dict);
if (xml == NULL) if (xml == NULL)
return (false); return (false);
rv = _prop_object_externalize_write_file(fname, xml, rv = _prop_object_externalize_write_file(fname, xml, strlen(xml),
strlen(xml), false); false);
if (rv == false) if (rv == false)
save_errno = errno; save_errno = errno;
_PROP_FREE(xml, M_TEMP); _PROP_FREE(xml, M_TEMP);
@ -1413,31 +1401,6 @@ prop_dictionary_externalize_to_file(prop_dictionary_t dict, const char *fname)
return (rv); 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 -- * prop_dictionary_internalize_from_file --
* Internalize a dictionary from a file. * Internalize a dictionary from a file.
@ -1456,87 +1419,4 @@ prop_dictionary_internalize_from_file(const char *fname)
return (dict); return (dict);
} }
#endif /* !_KERNEL && !_STANDALONE */
#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;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */ /* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
/*- /*-
* Copyright (c) 2006 The NetBSD Foundation, Inc. * Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -41,6 +41,18 @@
#include <prop/proplib.h> #include <prop/proplib.h>
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */ #include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
bool
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp)
{
prop_object_t o;
o = prop_dictionary_get(dict, key);
if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
return false;
*dp = o;
return true;
}
bool bool
prop_dictionary_get_bool(prop_dictionary_t dict, prop_dictionary_get_bool(prop_dictionary_t dict,
const char *key, const char *key,
@ -206,3 +218,15 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const) TEMPLATE(_nocopy,const)
#undef TEMPLATE #undef TEMPLATE
bool
prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_dictionary_set(dict, key, po);
prop_object_release(po);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_number.c,v 1.20 2008/11/30 00:17:07 haad Exp $ */ /* $NetBSD: prop_number.c,v 1.23 2010/09/24 22:51:52 rmind Exp $ */
/*- /*-
* Copyright (c) 2006 The NetBSD Foundation, Inc. * Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -33,8 +33,16 @@
#include "prop_object_impl.h" #include "prop_object_impl.h"
#include "prop_rb_impl.h" #include "prop_rb_impl.h"
#if defined(_KERNEL)
#include <sys/systm.h>
#elif defined(_STANDALONE)
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#else
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#define __unused /* empty */
#endif
struct _prop_number { struct _prop_number {
struct _prop_object pn_obj; struct _prop_object pn_obj;
@ -51,10 +59,6 @@ struct _prop_number {
} pn_value; } pn_value;
}; };
#define RBNODE_TO_PN(n) \
((struct _prop_number *) \
((uintptr_t)n - offsetof(struct _prop_number, pn_link)))
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr") _PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
static _prop_object_free_rv_t static _prop_object_free_rv_t
@ -115,33 +119,34 @@ _prop_number_compare_values(const struct _prop_number_value *pnv1,
} }
static int static int
_prop_number_rb_compare_nodes(const struct rb_node *n1, /*ARGSUSED*/
const struct rb_node *n2) _prop_number_rb_compare_nodes(void *ctx __unused,
const void *n1, const void *n2)
{ {
const prop_number_t pn1 = RBNODE_TO_PN(n1); const struct _prop_number *pn1 = n1;
const prop_number_t pn2 = RBNODE_TO_PN(n2); const struct _prop_number *pn2 = n2;
return (_prop_number_compare_values(&pn1->pn_value, &pn2->pn_value)); return _prop_number_compare_values(&pn1->pn_value, &pn2->pn_value);
} }
static int static int
_prop_number_rb_compare_key(const struct rb_node *n, /*ARGSUSED*/
const void *v) _prop_number_rb_compare_key(void *ctx __unused, const void *n, const void *v)
{ {
const prop_number_t pn = RBNODE_TO_PN(n); const struct _prop_number *pn = n;
const struct _prop_number_value *pnv = v; const struct _prop_number_value *pnv = v;
return (_prop_number_compare_values(&pn->pn_value, pnv)); return _prop_number_compare_values(&pn->pn_value, pnv);
} }
static const struct rb_tree_ops _prop_number_rb_tree_ops = { static const rb_tree_ops_t _prop_number_rb_tree_ops = {
.rbto_compare_nodes = _prop_number_rb_compare_nodes, .rbto_compare_nodes = _prop_number_rb_compare_nodes,
.rbto_compare_key = _prop_number_rb_compare_key, .rbto_compare_key = _prop_number_rb_compare_key,
.rbto_node_offset = offsetof(struct _prop_number, pn_link),
.rbto_context = NULL
}; };
static struct rb_tree _prop_number_tree; static struct rb_tree _prop_number_tree;
static bool _prop_number_tree_initialized;
_PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex) _PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex)
/* ARGSUSED */ /* ARGSUSED */
@ -150,21 +155,34 @@ _prop_number_free(prop_stack_t stack, prop_object_t *obj)
{ {
prop_number_t pn = *obj; prop_number_t pn = *obj;
_prop_rb_tree_remove_node(&_prop_number_tree, &pn->pn_link); _prop_rb_tree_remove_node(&_prop_number_tree, pn);
_PROP_POOL_PUT(_prop_number_pool, pn); _PROP_POOL_PUT(_prop_number_pool, pn);
return (_PROP_OBJECT_FREE_DONE); return (_PROP_OBJECT_FREE_DONE);
} }
static void _PROP_ONCE_DECL(_prop_number_init_once)
_prop_number_lock()
static int
_prop_number_init(void)
{ {
_PROP_MUTEX_INIT(_prop_number_tree_mutex);
_prop_rb_tree_init(&_prop_number_tree, &_prop_number_rb_tree_ops);
return 0;
}
static void
_prop_number_lock(void)
{
/* XXX: init necessary? */
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
_PROP_MUTEX_LOCK(_prop_number_tree_mutex); _PROP_MUTEX_LOCK(_prop_number_tree_mutex);
} }
static void static void
_prop_number_unlock() _prop_number_unlock(void)
{ {
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
} }
@ -178,8 +196,9 @@ _prop_number_externalize(struct _prop_object_externalize_context *ctx,
/* /*
* For the record: * For the record:
* The original implementation used hex for signed numbers, * the original NetBSD implementation used hexadecimal for unsigned
* but we changed it to be human readable. * numbers, but in the portable proplib we changed it to be human
* readable (base 10).
*/ */
if (pn->pn_value.pnv_is_unsigned) if (pn->pn_value.pnv_is_unsigned)
sprintf(tmpstr, "%" PRIu64, pn->pn_value.pnv_unsigned); sprintf(tmpstr, "%" PRIu64, pn->pn_value.pnv_unsigned);
@ -253,27 +272,20 @@ _prop_number_equals(prop_object_t v1, prop_object_t v2,
static prop_number_t static prop_number_t
_prop_number_alloc(const struct _prop_number_value *pnv) _prop_number_alloc(const struct _prop_number_value *pnv)
{ {
prop_number_t opn, pn; prop_number_t opn, pn, rpn;
struct rb_node *n;
bool rv; _PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
/* /*
* Check to see if this already exists in the tree. If it does, * Check to see if this already exists in the tree. If it does,
* we just retain it and return it. * we just retain it and return it.
*/ */
_PROP_MUTEX_LOCK(_prop_number_tree_mutex); _PROP_MUTEX_LOCK(_prop_number_tree_mutex);
if (! _prop_number_tree_initialized) { opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
_prop_rb_tree_init(&_prop_number_tree, if (opn != NULL) {
&_prop_number_rb_tree_ops); prop_object_retain(opn);
_prop_number_tree_initialized = true; _PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
} else { return (opn);
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (n != NULL) {
opn = RBNODE_TO_PN(n);
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (opn);
}
} }
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
@ -294,16 +306,15 @@ _prop_number_alloc(const struct _prop_number_value *pnv)
* we have to check again if it is in the tree. * we have to check again if it is in the tree.
*/ */
_PROP_MUTEX_LOCK(_prop_number_tree_mutex); _PROP_MUTEX_LOCK(_prop_number_tree_mutex);
n = _prop_rb_tree_find(&_prop_number_tree, pnv); opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (n != NULL) { if (opn != NULL) {
opn = RBNODE_TO_PN(n);
prop_object_retain(opn); prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
_PROP_POOL_PUT(_prop_number_pool, pn); _PROP_POOL_PUT(_prop_number_pool, pn);
return (opn); return (opn);
} }
rv = _prop_rb_tree_insert_node(&_prop_number_tree, &pn->pn_link); rpn = _prop_rb_tree_insert_node(&_prop_number_tree, pn);
_PROP_ASSERT(rv == true); _PROP_ASSERT(rpn == pn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex); _PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (pn); return (pn);
} }
@ -501,10 +512,14 @@ _prop_number_internalize_unsigned(struct _prop_object_internalize_context *ctx,
_PROP_ASSERT(/*CONSTCOND*/sizeof(unsigned long long) == _PROP_ASSERT(/*CONSTCOND*/sizeof(unsigned long long) ==
sizeof(uint64_t)); sizeof(uint64_t));
#ifndef _KERNEL
errno = 0; errno = 0;
#endif
pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0); pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE) if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE)
return (false); return (false);
#endif
pnv->pnv_is_unsigned = true; pnv->pnv_is_unsigned = true;
ctx->poic_cp = cp; ctx->poic_cp = cp;
@ -519,11 +534,15 @@ _prop_number_internalize_signed(struct _prop_object_internalize_context *ctx,
_PROP_ASSERT(/*CONSTCOND*/sizeof(long long) == sizeof(int64_t)); _PROP_ASSERT(/*CONSTCOND*/sizeof(long long) == sizeof(int64_t));
#ifndef _KERNEL
errno = 0; errno = 0;
#endif
pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0); pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) && if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) &&
errno == ERANGE) errno == ERANGE)
return (false); return (false);
#endif
pnv->pnv_is_unsigned = false; pnv->pnv_is_unsigned = false;
ctx->poic_cp = cp; ctx->poic_cp = cp;

View File

@ -41,10 +41,6 @@
#include <zlib.h> #include <zlib.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* /*
* _prop_object_init -- * _prop_object_init --
* Initialize an object. Called when sub-classes create * Initialize an object. Called when sub-classes create
@ -816,10 +812,7 @@ _prop_object_externalize_write_file(const char *fname, const char *xml,
size_t len, bool do_compress) size_t len, bool do_compress)
{ {
gzFile gzf = NULL; gzFile gzf = NULL;
char tname[PATH_MAX]; char tname[PATH_MAX], *otname;
#ifndef HAVE_STRLCAT
char *otname;
#endif
int fd; int fd;
int save_errno; int save_errno;
mode_t myumask; mode_t myumask;
@ -865,7 +858,11 @@ _prop_object_externalize_write_file(const char *fname, const char *xml,
goto bad; goto bad;
} }
#ifdef HAVE_FDATASYNC
if (fdatasync(fd) == -1)
#else
if (fsync(fd) == -1) if (fsync(fd) == -1)
#endif
goto bad; goto bad;
myumask = umask(0); myumask = umask(0);
@ -1190,6 +1187,8 @@ prop_object_equals_with_error(prop_object_t obj1, prop_object_t obj2,
if (!_prop_stack_pop(&stack, &obj1, &obj2, if (!_prop_stack_pop(&stack, &obj1, &obj2,
&stored_pointer1, &stored_pointer2)) &stored_pointer1, &stored_pointer2))
return true; return true;
po1 = obj1;
po2 = obj2;
goto continue_subtree; goto continue_subtree;
} }
_PROP_ASSERT(ret == _PROP_OBJECT_EQUALS_RECURSE); _PROP_ASSERT(ret == _PROP_OBJECT_EQUALS_RECURSE);

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_object_impl.h,v 1.28 2008/11/30 00:17:07 haad Exp $ */ /* $NetBSD: prop_object_impl.h,v 1.30 2009/09/13 18:45:10 pooka Exp $ */
/*- /*-
* Copyright (c) 2006 The NetBSD Foundation, Inc. * Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -32,7 +32,11 @@
#ifndef _PROPLIB_PROP_OBJECT_IMPL_H_ #ifndef _PROPLIB_PROP_OBJECT_IMPL_H_
#define _PROPLIB_PROP_OBJECT_IMPL_H_ #define _PROPLIB_PROP_OBJECT_IMPL_H_
#if defined(_KERNEL) || defined(_STANDALONE)
#include <lib/libkern/libkern.h>
#else
#include <inttypes.h> #include <inttypes.h>
#endif
#include "prop_stack.h" #include "prop_stack.h"
@ -143,9 +147,9 @@ struct _prop_object_internalize_context *
void _prop_object_internalize_context_free( void _prop_object_internalize_context_free(
struct _prop_object_internalize_context *); struct _prop_object_internalize_context *);
#if !defined(_KERNEL) && !defined(_STANDALONE)
bool _prop_object_externalize_write_file(const char *, bool _prop_object_externalize_write_file(const char *,
const char *, const char *, size_t, bool);
size_t, bool);
struct _prop_object_internalize_mapped_file { struct _prop_object_internalize_mapped_file {
char * poimf_xml; char * poimf_xml;
@ -156,6 +160,7 @@ struct _prop_object_internalize_mapped_file *
_prop_object_internalize_map_file(const char *); _prop_object_internalize_map_file(const char *);
void _prop_object_internalize_unmap_file( void _prop_object_internalize_unmap_file(
struct _prop_object_internalize_mapped_file *); struct _prop_object_internalize_mapped_file *);
#endif /* !_KERNEL && !_STANDALONE */
typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *, typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *); struct _prop_object_internalize_context *);
@ -226,6 +231,110 @@ struct _prop_object_iterator {
uint32_t pi_version; uint32_t pi_version;
}; };
#define _PROP_NOTHREAD_ONCE_DECL(x) static bool x = false;
#define _PROP_NOTHREAD_ONCE_RUN(x,f) \
do { \
if ((x) == false) { \
f(); \
x = true; \
} \
} while (/*CONSTCOND*/0)
#if defined(_KERNEL)
/*
* proplib in the kernel...
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/systm.h>
#include <sys/rwlock.h>
#include <sys/once.h>
#define _PROP_ASSERT(x) KASSERT(x)
#define _PROP_MALLOC(s, t) malloc((s), (t), M_WAITOK)
#define _PROP_CALLOC(s, t) malloc((s), (t), M_WAITOK | M_ZERO)
#define _PROP_REALLOC(v, s, t) realloc((v), (s), (t), M_WAITOK)
#define _PROP_FREE(v, t) free((v), (t))
#define _PROP_POOL_GET(p) pool_get(&(p), PR_WAITOK)
#define _PROP_POOL_PUT(p, v) pool_put(&(p), (v))
struct prop_pool_init {
struct pool *pp;
size_t size;
const char *wchan;
};
#define _PROP_POOL_INIT(pp, size, wchan) \
struct pool pp; \
static const struct prop_pool_init _link_ ## pp[1] = { \
{ &pp, size, wchan } \
}; \
__link_set_add_rodata(prop_linkpools, _link_ ## pp);
#define _PROP_MALLOC_DEFINE(t, s, l) \
MALLOC_DEFINE(t, s, l);
#define _PROP_MUTEX_DECL_STATIC(x) static kmutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x),MUTEX_DEFAULT,IPL_NONE)
#define _PROP_MUTEX_LOCK(x) mutex_enter(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_exit(&(x))
#define _PROP_RWLOCK_DECL(x) krwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rw_init(&(x))
#define _PROP_RWLOCK_RDLOCK(x) rw_enter(&(x), RW_READER)
#define _PROP_RWLOCK_WRLOCK(x) rw_enter(&(x), RW_WRITER)
#define _PROP_RWLOCK_UNLOCK(x) rw_exit(&(x))
#define _PROP_RWLOCK_DESTROY(x) rw_destroy(&(x))
#define _PROP_ONCE_DECL(x) static ONCE_DECL(x);
#define _PROP_ONCE_RUN(x,f) RUN_ONCE(&(x), f)
#elif defined(_STANDALONE)
/*
* proplib in a standalone environment...
*/
#include <lib/libsa/stand.h>
void * _prop_standalone_calloc(size_t);
void * _prop_standalone_realloc(void *, size_t);
#define _PROP_ASSERT(x) /* nothing */
#define _PROP_MALLOC(s, t) alloc((s))
#define _PROP_CALLOC(s, t) _prop_standalone_calloc((s))
#define _PROP_REALLOC(v, s, t) _prop_standalone_realloc((v), (s))
#define _PROP_FREE(v, t) dealloc((v), 0) /* XXX */
#define _PROP_POOL_GET(p) alloc((p))
#define _PROP_POOL_PUT(p, v) dealloc((v), (p))
#define _PROP_POOL_INIT(p, s, d) static const size_t p = s;
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/* /*
* proplib in user space... * proplib in user space...
*/ */
@ -250,12 +359,53 @@ struct _prop_object_iterator {
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */ #define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
#if defined(__NetBSD__) && defined(_LIBPROP)
/*
* Use the same mechanism as libc; we get pthread mutexes for threaded
* programs and do-nothing stubs for non-threaded programs.
*/
#include "reentrant.h"
#define _PROP_MUTEX_DECL_STATIC(x) static mutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_unlock(&(x))
#define _PROP_RWLOCK_DECL(x) rwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rwlock_init(&(x), NULL)
#define _PROP_RWLOCK_RDLOCK(x) rwlock_rdlock(&(x))
#define _PROP_RWLOCK_WRLOCK(x) rwlock_wrlock(&(x))
#define _PROP_RWLOCK_UNLOCK(x) rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) thr_once(&(x), (void(*)(void))f);
#elif defined(HAVE_NBTOOL_CONFIG_H)
/*
* None of NetBSD's build tools are multi-threaded.
*/
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/* /*
* Use pthread mutexes everywhere else. * Use pthread mutexes everywhere else.
*/ */
#include <pthread.h> #include <pthread.h>
#define _PROP_MUTEX_DECL_STATIC(x) \ #define _PROP_MUTEX_DECL_STATIC(x) static pthread_mutex_t x;
static pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; #define _PROP_MUTEX_INIT(x) pthread_mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x)) #define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) #define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
@ -266,9 +416,21 @@ struct _prop_object_iterator {
#define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(x)) #define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) pthread_rwlock_destroy(&(x)) #define _PROP_RWLOCK_DESTROY(x) pthread_rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f)
#endif
#endif /* _KERNEL */
/* /*
* Language features. * Language features.
*/ */
#if defined(__NetBSD__)
#include <sys/cdefs.h>
#define _PROP_ARG_UNUSED __unused
#else
#define _PROP_ARG_UNUSED /* delete */ #define _PROP_ARG_UNUSED /* delete */
#endif /* __NetBSD__ */
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */ #endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_rb_impl.h,v 1.7 2008/06/30 20:14:09 matt Exp $ */ /* $NetBSD: prop_rb_impl.h,v 1.8 2010/09/25 01:42:38 matt Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -32,8 +32,23 @@
#ifndef _PROP_RB_IMPL_H_ #ifndef _PROP_RB_IMPL_H_
#define _PROP_RB_IMPL_H_ #define _PROP_RB_IMPL_H_
#if 1
#include <prop/rbtree.h>
/*
* Define local names for common rb_tree functions.
*/
#define _prop_rb_tree_init rb_tree_init
#define _prop_rb_tree_insert_node rb_tree_insert_node
#define _prop_rb_tree_find rb_tree_find_node
#define _prop_rb_tree_remove_node rb_tree_remove_node
#define _prop_rb_tree_iterate rb_tree_iterate
#else /* __NetBSD__ */
#include <sys/types.h> #include <sys/types.h>
#include "queue.h" #include <sys/queue.h>
#include <machine/endian.h>
struct rb_node { struct rb_node {
struct rb_node *rb_nodes[3]; struct rb_node *rb_nodes[3];
@ -134,4 +149,6 @@ void _prop_rb_tree_check(const struct rb_tree *, bool);
struct rb_node * struct rb_node *
_prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int); _prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int);
#endif /* __NetBSD__ */
#endif /* _PROP_RB_IMPL_H_*/ #endif /* _PROP_RB_IMPL_H_*/

View File

@ -0,0 +1,146 @@
/*-
* Copyright (c) 2010-2012 Juan Romero Pardines.
* 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.
*/
#include <prop/proplib.h>
#include "prop_object_impl.h"
#include <errno.h>
#include <zlib.h>
#define _READ_CHUNK 8192
#define TEMPLATE(type) \
bool \
prop ## type ## _externalize_to_zfile(prop ## type ## _t obj, const char *fname) \
{ \
char *xml; \
bool rv; \
int save_errno = 0; \
\
xml = prop ## type ## _externalize(obj); \
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 ## type ## _t \
prop ## type ## _internalize_from_zfile(const char *fname) \
{ \
struct _prop_object_internalize_mapped_file *mf; \
prop ## type ## _t obj; \
z_stream strm; \
unsigned char *out; \
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; \
\
/* Output buffer (uncompressed) */ \
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
if (uncomp_xml == NULL) { \
_prop_object_internalize_unmap_file(mf); \
return NULL; \
} \
\
/* temporary output buffer for inflate */ \
out = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
if (out == NULL) { \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
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_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
return NULL; \
} \
strm.avail_in = mf->poimf_mapsize; \
strm.next_in = (unsigned char *)mf->poimf_xml; \
\
/* 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. */ \
(void)inflateEnd(&strm); \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
obj = prop ## type ## _internalize(mf->poimf_xml); \
_prop_object_internalize_unmap_file(mf); \
return obj; \
case Z_STREAM_ERROR: \
case Z_NEED_DICT: \
case Z_MEM_ERROR: \
(void)inflateEnd(&strm); \
_PROP_FREE(out, M_TEMP); \
_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); \
obj = prop ## type ## _internalize(uncomp_xml); \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
\
return obj; \
}
TEMPLATE(_array)
TEMPLATE(_dictionary)
#undef TEMPLATE

1335
lib/portableproplib/rb.c Normal file

File diff suppressed because it is too large Load Diff