Revert "Move all external code to lib/external."

This reverts commit 9effec0c4e.
This commit is contained in:
Duncan Overbruck
2021-02-04 22:42:57 +01:00
parent 93410bee7f
commit 51b39002e5
44 changed files with 32 additions and 32 deletions

View File

@@ -0,0 +1,152 @@
/* $NetBSD: prop_array.h,v 1.8 2008/09/11 13:15:13 haad Exp $ */
/*-
* Copyright (c) 2014 Juan Romero Pardines.
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_ARRAY_H_
#define _PROPLIB_PROP_ARRAY_H_
#include <stdint.h>
#include <prop/prop_object.h>
typedef struct _prop_array *prop_array_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_array_t prop_array_create(void);
prop_array_t prop_array_create_with_capacity(unsigned int);
prop_array_t prop_array_copy(prop_array_t);
prop_array_t prop_array_copy_mutable(prop_array_t);
unsigned int prop_array_capacity(prop_array_t);
unsigned int prop_array_count(prop_array_t);
bool prop_array_ensure_capacity(prop_array_t, unsigned int);
void prop_array_make_immutable(prop_array_t);
bool prop_array_mutable(prop_array_t);
prop_object_iterator_t prop_array_iterator(prop_array_t);
prop_object_t prop_array_get(prop_array_t, unsigned int);
bool prop_array_set(prop_array_t, unsigned int, prop_object_t);
bool prop_array_add(prop_array_t, prop_object_t);
bool prop_array_add_first(prop_array_t, prop_object_t);
void prop_array_remove(prop_array_t, unsigned int);
bool prop_array_equals(prop_array_t, prop_array_t);
char * prop_array_externalize(prop_array_t);
prop_array_t prop_array_internalize(const char *);
bool prop_array_externalize_to_file(prop_array_t, const char *);
bool prop_array_externalize_to_zfile(prop_array_t, const char *);
prop_array_t prop_array_internalize_from_file(const char *);
prop_array_t prop_array_internalize_from_zfile(const char *);
/*
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*/
bool prop_array_get_bool(prop_array_t, unsigned int,
bool *);
bool prop_array_set_bool(prop_array_t, unsigned int,
bool);
bool prop_array_get_int8(prop_array_t, unsigned int,
int8_t *);
bool prop_array_get_uint8(prop_array_t, unsigned int,
uint8_t *);
bool prop_array_set_int8(prop_array_t, unsigned int,
int8_t);
bool prop_array_set_uint8(prop_array_t, unsigned int,
uint8_t);
bool prop_array_get_int16(prop_array_t, unsigned int,
int16_t *);
bool prop_array_get_uint16(prop_array_t, unsigned int,
uint16_t *);
bool prop_array_set_int16(prop_array_t, unsigned int,
int16_t);
bool prop_array_set_uint16(prop_array_t, unsigned int,
uint16_t);
bool prop_array_get_int32(prop_array_t, unsigned int,
int32_t *);
bool prop_array_get_uint32(prop_array_t, unsigned int,
uint32_t *);
bool prop_array_set_int32(prop_array_t, unsigned int,
int32_t);
bool prop_array_set_uint32(prop_array_t, unsigned int,
uint32_t);
bool prop_array_get_int64(prop_array_t, unsigned int,
int64_t *);
bool prop_array_get_uint64(prop_array_t, unsigned int,
uint64_t *);
bool prop_array_set_int64(prop_array_t, unsigned int,
int64_t);
bool prop_array_set_uint64(prop_array_t, unsigned int,
uint64_t);
bool prop_array_add_int8(prop_array_t, int8_t);
bool prop_array_add_uint8(prop_array_t, uint8_t);
bool prop_array_add_int16(prop_array_t, int16_t);
bool prop_array_add_uint16(prop_array_t, uint16_t);
bool prop_array_add_int32(prop_array_t, int32_t);
bool prop_array_add_uint32(prop_array_t, uint32_t);
bool prop_array_add_int64(prop_array_t, int64_t);
bool prop_array_add_uint64(prop_array_t, uint64_t);
bool prop_array_get_cstring(prop_array_t, unsigned int,
char **);
bool prop_array_set_cstring(prop_array_t, unsigned int,
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,
unsigned int,
const char **);
bool prop_array_set_cstring_nocopy(prop_array_t,
unsigned int,
const char *);
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_ARRAY_H_ */

View File

@@ -0,0 +1,55 @@
/* $NetBSD: prop_bool.h,v 1.4 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_BOOL_H_
#define _PROPLIB_PROP_BOOL_H_
#include <stdbool.h>
#include <prop/prop_object.h>
typedef struct _prop_bool *prop_bool_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_bool_t prop_bool_create(bool);
prop_bool_t prop_bool_copy(prop_bool_t);
bool prop_bool_true(prop_bool_t);
bool prop_bool_equals(prop_bool_t, prop_bool_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_BOOL_H_ */

View File

@@ -0,0 +1,62 @@
/* $NetBSD: prop_data.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_DATA_H_
#define _PROPLIB_PROP_DATA_H_
#include <stdint.h>
#include <prop/prop_object.h>
#include <sys/types.h>
typedef struct _prop_data *prop_data_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_data_t prop_data_create_data(const void *, size_t);
prop_data_t prop_data_create_data_nocopy(const void *, size_t);
prop_data_t prop_data_copy(prop_data_t);
size_t prop_data_size(prop_data_t);
void * prop_data_data(prop_data_t);
const void * prop_data_data_nocopy(prop_data_t);
bool prop_data_equals(prop_data_t, prop_data_t);
bool prop_data_equals_data(prop_data_t, const void *, size_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_DATA_H_ */

View File

@@ -0,0 +1,158 @@
/* $NetBSD: prop_dictionary.h,v 1.9 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_DICTIONARY_H_
#define _PROPLIB_PROP_DICTIONARY_H_
#include <stdint.h>
#include <prop/prop_object.h>
#include <prop/prop_array.h>
typedef struct _prop_dictionary *prop_dictionary_t;
typedef struct _prop_dictionary_keysym *prop_dictionary_keysym_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_dictionary_t prop_dictionary_create(void);
prop_dictionary_t prop_dictionary_create_with_capacity(unsigned int);
prop_dictionary_t prop_dictionary_copy(prop_dictionary_t);
prop_dictionary_t prop_dictionary_copy_mutable(prop_dictionary_t);
unsigned int prop_dictionary_count(prop_dictionary_t);
bool prop_dictionary_ensure_capacity(prop_dictionary_t,
unsigned int);
void prop_dictionary_make_immutable(prop_dictionary_t);
bool prop_dictionary_mutable(prop_dictionary_t);
prop_object_iterator_t prop_dictionary_iterator(prop_dictionary_t);
prop_array_t prop_dictionary_all_keys(prop_dictionary_t);
prop_object_t prop_dictionary_get(prop_dictionary_t, const char *);
bool prop_dictionary_set(prop_dictionary_t, const char *,
prop_object_t);
void prop_dictionary_remove(prop_dictionary_t, const char *);
prop_object_t prop_dictionary_get_keysym(prop_dictionary_t,
prop_dictionary_keysym_t);
bool prop_dictionary_set_keysym(prop_dictionary_t,
prop_dictionary_keysym_t,
prop_object_t);
void prop_dictionary_remove_keysym(prop_dictionary_t,
prop_dictionary_keysym_t);
bool prop_dictionary_equals(prop_dictionary_t, prop_dictionary_t);
char * prop_dictionary_externalize(prop_dictionary_t);
prop_dictionary_t prop_dictionary_internalize(const char *);
bool prop_dictionary_externalize_to_file(prop_dictionary_t,
const char *);
bool prop_dictionary_externalize_to_zfile(prop_dictionary_t,
const char *);
prop_dictionary_t prop_dictionary_internalize_from_file(const char *);
prop_dictionary_t prop_dictionary_internalize_from_zfile(const char *);
const char * prop_dictionary_keysym_cstring_nocopy(prop_dictionary_keysym_t);
bool prop_dictionary_keysym_equals(prop_dictionary_keysym_t,
prop_dictionary_keysym_t);
/*
* Utility routines to make it more convenient to work with values
* 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 *);
bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
bool);
bool prop_dictionary_get_int8(prop_dictionary_t, const char *,
int8_t *);
bool prop_dictionary_get_uint8(prop_dictionary_t, const char *,
uint8_t *);
bool prop_dictionary_set_int8(prop_dictionary_t, const char *,
int8_t);
bool prop_dictionary_set_uint8(prop_dictionary_t, const char *,
uint8_t);
bool prop_dictionary_get_int16(prop_dictionary_t, const char *,
int16_t *);
bool prop_dictionary_get_uint16(prop_dictionary_t, const char *,
uint16_t *);
bool prop_dictionary_set_int16(prop_dictionary_t, const char *,
int16_t);
bool prop_dictionary_set_uint16(prop_dictionary_t, const char *,
uint16_t);
bool prop_dictionary_get_int32(prop_dictionary_t, const char *,
int32_t *);
bool prop_dictionary_get_uint32(prop_dictionary_t, const char *,
uint32_t *);
bool prop_dictionary_set_int32(prop_dictionary_t, const char *,
int32_t);
bool prop_dictionary_set_uint32(prop_dictionary_t, const char *,
uint32_t);
bool prop_dictionary_get_int64(prop_dictionary_t, const char *,
int64_t *);
bool prop_dictionary_get_uint64(prop_dictionary_t, const char *,
uint64_t *);
bool prop_dictionary_set_int64(prop_dictionary_t, const char *,
int64_t);
bool prop_dictionary_set_uint64(prop_dictionary_t, const char *,
uint64_t);
bool prop_dictionary_get_cstring(prop_dictionary_t, const char *,
char **);
bool prop_dictionary_set_cstring(prop_dictionary_t, const char *,
const char *);
bool prop_dictionary_get_cstring_nocopy(prop_dictionary_t,
const char *,
const char **);
bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
const char *,
const char *);
bool prop_dictionary_set_and_rel(prop_dictionary_t,
const char *,
prop_object_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_DICTIONARY_H_ */

View File

@@ -0,0 +1,96 @@
/* $NetBSD: prop_ingest.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_INGEST_H_
#define _PROPLIB_PROP_INGEST_H_
#include <prop/prop_object.h>
#include <prop/prop_dictionary.h>
typedef enum {
PROP_INGEST_ERROR_NO_ERROR = 0,
PROP_INGEST_ERROR_NO_KEY = 1,
PROP_INGEST_ERROR_WRONG_TYPE = 2,
PROP_INGEST_ERROR_HANDLER_FAILED = 3
} prop_ingest_error_t;
typedef enum {
PROP_INGEST_FLAG_OPTIONAL = 0x01
} prop_ingest_flag_t;
typedef struct _prop_ingest_context *prop_ingest_context_t;
typedef bool (*prop_ingest_handler_t)(prop_ingest_context_t, prop_object_t);
typedef struct {
const char *pite_key;
prop_type_t pite_type;
unsigned int pite_flags;
prop_ingest_handler_t pite_handler;
} prop_ingest_table_entry;
#define PROP_INGEST(key_, type_, handler_) \
{ .pite_key = key_ , \
.pite_type = type_ , \
.pite_flags = 0 , \
.pite_handler = handler_ }
#define PROP_INGEST_OPTIONAL(key_, type_, handler_) \
{ .pite_key = key_ , \
.pite_type = type_ , \
.pite_flags = PROP_INGEST_FLAG_OPTIONAL , \
.pite_handler = handler_ }
#define PROP_INGEST_END \
{ .pite_key = NULL }
#ifdef __cplusplus
extern "C" {
#endif
prop_ingest_context_t
prop_ingest_context_alloc(void *);
void prop_ingest_context_free(prop_ingest_context_t);
prop_ingest_error_t
prop_ingest_context_error(prop_ingest_context_t);
prop_type_t prop_ingest_context_type(prop_ingest_context_t);
const char * prop_ingest_context_key(prop_ingest_context_t);
void * prop_ingest_context_private(prop_ingest_context_t);
bool prop_dictionary_ingest(prop_dictionary_t,
const prop_ingest_table_entry[],
prop_ingest_context_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_INGEST_H_ */

View File

@@ -0,0 +1,63 @@
/* $NetBSD: prop_number.h,v 1.6 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_NUMBER_H_
#define _PROPLIB_PROP_NUMBER_H_
#include <stdint.h>
#include <prop/prop_object.h>
typedef struct _prop_number *prop_number_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_number_t prop_number_create_integer(int64_t);
prop_number_t prop_number_create_unsigned_integer(uint64_t);
prop_number_t prop_number_copy(prop_number_t);
int prop_number_size(prop_number_t);
bool prop_number_unsigned(prop_number_t);
int64_t prop_number_integer_value(prop_number_t);
uint64_t prop_number_unsigned_integer_value(prop_number_t);
bool prop_number_equals(prop_number_t, prop_number_t);
bool prop_number_equals_integer(prop_number_t, int64_t);
bool prop_number_equals_unsigned_integer(prop_number_t, uint64_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_NUMBER_H_ */

View File

@@ -0,0 +1,73 @@
/* $NetBSD: prop_object.h,v 1.7 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_OBJECT_H_
#define _PROPLIB_PROP_OBJECT_H_
#include <stdint.h>
#include <stdbool.h>
typedef void *prop_object_t;
typedef enum {
PROP_TYPE_UNKNOWN = 0x00000000,
PROP_TYPE_BOOL = 0x626f6f6c, /* 'bool' */
PROP_TYPE_NUMBER = 0x6e6d6272, /* 'nmbr' */
PROP_TYPE_STRING = 0x73746e67, /* 'stng' */
PROP_TYPE_DATA = 0x64617461, /* 'data' */
PROP_TYPE_ARRAY = 0x61726179, /* 'aray' */
PROP_TYPE_DICTIONARY = 0x64696374, /* 'dict' */
PROP_TYPE_DICT_KEYSYM = 0x646b6579 /* 'dkey' */
} prop_type_t;
#ifdef __cplusplus
extern "C" {
#endif
void prop_object_retain(prop_object_t);
void prop_object_release(prop_object_t);
prop_type_t prop_object_type(prop_object_t);
bool prop_object_equals(prop_object_t, prop_object_t);
bool prop_object_equals_with_error(prop_object_t, prop_object_t, bool *);
typedef struct _prop_object_iterator *prop_object_iterator_t;
prop_object_t prop_object_iterator_next(prop_object_iterator_t);
void prop_object_iterator_reset(prop_object_iterator_t);
void prop_object_iterator_release(prop_object_iterator_t);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_OBJECT_H_ */

View File

@@ -0,0 +1,68 @@
/* $NetBSD: prop_string.h,v 1.3 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_STRING_H_
#define _PROPLIB_PROP_STRING_H_
#include <stdint.h>
#include <prop/prop_object.h>
#include <sys/types.h>
typedef struct _prop_string *prop_string_t;
#ifdef __cplusplus
extern "C" {
#endif
prop_string_t prop_string_create(void);
prop_string_t prop_string_create_cstring(const char *);
prop_string_t prop_string_create_cstring_nocopy(const char *);
prop_string_t prop_string_copy(prop_string_t);
prop_string_t prop_string_copy_mutable(prop_string_t);
size_t prop_string_size(prop_string_t);
bool prop_string_mutable(prop_string_t);
char * prop_string_cstring(prop_string_t);
const char * prop_string_cstring_nocopy(prop_string_t);
bool prop_string_append(prop_string_t, prop_string_t);
bool prop_string_append_cstring(prop_string_t, const char *);
bool prop_string_equals(prop_string_t, prop_string_t);
bool prop_string_equals_cstring(prop_string_t, const char *);
#ifdef __cplusplus
}
#endif
#endif /* _PROPLIB_PROP_STRING_H_ */

View File

@@ -0,0 +1,45 @@
/* $NetBSD: proplib.h,v 1.6 2008/04/28 20:22:51 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROPLIB_H_
#define _PROPLIB_PROPLIB_H_
#include <stdint.h>
#include <prop/prop_array.h>
#include <prop/prop_bool.h>
#include <prop/prop_data.h>
#include <prop/prop_dictionary.h>
#include <prop/prop_number.h>
#include <prop/prop_string.h>
#include <prop/prop_ingest.h>
#endif /* _PROPLIB_PROPLIB_H_ */

View File

@@ -0,0 +1,222 @@
/* $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>
/* GCC version checking borrowed from glibc. */
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define __GNUC_PREREQ(maj,min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
# define __GNUC_PREREQ(maj,min) 0
#endif
#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
#ifdef __cplusplus
extern "C" {
#endif
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
#ifdef __cplusplus
extern "C" {
#endif
#endif /* _SYS_RBTREE_H_*/

View File

@@ -0,0 +1,962 @@
/* $NetBSD: prop_array.c,v 1.21 2012/07/27 09:10:59 pooka Exp $ */
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include "prop_object_impl.h"
#include <prop/prop_array.h>
#include <errno.h>
struct _prop_array {
struct _prop_object pa_obj;
_PROP_RWLOCK_DECL(pa_rwlock)
prop_object_t * pa_array;
unsigned int pa_capacity;
unsigned int pa_count;
int pa_flags;
uint32_t pa_version;
};
#define PA_F_IMMUTABLE 0x01 /* array is immutable */
_PROP_POOL_INIT(_prop_array_pool, sizeof(struct _prop_array), "proparay")
static _prop_object_free_rv_t
_prop_array_free(prop_stack_t, prop_object_t *);
static void _prop_array_emergency_free(prop_object_t);
static bool _prop_array_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_array_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static void _prop_array_equals_finish(prop_object_t, prop_object_t);
static prop_object_iterator_t
_prop_array_iterator_locked(prop_array_t);
static prop_object_t
_prop_array_iterator_next_object_locked(void *);
static void _prop_array_iterator_reset_locked(void *);
static const struct _prop_object_type _prop_object_type_array = {
.pot_type = PROP_TYPE_ARRAY,
.pot_free = _prop_array_free,
.pot_emergency_free = _prop_array_emergency_free,
.pot_extern = _prop_array_externalize,
.pot_equals = _prop_array_equals,
.pot_equals_finish = _prop_array_equals_finish,
};
#define prop_object_is_array(x) \
((x) != NULL && (x)->pa_obj.po_type == &_prop_object_type_array)
#define prop_array_is_immutable(x) (((x)->pa_flags & PA_F_IMMUTABLE) != 0)
struct _prop_array_iterator {
struct _prop_object_iterator pai_base;
unsigned int pai_index;
};
#define EXPAND_STEP 16
static _prop_object_free_rv_t
_prop_array_free(prop_stack_t stack, prop_object_t *obj)
{
prop_array_t pa = *obj;
prop_object_t po;
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
_PROP_ASSERT((pa->pa_capacity == 0 && pa->pa_array == NULL) ||
(pa->pa_capacity != 0 && pa->pa_array != NULL));
/* The easy case is an empty array, just free and return. */
if (pa->pa_count == 0) {
if (pa->pa_array != NULL)
_PROP_FREE(pa->pa_array, M_PROP_ARRAY);
_PROP_RWLOCK_DESTROY(pa->pa_rwlock);
_PROP_POOL_PUT(_prop_array_pool, pa);
return (_PROP_OBJECT_FREE_DONE);
}
po = pa->pa_array[pa->pa_count - 1];
_PROP_ASSERT(po != NULL);
if (stack == NULL) {
/*
* If we are in emergency release mode,
* just let caller recurse down.
*/
*obj = po;
return (_PROP_OBJECT_FREE_FAILED);
}
/* Otherwise, try to push the current object on the stack. */
if (!_prop_stack_push(stack, pa, NULL, NULL, NULL)) {
/* Push failed, entering emergency release mode. */
return (_PROP_OBJECT_FREE_FAILED);
}
/* Object pushed on stack, caller will release it. */
--pa->pa_count;
*obj = po;
return (_PROP_OBJECT_FREE_RECURSE);
}
static void
_prop_array_emergency_free(prop_object_t obj)
{
prop_array_t pa = obj;
_PROP_ASSERT(pa->pa_count != 0);
--pa->pa_count;
}
static bool
_prop_array_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_array_t pa = v;
struct _prop_object *po;
prop_object_iterator_t pi;
unsigned int i;
bool rv = false;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
if (pa->pa_count == 0) {
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (_prop_object_externalize_empty_tag(ctx, "array"));
}
/* XXXJRT Hint "count" for the internalize step? */
if (_prop_object_externalize_start_tag(ctx, "array") == false ||
_prop_object_externalize_append_char(ctx, '\n') == false)
goto out;
pi = _prop_array_iterator_locked(pa);
if (pi == NULL)
goto out;
ctx->poec_depth++;
_PROP_ASSERT(ctx->poec_depth != 0);
while ((po = _prop_array_iterator_next_object_locked(pi)) != NULL) {
if ((*po->po_type->pot_extern)(ctx, po) == false) {
prop_object_iterator_release(pi);
goto out;
}
}
prop_object_iterator_release(pi);
ctx->poec_depth--;
for (i = 0; i < ctx->poec_depth; i++) {
if (_prop_object_externalize_append_char(ctx, '\t') == false)
goto out;
}
if (_prop_object_externalize_end_tag(ctx, "array") == false)
goto out;
rv = true;
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_array_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_array_t array1 = v1;
prop_array_t array2 = v2;
uintptr_t idx;
_prop_object_equals_rv_t rv = _PROP_OBJECT_EQUALS_FALSE;
if (array1 == array2)
return (_PROP_OBJECT_EQUALS_TRUE);
_PROP_ASSERT(*stored_pointer1 == *stored_pointer2);
idx = (uintptr_t)*stored_pointer1;
/* For the first iteration, lock the objects. */
if (idx == 0) {
if ((uintptr_t)array1 < (uintptr_t)array2) {
_PROP_RWLOCK_RDLOCK(array1->pa_rwlock);
_PROP_RWLOCK_RDLOCK(array2->pa_rwlock);
} else {
_PROP_RWLOCK_RDLOCK(array2->pa_rwlock);
_PROP_RWLOCK_RDLOCK(array1->pa_rwlock);
}
}
if (array1->pa_count != array2->pa_count)
goto out;
if (idx == array1->pa_count) {
rv = _PROP_OBJECT_EQUALS_TRUE;
goto out;
}
_PROP_ASSERT(idx < array1->pa_count);
*stored_pointer1 = (void *)(idx + 1);
*stored_pointer2 = (void *)(idx + 1);
*next_obj1 = array1->pa_array[idx];
*next_obj2 = array2->pa_array[idx];
return (_PROP_OBJECT_EQUALS_RECURSE);
out:
_PROP_RWLOCK_UNLOCK(array1->pa_rwlock);
_PROP_RWLOCK_UNLOCK(array2->pa_rwlock);
return (rv);
}
static void
_prop_array_equals_finish(prop_object_t v1, prop_object_t v2)
{
_PROP_RWLOCK_UNLOCK(((prop_array_t)v1)->pa_rwlock);
_PROP_RWLOCK_UNLOCK(((prop_array_t)v2)->pa_rwlock);
}
static prop_array_t
_prop_array_alloc(unsigned int capacity)
{
prop_array_t pa;
prop_object_t *array;
if (capacity != 0) {
array = _PROP_CALLOC(capacity * sizeof(prop_object_t),
M_PROP_ARRAY);
if (array == NULL)
return (NULL);
} else
array = NULL;
pa = _PROP_POOL_GET(_prop_array_pool);
if (pa != NULL) {
_prop_object_init(&pa->pa_obj, &_prop_object_type_array);
pa->pa_obj.po_type = &_prop_object_type_array;
_PROP_RWLOCK_INIT(pa->pa_rwlock);
pa->pa_array = array;
pa->pa_capacity = capacity;
pa->pa_count = 0;
pa->pa_flags = 0;
pa->pa_version = 0;
} else if (array != NULL)
_PROP_FREE(array, M_PROP_ARRAY);
return (pa);
}
static bool
_prop_array_expand(prop_array_t pa, unsigned int capacity)
{
prop_object_t *array, *oarray;
/*
* Array must be WRITE-LOCKED.
*/
oarray = pa->pa_array;
array = _PROP_CALLOC(capacity * sizeof(*array), M_PROP_ARRAY);
if (array == NULL)
return (false);
if (oarray != NULL)
memcpy(array, oarray, pa->pa_capacity * sizeof(*array));
pa->pa_array = array;
pa->pa_capacity = capacity;
if (oarray != NULL)
_PROP_FREE(oarray, M_PROP_ARRAY);
return (true);
}
static prop_object_t
_prop_array_iterator_next_object_locked(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
prop_object_t po = NULL;
_PROP_ASSERT(prop_object_is_array(pa));
if (pa->pa_version != pai->pai_base.pi_version)
goto out; /* array changed during iteration */
_PROP_ASSERT(pai->pai_index <= pa->pa_count);
if (pai->pai_index == pa->pa_count)
goto out; /* we've iterated all objects */
po = pa->pa_array[pai->pai_index];
pai->pai_index++;
out:
return (po);
}
static prop_object_t
_prop_array_iterator_next_object(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa _PROP_ARG_UNUSED = pai->pai_base.pi_obj;
prop_object_t po;
_PROP_ASSERT(prop_object_is_array(pa));
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
po = _prop_array_iterator_next_object_locked(pai);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (po);
}
static void
_prop_array_iterator_reset_locked(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa));
pai->pai_index = 0;
pai->pai_base.pi_version = pa->pa_version;
}
static void
_prop_array_iterator_reset(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa _PROP_ARG_UNUSED = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa));
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
_prop_array_iterator_reset_locked(pai);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
}
/*
* prop_array_create --
* Create an empty array.
*/
prop_array_t
prop_array_create(void)
{
return (_prop_array_alloc(0));
}
/*
* prop_array_create_with_capacity --
* Create an array with the capacity to store N objects.
*/
prop_array_t
prop_array_create_with_capacity(unsigned int capacity)
{
return (_prop_array_alloc(capacity));
}
/*
* prop_array_copy --
* Copy an array. The new array has an initial capacity equal to
* the number of objects stored in the original array. The new
* array contains references to the original array's objects, not
* copies of those objects (i.e. a shallow copy).
*/
prop_array_t
prop_array_copy(prop_array_t opa)
{
prop_array_t pa;
prop_object_t po;
unsigned int idx;
if (! prop_object_is_array(opa))
return (NULL);
_PROP_RWLOCK_RDLOCK(opa->pa_rwlock);
pa = _prop_array_alloc(opa->pa_count);
if (pa != NULL) {
for (idx = 0; idx < opa->pa_count; idx++) {
po = opa->pa_array[idx];
prop_object_retain(po);
pa->pa_array[idx] = po;
}
pa->pa_count = opa->pa_count;
pa->pa_flags = opa->pa_flags;
}
_PROP_RWLOCK_UNLOCK(opa->pa_rwlock);
return (pa);
}
/*
* prop_array_copy_mutable --
* Like prop_array_copy(), but the resulting array is mutable.
*/
prop_array_t
prop_array_copy_mutable(prop_array_t opa)
{
prop_array_t pa;
pa = prop_array_copy(opa);
if (pa != NULL)
pa->pa_flags &= ~PA_F_IMMUTABLE;
return (pa);
}
/*
* prop_array_capacity --
* Return the capacity of the array.
*/
unsigned int
prop_array_capacity(prop_array_t pa)
{
unsigned int rv;
if (! prop_object_is_array(pa))
return (0);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = pa->pa_capacity;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_count --
* Return the number of objects stored in the array.
*/
unsigned int
prop_array_count(prop_array_t pa)
{
unsigned int rv;
if (! prop_object_is_array(pa))
return (0);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = pa->pa_count;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_ensure_capacity --
* Ensure that the array has the capacity to store the specified
* total number of objects (inluding the objects already stored
* in the array).
*/
bool
prop_array_ensure_capacity(prop_array_t pa, unsigned int capacity)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (capacity > pa->pa_capacity)
rv = _prop_array_expand(pa, capacity);
else
rv = true;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
static prop_object_iterator_t
_prop_array_iterator_locked(prop_array_t pa)
{
struct _prop_array_iterator *pai;
if (! prop_object_is_array(pa))
return (NULL);
pai = _PROP_CALLOC(sizeof(*pai), M_TEMP);
if (pai == NULL)
return (NULL);
pai->pai_base.pi_next_object = _prop_array_iterator_next_object;
pai->pai_base.pi_reset = _prop_array_iterator_reset;
prop_object_retain(pa);
pai->pai_base.pi_obj = pa;
_prop_array_iterator_reset_locked(pai);
return (&pai->pai_base);
}
/*
* prop_array_iterator --
* Return an iterator for the array. The array is retained by
* the iterator.
*/
prop_object_iterator_t
prop_array_iterator(prop_array_t pa)
{
prop_object_iterator_t pi;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
pi = _prop_array_iterator_locked(pa);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (pi);
}
/*
* prop_array_make_immutable --
* Make the array immutable.
*/
void
prop_array_make_immutable(prop_array_t pa)
{
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (prop_array_is_immutable(pa) == false)
pa->pa_flags |= PA_F_IMMUTABLE;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
}
/*
* prop_array_mutable --
* Returns true if the array is mutable.
*/
bool
prop_array_mutable(prop_array_t pa)
{
bool rv;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = prop_array_is_immutable(pa) == false;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_get --
* Return the object stored at the specified array index.
*/
prop_object_t
prop_array_get(prop_array_t pa, unsigned int idx)
{
prop_object_t po = NULL;
if (! prop_object_is_array(pa))
return (NULL);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
if (idx >= pa->pa_count)
goto out;
po = pa->pa_array[idx];
_PROP_ASSERT(po != NULL);
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (po);
}
static bool
_prop_array_add(prop_array_t pa, prop_object_t po)
{
/*
* Array must be WRITE-LOCKED.
*/
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
if (prop_array_is_immutable(pa) ||
(pa->pa_count == pa->pa_capacity &&
_prop_array_expand(pa, pa->pa_capacity + EXPAND_STEP) == false))
return (false);
prop_object_retain(po);
pa->pa_array[pa->pa_count++] = po;
pa->pa_version++;
return (true);
}
static bool
_prop_array_add_first(prop_array_t pa, prop_object_t po)
{
unsigned int cnt;
/*
* Array must be WRITE-LOCKED.
*/
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
if (prop_array_is_immutable(pa) ||
(pa->pa_count == pa->pa_capacity &&
_prop_array_expand(pa, pa->pa_capacity + EXPAND_STEP) == false))
return false;
prop_object_retain(po);
if (pa->pa_count) {
cnt = pa->pa_count+1;
/* move all stored elements to the right */
while (--cnt) {
prop_object_t opo = pa->pa_array[cnt-1];
_PROP_ASSERT(opo != NULL);
prop_object_retain(opo);
pa->pa_array[cnt] = opo;
prop_object_release(opo);
}
/* passed in object is now the first element */
pa->pa_array[0] = po;
pa->pa_version++;
pa->pa_count++;
} else {
pa->pa_array[pa->pa_count++] = po;
pa->pa_version++;
}
return true;
}
/*
* prop_array_set --
* Store a reference to an object at the specified array index.
* This method is not allowed to create holes in the array; the
* caller must either be setting the object just beyond the existing
* count or replacing an already existing object reference.
*/
bool
prop_array_set(prop_array_t pa, unsigned int idx, prop_object_t po)
{
prop_object_t opo;
bool rv = false;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (prop_array_is_immutable(pa))
goto out;
if (idx == pa->pa_count) {
rv = _prop_array_add(pa, po);
goto out;
}
_PROP_ASSERT(idx < pa->pa_count);
opo = pa->pa_array[idx];
_PROP_ASSERT(opo != NULL);
prop_object_retain(po);
pa->pa_array[idx] = po;
pa->pa_version++;
prop_object_release(opo);
rv = true;
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_add --
* Add a reference to an object to the specified array, appending
* to the end and growing the array's capacity, if necessary.
*/
bool
prop_array_add(prop_array_t pa, prop_object_t po)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
rv = _prop_array_add(pa, po);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_add_first --
* Add a reference to an object to the specified array, inserting it
* as first element, moving all objects to the right and growing the
* array's capacity, if necessary.
*/
bool
prop_array_add_first(prop_array_t pa, prop_object_t po)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
rv = _prop_array_add_first(pa, po);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_remove --
* Remove the reference to an object from an array at the specified
* index. The array will be compacted following the removal.
*/
void
prop_array_remove(prop_array_t pa, unsigned int idx)
{
prop_object_t po;
if (! prop_object_is_array(pa))
return;
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
_PROP_ASSERT(idx < pa->pa_count);
/* XXX Should this be a _PROP_ASSERT()? */
if (prop_array_is_immutable(pa)) {
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return;
}
po = pa->pa_array[idx];
_PROP_ASSERT(po != NULL);
for (++idx; idx < pa->pa_count; idx++)
pa->pa_array[idx - 1] = pa->pa_array[idx];
pa->pa_count--;
pa->pa_version++;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
prop_object_release(po);
}
/*
* prop_array_equals --
* Return true if the two arrays are equivalent. Note we do a
* by-value comparison of the objects in the array.
*/
bool
prop_array_equals(prop_array_t array1, prop_array_t array2)
{
if (!prop_object_is_array(array1) || !prop_object_is_array(array2))
return (false);
return (prop_object_equals(array1, array2));
}
/*
* prop_array_externalize --
* Externalize an array, return a NUL-terminated buffer
* containing the XML-style representation. The buffer is allocated
* with the M_TEMP memory type.
*/
char *
prop_array_externalize(prop_array_t pa)
{
struct _prop_object_externalize_context *ctx;
char *cp;
ctx = _prop_object_externalize_context_alloc();
if (ctx == NULL)
return (NULL);
if (_prop_object_externalize_header(ctx) == false ||
(*pa->pa_obj.po_type->pot_extern)(ctx, pa) == false ||
_prop_object_externalize_footer(ctx) == false) {
/* We are responsible for releasing the buffer. */
_PROP_FREE(ctx->poec_buf, M_TEMP);
_prop_object_externalize_context_free(ctx);
return (NULL);
}
cp = ctx->poec_buf;
_prop_object_externalize_context_free(ctx);
return (cp);
}
/*
* _prop_array_internalize --
* Parse an <array>...</array> and return the object created from the
* external representation.
*/
static bool _prop_array_internalize_body(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool
_prop_array_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
/* We don't currently understand any attributes. */
if (ctx->poic_tagattr != NULL)
return (true);
*obj = prop_array_create();
/*
* We are done if the create failed or no child elements exist.
*/
if (*obj == NULL || ctx->poic_is_empty_element)
return (true);
/*
* Opening tag is found, now continue to the first element.
*/
return (_prop_array_internalize_body(stack, obj, ctx));
}
static bool
_prop_array_internalize_continue(prop_stack_t stack,
prop_object_t *obj,
struct _prop_object_internalize_context *ctx,
void *data, prop_object_t child)
{
prop_array_t array;
_PROP_ASSERT(data == NULL);
if (child == NULL)
goto bad; /* Element could not be parsed. */
array = *obj;
if (prop_array_add(array, child) == false) {
prop_object_release(child);
goto bad;
}
prop_object_release(child);
/*
* Current element is processed and added, look for next.
*/
return (_prop_array_internalize_body(stack, obj, ctx));
bad:
prop_object_release(*obj);
*obj = NULL;
return (true);
}
static bool
_prop_array_internalize_body(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
prop_array_t array = *obj;
_PROP_ASSERT(array != NULL);
/* Fetch the next tag. */
if (_prop_object_internalize_find_tag(ctx, NULL,
_PROP_TAG_TYPE_EITHER) == false)
goto bad;
/* Check to see if this is the end of the array. */
if (_PROP_TAG_MATCH(ctx, "array") &&
ctx->poic_tag_type == _PROP_TAG_TYPE_END) {
/* It is, so don't iterate any further. */
return (true);
}
if (_prop_stack_push(stack, array,
_prop_array_internalize_continue, NULL, NULL))
return (false);
bad:
prop_object_release(array);
*obj = NULL;
return (true);
}
/*
* prop_array_internalize --
* Create an array by parsing the XML-style representation.
*/
prop_array_t
prop_array_internalize(const char *xml)
{
return _prop_generic_internalize(xml, "array");
}
/*
* prop_array_externalize_to_file --
* Externalize an array to the specified file.
*/
bool
prop_array_externalize_to_file(prop_array_t array, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0; /* XXXGCC -Wuninitialized [mips, ...] */
xml = prop_array_externalize(array);
if (xml == NULL)
return (false);
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), false);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
if (rv == false)
errno = save_errno;
return (rv);
}
/*
* prop_array_internalize_from_file --
* Internalize an array from a file.
*/
prop_array_t
prop_array_internalize_from_file(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_array_t array;
mf = _prop_object_internalize_map_file(fname);
if (mf == NULL)
return (NULL);
array = prop_array_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return (array);
}

View File

@@ -0,0 +1,266 @@
/* $NetBSD: prop_array_util.c,v 1.4 2012/07/27 09:10:59 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
/*
* Utility routines to make it more convenient to work with values
* stored in array.
*
* Note: There is no special magic going on here. We use the standard
* proplib(3) APIs to do all of this work. Any application could do
* exactly what we're doing here.
*/
#include "prop_object_impl.h" /* hide kernel vs. not-kernel vs. standalone */
#include <prop/proplib.h>
bool
prop_array_get_bool(prop_array_t array,
unsigned int indx,
bool *valp)
{
prop_bool_t b;
b = prop_array_get(array, indx);
if (prop_object_type(b) != PROP_TYPE_BOOL)
return (false);
*valp = prop_bool_true(b);
return (true);
}
bool
prop_array_set_bool(prop_array_t array,
unsigned int indx,
bool val)
{
prop_bool_t b;
int rv;
b = prop_bool_create(val);
if (b == NULL)
return (false);
rv = prop_array_set(array, indx, b);
prop_object_release(b);
return (rv);
}
#define TEMPLATE(size) \
bool \
prop_array_get_int ## size (prop_array_t array, \
unsigned int indx, \
int ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_array_get(array, indx); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) && \
prop_number_unsigned_integer_value(num) > \
/*CONSTCOND*/((size) == 8 ? INT8_MAX : \
(size) == 16 ? INT16_MAX : \
(size) == 32 ? INT32_MAX : INT64_MAX)) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (int ## size ## _t) prop_number_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_array_get_uint ## size (prop_array_t array, \
unsigned int indx, \
uint ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_array_get(array, indx); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) == false && \
prop_number_integer_value(num) < 0) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (uint ## size ## _t) \
prop_number_unsigned_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_array_set_int ## size (prop_array_t array, \
unsigned int indx, \
int ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_integer((int64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_array_set(array, indx, num); \
prop_object_release(num); \
\
return (rv); \
} \
\
bool \
prop_array_set_uint ## size (prop_array_t array, \
unsigned int indx, \
uint ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_unsigned_integer((uint64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_array_set(array, indx, num); \
prop_object_release(num); \
\
return (rv); \
} \
\
bool \
prop_array_add_int ## size (prop_array_t array, \
int ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_integer((int64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_array_add(array, num); \
prop_object_release(num); \
\
return (rv); \
} \
\
bool \
prop_array_add_uint ## size (prop_array_t array, \
uint ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_integer((int64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_array_add(array, num); \
prop_object_release(num); \
\
return (rv); \
}
TEMPLATE(8)
TEMPLATE(16)
TEMPLATE(32)
TEMPLATE(64)
#undef TEMPLATE
#define TEMPLATE(variant, qualifier) \
bool \
prop_array_get_cstring ## variant (prop_array_t array, \
unsigned int indx, \
qualifier char **cpp) \
{ \
prop_string_t str; \
\
str = prop_array_get(array, indx); \
if (prop_object_type(str) != PROP_TYPE_STRING) \
return (false); \
\
*cpp = prop_string_cstring ## variant (str); \
\
return (*cpp == NULL ? false : true); \
} \
\
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, \
unsigned int indx, \
const char *cp) \
{ \
prop_string_t str; \
int rv; \
\
str = prop_string_create_cstring ## variant (cp); \
if (str == NULL) \
return (false); \
rv = prop_array_set(array, indx, str); \
prop_object_release(str); \
\
return (rv); \
}
TEMPLATE(,)
TEMPLATE(_nocopy,const)
#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

@@ -0,0 +1,222 @@
/* $NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include <prop/prop_bool.h>
#include "prop_object_impl.h"
struct _prop_bool {
struct _prop_object pb_obj;
bool pb_value;
};
static struct _prop_bool _prop_bool_true;
static struct _prop_bool _prop_bool_false;
static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t, prop_object_t *);
static bool _prop_bool_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static const struct _prop_object_type _prop_object_type_bool = {
.pot_type = PROP_TYPE_BOOL,
.pot_free = _prop_bool_free,
.pot_extern = _prop_bool_externalize,
.pot_equals = _prop_bool_equals,
};
#define prop_object_is_bool(x) \
((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t stack, prop_object_t *obj)
{
/*
* This should never happen as we "leak" our initial reference
* count.
*/
/* XXX forced assertion failure? */
return (_PROP_OBJECT_FREE_DONE);
}
static bool
_prop_bool_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_bool_t pb = v;
return (_prop_object_externalize_empty_tag(ctx,
pb->pb_value ? "true" : "false"));
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_bool_t b1 = v1;
prop_bool_t b2 = v2;
if (! (prop_object_is_bool(b1) &&
prop_object_is_bool(b2)))
return (_PROP_OBJECT_EQUALS_FALSE);
/*
* Since we only ever allocate one true and one false,
* save ourselves a couple of memory operations.
*/
if (b1 == b2)
return (_PROP_OBJECT_EQUALS_TRUE);
else
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
_prop_bool_alloc(bool val)
{
prop_bool_t pb;
_PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
pb = val ? &_prop_bool_true : &_prop_bool_false;
prop_object_retain(pb);
return (pb);
}
/*
* prop_bool_create --
* Create a prop_bool_t and initialize it with the
* provided boolean value.
*/
prop_bool_t
prop_bool_create(bool val)
{
return (_prop_bool_alloc(val));
}
/*
* prop_bool_copy --
* Copy a prop_bool_t.
*/
prop_bool_t
prop_bool_copy(prop_bool_t opb)
{
if (! prop_object_is_bool(opb))
return (NULL);
/*
* Because we only ever allocate one true and one false, this
* can be reduced to a simple retain operation.
*/
prop_object_retain(opb);
return (opb);
}
/*
* prop_bool_true --
* Get the value of a prop_bool_t.
*/
bool
prop_bool_true(prop_bool_t pb)
{
if (! prop_object_is_bool(pb))
return (false);
return (pb->pb_value);
}
/*
* prop_bool_equals --
* Return true if the boolean values are equivalent.
*/
bool
prop_bool_equals(prop_bool_t b1, prop_bool_t b2)
{
if (!prop_object_is_bool(b1) || !prop_object_is_bool(b2))
return (false);
return (prop_object_equals(b1, b2));
}
/*
* _prop_bool_internalize --
* Parse a <true/> or <false/> and return the object created from
* the external representation.
*/
/* ARGSUSED */
bool
_prop_bool_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
bool val;
/* No attributes, and it must be an empty element. */
if (ctx->poic_tagattr != NULL ||
ctx->poic_is_empty_element == false)
return (true);
if (_PROP_TAG_MATCH(ctx, "true"))
val = true;
else {
_PROP_ASSERT(_PROP_TAG_MATCH(ctx, "false"));
val = false;
}
*obj = prop_bool_create(val);
return (true);
}

View File

@@ -0,0 +1,614 @@
/* $NetBSD: prop_data.c,v 1.13 2008/08/03 04:00:12 thorpej Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include <prop/prop_data.h>
#include "prop_object_impl.h"
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
struct _prop_data {
struct _prop_object pd_obj;
union {
void * pdu_mutable;
const void * pdu_immutable;
} pd_un;
#define pd_mutable pd_un.pdu_mutable
#define pd_immutable pd_un.pdu_immutable
size_t pd_size;
int pd_flags;
};
#define PD_F_NOCOPY 0x01
_PROP_POOL_INIT(_prop_data_pool, sizeof(struct _prop_data), "propdata")
static _prop_object_free_rv_t
_prop_data_free(prop_stack_t, prop_object_t *);
static bool _prop_data_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_data_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static const struct _prop_object_type _prop_object_type_data = {
.pot_type = PROP_TYPE_DATA,
.pot_free = _prop_data_free,
.pot_extern = _prop_data_externalize,
.pot_equals = _prop_data_equals,
};
#define prop_object_is_data(x) \
((x) != NULL && (x)->pd_obj.po_type == &_prop_object_type_data)
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_data_free(prop_stack_t stack, prop_object_t *obj)
{
prop_data_t pd = *obj;
if ((pd->pd_flags & PD_F_NOCOPY) == 0 && pd->pd_mutable != NULL)
_PROP_FREE(pd->pd_mutable, M_PROP_DATA);
_PROP_POOL_PUT(_prop_data_pool, pd);
return (_PROP_OBJECT_FREE_DONE);
}
static const char _prop_data_base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char _prop_data_pad64 = '=';
static bool
_prop_data_externalize(struct _prop_object_externalize_context *ctx, void *v)
{
prop_data_t pd = v;
size_t i, srclen;
const uint8_t *src;
uint8_t output[4];
uint8_t input[3];
if (pd->pd_size == 0)
return (_prop_object_externalize_empty_tag(ctx, "data"));
if (_prop_object_externalize_start_tag(ctx, "data") == false)
return (false);
for (src = pd->pd_immutable, srclen = pd->pd_size;
srclen > 2; srclen -= 3) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
output[0] = (uint32_t)input[0] >> 2;
output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
((uint32_t)input[1] >> 4);
output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
((uint32_t)input[2] >> 6);
output[3] = input[2] & 0x3f;
_PROP_ASSERT(output[0] < 64);
_PROP_ASSERT(output[1] < 64);
_PROP_ASSERT(output[2] < 64);
_PROP_ASSERT(output[3] < 64);
if (_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[0]]) == false ||
_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[1]]) == false ||
_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[2]]) == false ||
_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[3]]) == false)
return (false);
}
if (srclen != 0) {
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclen; i++)
input[i] = *src++;
output[0] = (uint32_t)input[0] >> 2;
output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
((uint32_t)input[1] >> 4);
output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
((uint32_t)input[2] >> 6);
_PROP_ASSERT(output[0] < 64);
_PROP_ASSERT(output[1] < 64);
_PROP_ASSERT(output[2] < 64);
if (_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[0]]) == false ||
_prop_object_externalize_append_char(ctx,
_prop_data_base64[output[1]]) == false ||
_prop_object_externalize_append_char(ctx,
srclen == 1 ? _prop_data_pad64
: _prop_data_base64[output[2]]) == false ||
_prop_object_externalize_append_char(ctx,
_prop_data_pad64) == false)
return (false);
}
if (_prop_object_externalize_end_tag(ctx, "data") == false)
return (false);
return (true);
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_data_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_data_t pd1 = v1;
prop_data_t pd2 = v2;
if (pd1 == pd2)
return (_PROP_OBJECT_EQUALS_TRUE);
if (pd1->pd_size != pd2->pd_size)
return (_PROP_OBJECT_EQUALS_FALSE);
if (pd1->pd_size == 0) {
_PROP_ASSERT(pd1->pd_immutable == NULL);
_PROP_ASSERT(pd2->pd_immutable == NULL);
return (_PROP_OBJECT_EQUALS_TRUE);
}
if (memcmp(pd1->pd_immutable, pd2->pd_immutable, pd1->pd_size) == 0)
return _PROP_OBJECT_EQUALS_TRUE;
else
return _PROP_OBJECT_EQUALS_FALSE;
}
static prop_data_t
_prop_data_alloc(void)
{
prop_data_t pd;
pd = _PROP_POOL_GET(_prop_data_pool);
if (pd != NULL) {
_prop_object_init(&pd->pd_obj, &_prop_object_type_data);
pd->pd_mutable = NULL;
pd->pd_size = 0;
pd->pd_flags = 0;
}
return (pd);
}
/*
* prop_data_create_data --
* Create a data container that contains a copy of the data.
*/
prop_data_t
prop_data_create_data(const void *v, size_t size)
{
prop_data_t pd;
void *nv;
pd = _prop_data_alloc();
if (pd != NULL && size != 0) {
nv = _PROP_MALLOC(size, M_PROP_DATA);
if (nv == NULL) {
prop_object_release(pd);
return (NULL);
}
memcpy(nv, v, size);
pd->pd_mutable = nv;
pd->pd_size = size;
}
return (pd);
}
/*
* prop_data_create_data_nocopy --
* Create an immutable data container that contains a refrence to the
* provided external data.
*/
prop_data_t
prop_data_create_data_nocopy(const void *v, size_t size)
{
prop_data_t pd;
pd = _prop_data_alloc();
if (pd != NULL) {
pd->pd_immutable = v;
pd->pd_size = size;
pd->pd_flags |= PD_F_NOCOPY;
}
return (pd);
}
/*
* prop_data_copy --
* Copy a data container. If the original data is external, then
* the copy is also references the same external data.
*/
prop_data_t
prop_data_copy(prop_data_t opd)
{
prop_data_t pd;
if (! prop_object_is_data(opd))
return (NULL);
pd = _prop_data_alloc();
if (pd != NULL) {
pd->pd_size = opd->pd_size;
pd->pd_flags = opd->pd_flags;
if (opd->pd_flags & PD_F_NOCOPY)
pd->pd_immutable = opd->pd_immutable;
else if (opd->pd_size != 0) {
void *nv = _PROP_MALLOC(pd->pd_size, M_PROP_DATA);
if (nv == NULL) {
prop_object_release(pd);
return (NULL);
}
memcpy(nv, opd->pd_immutable, opd->pd_size);
pd->pd_mutable = nv;
}
}
return (pd);
}
/*
* prop_data_size --
* Return the size of the data.
*/
size_t
prop_data_size(prop_data_t pd)
{
if (! prop_object_is_data(pd))
return (0);
return (pd->pd_size);
}
/*
* prop_data_data --
* Return a copy of the contents of the data container.
* The data is allocated with the M_TEMP malloc type.
* If the data container is empty, NULL is returned.
*/
void *
prop_data_data(prop_data_t pd)
{
void *v;
if (! prop_object_is_data(pd))
return (NULL);
if (pd->pd_size == 0) {
_PROP_ASSERT(pd->pd_immutable == NULL);
return (NULL);
}
_PROP_ASSERT(pd->pd_immutable != NULL);
v = _PROP_MALLOC(pd->pd_size, M_TEMP);
if (v != NULL)
memcpy(v, pd->pd_immutable, pd->pd_size);
return (v);
}
/*
* prop_data_data_nocopy --
* Return an immutable reference to the contents of the data
* container.
*/
const void *
prop_data_data_nocopy(prop_data_t pd)
{
if (! prop_object_is_data(pd))
return (NULL);
_PROP_ASSERT((pd->pd_size == 0 && pd->pd_immutable == NULL) ||
(pd->pd_size != 0 && pd->pd_immutable != NULL));
return (pd->pd_immutable);
}
/*
* prop_data_equals --
* Return true if two strings are equivalent.
*/
bool
prop_data_equals(prop_data_t pd1, prop_data_t pd2)
{
if (!prop_object_is_data(pd1) || !prop_object_is_data(pd2))
return (false);
return (prop_object_equals(pd1, pd2));
}
/*
* prop_data_equals_data --
* Return true if the contained data is equivalent to the specified
* external data.
*/
bool
prop_data_equals_data(prop_data_t pd, const void *v, size_t size)
{
if (! prop_object_is_data(pd))
return (false);
if (pd->pd_size != size)
return (false);
return (memcmp(pd->pd_immutable, v, size) == 0);
}
static bool
_prop_data_internalize_decode(struct _prop_object_internalize_context *ctx,
uint8_t *target, size_t targsize, size_t *sizep,
const char **cpp)
{
const char *src;
size_t tarindex;
int state, ch;
const char *pos;
state = 0;
tarindex = 0;
src = ctx->poic_cp;
for (;;) {
ch = (unsigned char) *src++;
if (_PROP_EOF(ch))
return (false);
if (_PROP_ISSPACE(ch))
continue;
if (ch == '<') {
src--;
break;
}
if (ch == _prop_data_pad64)
break;
pos = strchr(_prop_data_base64, ch);
if (pos == NULL)
return (false);
switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (false);
target[tarindex] =
(uint8_t)((pos - _prop_data_base64) << 2);
}
state = 1;
break;
case 1:
if (target) {
if (tarindex + 1 >= targsize)
return (false);
target[tarindex] |=
(uint32_t)(pos - _prop_data_base64) >> 4;
target[tarindex + 1] =
(uint8_t)(((pos - _prop_data_base64) & 0xf)
<< 4);
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex + 1 >= targsize)
return (false);
target[tarindex] |=
(uint32_t)(pos - _prop_data_base64) >> 2;
target[tarindex + 1] =
(uint8_t)(((pos - _prop_data_base64)
& 0x3) << 6);
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (false);
target[tarindex] |= (uint8_t)
(pos - _prop_data_base64);
}
tarindex++;
state = 0;
break;
default:
_PROP_ASSERT(/*CONSTCOND*/0);
}
}
/*
* We are done decoding the Base64 characters. Let's see if we
* ended up on a byte boundary and/or with unrecognized trailing
* characters.
*/
if (ch == _prop_data_pad64) {
ch = (unsigned char) *src; /* src already advanced */
if (_PROP_EOF(ch))
return (false);
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (false);
case 2: /* Valid, one byte of info */
/* Skip whitespace */
for (ch = (unsigned char) *src++;
ch != '<'; ch = (unsigned char) *src++) {
if (_PROP_EOF(ch))
return (false);
if (!_PROP_ISSPACE(ch))
break;
}
/* Make sure there is another trailing = */
if (ch != _prop_data_pad64)
return (false);
/* FALLTHROUGH */
case 3: /* Valid, two bytes of info */
/*
* We know this char is a =. Is there anything but
* whitespace after it?
*/
for (ch = (unsigned char) *src++;
ch != '<'; ch = (unsigned char) *src++) {
if (_PROP_EOF(ch))
return (false);
if (!_PROP_ISSPACE(ch))
return (false);
}
/* back up to '<' */
src--;
}
} else {
/*
* We ended by seeing the end of the Base64 string. Make
* sure there are no partial bytes lying around.
*/
if (state != 0)
return (false);
}
_PROP_ASSERT(*src == '<');
if (sizep != NULL)
*sizep = tarindex;
if (cpp != NULL)
*cpp = src;
return (true);
}
/*
* _prop_data_internalize --
* Parse a <data>...</data> and return the object created from the
* external representation.
*/
/* strtoul is used for parsing, enforce. */
typedef int PROP_DATA_ASSERT[/* CONSTCOND */sizeof(size_t) == sizeof(unsigned long) ? 1 : -1];
/* ARGSUSED */
bool
_prop_data_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
prop_data_t data;
uint8_t *buf;
size_t len, alen;
/*
* We don't accept empty elements.
* This actually only checks for the node to be <data/>
* (Which actually causes another error if found.)
*/
if (ctx->poic_is_empty_element)
return (true);
/*
* If we got a "size" attribute, get the size of the data blob
* from that. Otherwise, we have to figure it out from the base64.
*/
if (ctx->poic_tagattr != NULL) {
char *cp;
if (!_PROP_TAGATTR_MATCH(ctx, "size") ||
ctx->poic_tagattrval_len == 0)
return (true);
errno = 0;
len = strtoul(ctx->poic_tagattrval, &cp, 0);
if (len == ULONG_MAX && errno == ERANGE)
return (true);
if (cp != ctx->poic_tagattrval + ctx->poic_tagattrval_len)
return (true);
_PROP_ASSERT(*cp == '\"');
} else if (_prop_data_internalize_decode(ctx, NULL, 0, &len,
NULL) == false)
return (true);
if (len >= SIZE_MAX)
len = 1;
/*
* Always allocate one extra in case we don't land on an even byte
* boundary during the decode.
*/
buf = _PROP_MALLOC(len + 1, M_PROP_DATA);
if (buf == NULL)
return (true);
if (_prop_data_internalize_decode(ctx, buf, len + 1, &alen,
&ctx->poic_cp) == false) {
_PROP_FREE(buf, M_PROP_DATA);
return (true);
}
if (alen != len) {
_PROP_FREE(buf, M_PROP_DATA);
return (true);
}
if (_prop_object_internalize_find_tag(ctx, "data",
_PROP_TAG_TYPE_END) == false) {
_PROP_FREE(buf, M_PROP_DATA);
return (true);
}
data = _prop_data_alloc();
if (data == NULL) {
_PROP_FREE(buf, M_PROP_DATA);
return (true);
}
/*
* Handle alternate type of empty node.
* XML document could contain open/close tags, yet still be empty.
*/
if (alen == 0) {
_PROP_FREE(buf, M_PROP_DATA);
data->pd_mutable = NULL;
} else {
data->pd_mutable = buf;
}
data->pd_size = len;
*obj = data;
return (true);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
/*
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*
* Note: There is no special magic going on here. We use the standard
* proplib(3) APIs to do all of this work. Any application could do
* exactly what we're doing here.
*/
#include <prop/proplib.h>
#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
prop_dictionary_get_bool(prop_dictionary_t dict,
const char *key,
bool *valp)
{
prop_bool_t b;
b = prop_dictionary_get(dict, key);
if (prop_object_type(b) != PROP_TYPE_BOOL)
return (false);
*valp = prop_bool_true(b);
return (true);
}
bool
prop_dictionary_set_bool(prop_dictionary_t dict,
const char *key,
bool val)
{
prop_bool_t b;
int rv;
b = prop_bool_create(val);
if (b == NULL)
return (false);
rv = prop_dictionary_set(dict, key, b);
prop_object_release(b);
return (rv);
}
#define TEMPLATE(size) \
bool \
prop_dictionary_get_int ## size (prop_dictionary_t dict, \
const char *key, \
int ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_dictionary_get(dict, key); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) && \
prop_number_unsigned_integer_value(num) > \
/*CONSTCOND*/((size) == 8 ? INT8_MAX : \
(size) == 16 ? INT16_MAX : \
(size) == 32 ? INT32_MAX : INT64_MAX)) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (int ## size ## _t) prop_number_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_dictionary_get_uint ## size (prop_dictionary_t dict, \
const char *key, \
uint ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_dictionary_get(dict, key); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) == false && \
prop_number_integer_value(num) < 0) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (uint ## size ## _t) \
prop_number_unsigned_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_dictionary_set_int ## size (prop_dictionary_t dict, \
const char *key, \
int ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_integer((int64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, num); \
prop_object_release(num); \
\
return (rv); \
} \
\
bool \
prop_dictionary_set_uint ## size (prop_dictionary_t dict, \
const char *key, \
uint ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_unsigned_integer((uint64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, num); \
prop_object_release(num); \
\
return (rv); \
}
TEMPLATE(8)
TEMPLATE(16)
TEMPLATE(32)
TEMPLATE(64)
#undef TEMPLATE
#define TEMPLATE(variant, qualifier) \
bool \
prop_dictionary_get_cstring ## variant (prop_dictionary_t dict, \
const char *key, \
qualifier char **cpp) \
{ \
prop_string_t str; \
\
str = prop_dictionary_get(dict, key); \
if (prop_object_type(str) != PROP_TYPE_STRING) \
return (false); \
\
*cpp = prop_string_cstring ## variant (str); \
\
return (*cpp == NULL ? false : true); \
} \
\
bool \
prop_dictionary_set_cstring ## variant (prop_dictionary_t dict, \
const char *key, \
const char *cp) \
{ \
prop_string_t str; \
int rv; \
\
str = prop_string_create_cstring ## variant (cp); \
if (str == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, str); \
prop_object_release(str); \
\
return (rv); \
}
TEMPLATE(,)
TEMPLATE(_nocopy,const)
#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

@@ -0,0 +1,159 @@
/* $NetBSD: prop_ingest.c,v 1.5 2014/09/05 05:19:24 matt Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include "prop_object_impl.h"
#include <prop/proplib.h>
struct _prop_ingest_context {
prop_ingest_error_t pic_error;
prop_type_t pic_type;
const char * pic_key;
void * pic_private;
};
/*
* prop_ingest_context_alloc --
* Allocate and initialize an ingest context.
*/
prop_ingest_context_t
prop_ingest_context_alloc(void *xprivate)
{
prop_ingest_context_t ctx;
ctx = _PROP_MALLOC(sizeof(*ctx), M_TEMP);
if (ctx != NULL) {
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
ctx->pic_type = PROP_TYPE_UNKNOWN;
ctx->pic_key = NULL;
ctx->pic_private = xprivate;
}
return (ctx);
}
/*
* prop_ingest_context_free --
* Free an ingest context.
*/
void
prop_ingest_context_free(prop_ingest_context_t ctx)
{
_PROP_FREE(ctx, M_TEMP);
}
/*
* prop_ingest_context_error --
* Get the error code from an ingest context.
*/
prop_ingest_error_t
prop_ingest_context_error(prop_ingest_context_t ctx)
{
return (ctx->pic_error);
}
/*
* prop_ingest_context_type --
* Return the type of last object visisted by an ingest context.
*/
prop_type_t
prop_ingest_context_type(prop_ingest_context_t ctx)
{
return (ctx->pic_type);
}
/*
* prop_ingest_context_key --
* Return the last key looked up by an ingest context.
*/
const char *
prop_ingest_context_key(prop_ingest_context_t ctx)
{
return (ctx->pic_key);
}
/*
* prop_ingest_context_private --
* Return the caller-private data associated with an ingest context.
*/
void *
prop_ingest_context_private(prop_ingest_context_t ctx)
{
return (ctx->pic_private);
}
/*
* prop_dictionary_ingest --
* Ingest a dictionary using handlers for each object to translate
* into an arbitrary binary format.
*/
bool
prop_dictionary_ingest(prop_dictionary_t dict,
const prop_ingest_table_entry rules[],
prop_ingest_context_t ctx)
{
const prop_ingest_table_entry *pite;
prop_object_t obj;
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
for (pite = rules; pite->pite_key != NULL; pite++) {
ctx->pic_key = pite->pite_key;
obj = prop_dictionary_get(dict, pite->pite_key);
ctx->pic_type = prop_object_type(obj);
if (obj == NULL) {
if (pite->pite_flags & PROP_INGEST_FLAG_OPTIONAL) {
if ((*pite->pite_handler)(ctx, NULL) == false) {
ctx->pic_error =
PROP_INGEST_ERROR_HANDLER_FAILED;
return (false);
}
continue;
}
ctx->pic_error = PROP_INGEST_ERROR_NO_KEY;
return (false);
}
if (ctx->pic_type != pite->pite_type &&
pite->pite_type != PROP_TYPE_UNKNOWN) {
ctx->pic_error = PROP_INGEST_ERROR_WRONG_TYPE;
return (false);
}
if ((*pite->pite_handler)(ctx, obj) == false) {
ctx->pic_error = PROP_INGEST_ERROR_HANDLER_FAILED;
return (false);
}
}
return (true);
}

View File

@@ -0,0 +1,584 @@
/* $NetBSD: prop_number.c,v 1.27 2014/09/05 05:19:24 matt Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include <prop/prop_number.h>
#include "prop_object_impl.h"
#include "prop_rb_impl.h"
#include <errno.h>
#include <stdlib.h>
struct _prop_number_value {
union {
int64_t pnu_signed;
uint64_t pnu_unsigned;
} pnv_un;
#define pnv_signed pnv_un.pnu_signed
#define pnv_unsigned pnv_un.pnu_unsigned
unsigned int pnv_is_unsigned :1,
:31;
};
struct _prop_number {
struct _prop_object pn_obj;
struct rb_node pn_link;
struct _prop_number_value pn_value;
};
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
static _prop_object_free_rv_t
_prop_number_free(prop_stack_t, prop_object_t *);
static bool _prop_number_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_number_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static void _prop_number_lock(void);
static void _prop_number_unlock(void);
static const struct _prop_object_type _prop_object_type_number = {
.pot_type = PROP_TYPE_NUMBER,
.pot_free = _prop_number_free,
.pot_extern = _prop_number_externalize,
.pot_equals = _prop_number_equals,
.pot_lock = _prop_number_lock,
.pot_unlock = _prop_number_unlock,
};
#define prop_object_is_number(x) \
((x) != NULL && (x)->pn_obj.po_type == &_prop_object_type_number)
/*
* Number objects are immutable, and we are likely to have many number
* objects that have the same value. So, to save memory, we unique'ify
* numbers so we only have one copy of each.
*/
static int
_prop_number_compare_values(const struct _prop_number_value *pnv1,
const struct _prop_number_value *pnv2)
{
/* Signed numbers are sorted before unsigned numbers. */
if (pnv1->pnv_is_unsigned) {
if (! pnv2->pnv_is_unsigned)
return (1);
if (pnv1->pnv_unsigned < pnv2->pnv_unsigned)
return (-1);
if (pnv1->pnv_unsigned > pnv2->pnv_unsigned)
return (1);
return (0);
}
if (pnv2->pnv_is_unsigned)
return (-1);
if (pnv1->pnv_signed < pnv2->pnv_signed)
return (-1);
if (pnv1->pnv_signed > pnv2->pnv_signed)
return (1);
return (0);
}
static int
/*ARGSUSED*/
_prop_number_rb_compare_nodes(void *ctx _PROP_ARG_UNUSED,
const void *n1, const void *n2)
{
const struct _prop_number *pn1 = n1;
const struct _prop_number *pn2 = n2;
return _prop_number_compare_values(&pn1->pn_value, &pn2->pn_value);
}
static int
/*ARGSUSED*/
_prop_number_rb_compare_key(void *ctx _PROP_ARG_UNUSED,
const void *n, const void *v)
{
const struct _prop_number *pn = n;
const struct _prop_number_value *pnv = v;
return _prop_number_compare_values(&pn->pn_value, pnv);
}
static const rb_tree_ops_t _prop_number_rb_tree_ops = {
.rbto_compare_nodes = _prop_number_rb_compare_nodes,
.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;
_PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex)
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_number_free(prop_stack_t stack, prop_object_t *obj)
{
prop_number_t pn = *obj;
_prop_rb_tree_remove_node(&_prop_number_tree, pn);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (_PROP_OBJECT_FREE_DONE);
}
_PROP_ONCE_DECL(_prop_number_init_once)
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);
}
static void
_prop_number_unlock(void)
{
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
}
static bool
_prop_number_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_number_t pn = v;
char tmpstr[32];
/*
* For unsigned numbers, we output in hex. For signed numbers,
* we output in decimal.
*/
if (pn->pn_value.pnv_is_unsigned)
snprintf(tmpstr, sizeof(tmpstr), "%" PRIu64,
pn->pn_value.pnv_unsigned);
else
snprintf(tmpstr, sizeof(tmpstr), "%" PRIi64,
pn->pn_value.pnv_signed);
if (_prop_object_externalize_start_tag(ctx, "integer") == false ||
_prop_object_externalize_append_cstring(ctx, tmpstr) == false ||
_prop_object_externalize_end_tag(ctx, "integer") == false)
return (false);
return (true);
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_number_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_number_t num1 = v1;
prop_number_t num2 = v2;
/*
* There is only ever one copy of a number object at any given
* time, so we can reduce this to a simple pointer equality check
* in the common case.
*/
if (num1 == num2)
return (_PROP_OBJECT_EQUALS_TRUE);
/*
* If the numbers are the same signed-ness, then we know they
* cannot be equal because they would have had pointer equality.
*/
if (num1->pn_value.pnv_is_unsigned == num2->pn_value.pnv_is_unsigned)
return (_PROP_OBJECT_EQUALS_FALSE);
/*
* We now have one signed value and one unsigned value. We can
* compare them iff:
* - The unsigned value is not larger than the signed value
* can represent.
* - The signed value is not smaller than the unsigned value
* can represent.
*/
if (num1->pn_value.pnv_is_unsigned) {
/*
* num1 is unsigned and num2 is signed.
*/
if (num1->pn_value.pnv_unsigned > INT64_MAX)
return (_PROP_OBJECT_EQUALS_FALSE);
if (num2->pn_value.pnv_signed < 0)
return (_PROP_OBJECT_EQUALS_FALSE);
} else {
/*
* num1 is signed and num2 is unsigned.
*/
if (num1->pn_value.pnv_signed < 0)
return (_PROP_OBJECT_EQUALS_FALSE);
if (num2->pn_value.pnv_unsigned > INT64_MAX)
return (_PROP_OBJECT_EQUALS_FALSE);
}
if (num1->pn_value.pnv_signed == num2->pn_value.pnv_signed)
return _PROP_OBJECT_EQUALS_TRUE;
else
return _PROP_OBJECT_EQUALS_FALSE;
}
static prop_number_t
_prop_number_alloc(const struct _prop_number_value *pnv)
{
prop_number_t opn, pn, rpn;
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_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_number_tree_mutex);
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (opn);
}
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
/*
* Not in the tree. Create it now.
*/
pn = _PROP_POOL_GET(_prop_number_pool);
if (pn == NULL)
return (NULL);
_prop_object_init(&pn->pn_obj, &_prop_object_type_number);
pn->pn_value = *pnv;
/*
* We dropped the mutex when we allocated the new object, so
* we have to check again if it is in the tree.
*/
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (opn);
}
rpn = _prop_rb_tree_insert_node(&_prop_number_tree, pn);
_PROP_ASSERT(rpn == pn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (rpn);
}
/*
* prop_number_create_integer --
* Create a prop_number_t and initialize it with the
* provided integer value.
*/
prop_number_t
prop_number_create_integer(int64_t val)
{
struct _prop_number_value pnv;
memset(&pnv, 0, sizeof(pnv));
pnv.pnv_signed = val;
pnv.pnv_is_unsigned = false;
return (_prop_number_alloc(&pnv));
}
/*
* prop_number_create_unsigned_integer --
* Create a prop_number_t and initialize it with the
* provided unsigned integer value.
*/
prop_number_t
prop_number_create_unsigned_integer(uint64_t val)
{
struct _prop_number_value pnv;
memset(&pnv, 0, sizeof(pnv));
pnv.pnv_unsigned = val;
pnv.pnv_is_unsigned = true;
return (_prop_number_alloc(&pnv));
}
/*
* prop_number_copy --
* Copy a prop_number_t.
*/
prop_number_t
prop_number_copy(prop_number_t opn)
{
if (! prop_object_is_number(opn))
return (NULL);
/*
* Because we only ever allocate one object for any given
* value, this can be reduced to a simple retain operation.
*/
prop_object_retain(opn);
return (opn);
}
/*
* prop_number_unsigned --
* Returns true if the prop_number_t has an unsigned value.
*/
bool
prop_number_unsigned(prop_number_t pn)
{
return (pn->pn_value.pnv_is_unsigned);
}
/*
* prop_number_size --
* Return the size, in bits, required to hold the value of
* the specified number.
*/
int
prop_number_size(prop_number_t pn)
{
struct _prop_number_value *pnv;
if (! prop_object_is_number(pn))
return (0);
pnv = &pn->pn_value;
if (pnv->pnv_is_unsigned) {
if (pnv->pnv_unsigned > UINT32_MAX)
return (64);
if (pnv->pnv_unsigned > UINT16_MAX)
return (32);
if (pnv->pnv_unsigned > UINT8_MAX)
return (16);
return (8);
}
if (pnv->pnv_signed > INT32_MAX || pnv->pnv_signed < INT32_MIN)
return (64);
if (pnv->pnv_signed > INT16_MAX || pnv->pnv_signed < INT16_MIN)
return (32);
if (pnv->pnv_signed > INT8_MAX || pnv->pnv_signed < INT8_MIN)
return (16);
return (8);
}
/*
* prop_number_integer_value --
* Get the integer value of a prop_number_t.
*/
int64_t
prop_number_integer_value(prop_number_t pn)
{
/*
* XXX Impossible to distinguish between "not a prop_number_t"
* XXX and "prop_number_t has a value of 0".
*/
if (! prop_object_is_number(pn))
return (0);
return (pn->pn_value.pnv_signed);
}
/*
* prop_number_unsigned_integer_value --
* Get the unsigned integer value of a prop_number_t.
*/
uint64_t
prop_number_unsigned_integer_value(prop_number_t pn)
{
/*
* XXX Impossible to distinguish between "not a prop_number_t"
* XXX and "prop_number_t has a value of 0".
*/
if (! prop_object_is_number(pn))
return (0);
return (pn->pn_value.pnv_unsigned);
}
/*
* prop_number_equals --
* Return true if two numbers are equivalent.
*/
bool
prop_number_equals(prop_number_t num1, prop_number_t num2)
{
if (!prop_object_is_number(num1) || !prop_object_is_number(num2))
return (false);
return (prop_object_equals(num1, num2));
}
/*
* prop_number_equals_integer --
* Return true if the number is equivalent to the specified integer.
*/
bool
prop_number_equals_integer(prop_number_t pn, int64_t val)
{
if (! prop_object_is_number(pn))
return (false);
if (pn->pn_value.pnv_is_unsigned &&
(pn->pn_value.pnv_unsigned > INT64_MAX || val < 0))
return (false);
return (pn->pn_value.pnv_signed == val);
}
/*
* prop_number_equals_unsigned_integer --
* Return true if the number is equivalent to the specified
* unsigned integer.
*/
bool
prop_number_equals_unsigned_integer(prop_number_t pn, uint64_t val)
{
if (! prop_object_is_number(pn))
return (false);
if (! pn->pn_value.pnv_is_unsigned &&
(pn->pn_value.pnv_signed < 0 || val > INT64_MAX))
return (false);
return (pn->pn_value.pnv_unsigned == val);
}
static bool
_prop_number_internalize_unsigned(struct _prop_object_internalize_context *ctx,
struct _prop_number_value *pnv)
{
char *cp;
_PROP_ASSERT(/*CONSTCOND*/sizeof(unsigned long long) ==
sizeof(uint64_t));
errno = 0;
pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0);
if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE)
return (false);
pnv->pnv_is_unsigned = true;
ctx->poic_cp = cp;
return (true);
}
static bool
_prop_number_internalize_signed(struct _prop_object_internalize_context *ctx,
struct _prop_number_value *pnv)
{
char *cp;
_PROP_ASSERT(/*CONSTCOND*/sizeof(long long) == sizeof(int64_t));
errno = 0;
pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0);
if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) &&
errno == ERANGE)
return (false);
pnv->pnv_is_unsigned = false;
ctx->poic_cp = cp;
return (true);
}
/*
* _prop_number_internalize --
* Parse a <number>...</number> and return the object created from
* the external representation.
*/
/* ARGSUSED */
bool
_prop_number_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
struct _prop_number_value pnv;
memset(&pnv, 0, sizeof(pnv));
/* No attributes, no empty elements. */
if (ctx->poic_tagattr != NULL || ctx->poic_is_empty_element)
return (true);
/*
* If the first character is '-', then we treat as signed.
* If the first two characters are "0x" (i.e. the number is
* in hex), then we treat as unsigned. Otherwise, we try
* signed first, and if that fails (presumably due to ERANGE),
* then we switch to unsigned.
*/
if (ctx->poic_cp[0] == '-') {
if (_prop_number_internalize_signed(ctx, &pnv) == false)
return (true);
} else if (ctx->poic_cp[0] == '0' && ctx->poic_cp[1] == 'x') {
if (_prop_number_internalize_unsigned(ctx, &pnv) == false)
return (true);
} else {
if (_prop_number_internalize_signed(ctx, &pnv) == false &&
_prop_number_internalize_unsigned(ctx, &pnv) == false)
return (true);
}
if (_prop_object_internalize_find_tag(ctx, "integer",
_PROP_TAG_TYPE_END) == false)
return (true);
*obj = _prop_number_alloc(&pnv);
return (true);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,336 @@
/* $NetBSD: prop_object_impl.h,v 1.31 2012/07/27 09:10:59 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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 _PROPLIB_PROP_OBJECT_IMPL_H_
#define _PROPLIB_PROP_OBJECT_IMPL_H_
#include <inttypes.h>
#include "prop_stack.h"
struct _prop_object_externalize_context {
char * poec_buf; /* string buffer */
size_t poec_capacity; /* capacity of buffer */
size_t poec_len; /* current length of string */
unsigned int poec_depth; /* nesting depth */
};
bool _prop_object_externalize_start_tag(
struct _prop_object_externalize_context *,
const char *);
bool _prop_object_externalize_end_tag(
struct _prop_object_externalize_context *,
const char *);
bool _prop_object_externalize_empty_tag(
struct _prop_object_externalize_context *,
const char *);
bool _prop_object_externalize_append_cstring(
struct _prop_object_externalize_context *,
const char *);
bool _prop_object_externalize_append_encoded_cstring(
struct _prop_object_externalize_context *,
const char *);
bool _prop_object_externalize_append_char(
struct _prop_object_externalize_context *,
unsigned char);
bool _prop_object_externalize_header(
struct _prop_object_externalize_context *);
bool _prop_object_externalize_footer(
struct _prop_object_externalize_context *);
struct _prop_object_externalize_context *
_prop_object_externalize_context_alloc(void);
void _prop_object_externalize_context_free(
struct _prop_object_externalize_context *);
typedef enum {
_PROP_TAG_TYPE_START, /* e.g. <dict> */
_PROP_TAG_TYPE_END, /* e.g. </dict> */
_PROP_TAG_TYPE_EITHER
} _prop_tag_type_t;
struct _prop_object_internalize_context {
const char *poic_xml;
const char *poic_cp;
const char *poic_tag_start;
const char *poic_tagname;
size_t poic_tagname_len;
const char *poic_tagattr;
size_t poic_tagattr_len;
const char *poic_tagattrval;
size_t poic_tagattrval_len;
bool poic_is_empty_element;
_prop_tag_type_t poic_tag_type;
};
typedef enum {
_PROP_OBJECT_FREE_DONE,
_PROP_OBJECT_FREE_RECURSE,
_PROP_OBJECT_FREE_FAILED
} _prop_object_free_rv_t;
typedef enum {
_PROP_OBJECT_EQUALS_FALSE,
_PROP_OBJECT_EQUALS_TRUE,
_PROP_OBJECT_EQUALS_RECURSE
} _prop_object_equals_rv_t;
#define _PROP_EOF(c) ((c) == '\0')
#define _PROP_ISSPACE(c) \
((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
#define _PROP_TAG_MATCH(ctx, t) \
_prop_object_internalize_match((ctx)->poic_tagname, \
(ctx)->poic_tagname_len, \
(t), strlen(t))
#define _PROP_TAGATTR_MATCH(ctx, a) \
_prop_object_internalize_match((ctx)->poic_tagattr, \
(ctx)->poic_tagattr_len, \
(a), strlen(a))
#define _PROP_TAGATTRVAL_MATCH(ctx, a) \
_prop_object_internalize_match((ctx)->poic_tagattrval, \
(ctx)->poic_tagattrval_len,\
(a), strlen(a))
bool _prop_object_internalize_find_tag(
struct _prop_object_internalize_context *,
const char *, _prop_tag_type_t);
bool _prop_object_internalize_match(const char *, size_t,
const char *, size_t);
prop_object_t _prop_object_internalize_by_tag(
struct _prop_object_internalize_context *);
bool _prop_object_internalize_decode_string(
struct _prop_object_internalize_context *,
char *, size_t, size_t *, const char **);
prop_object_t _prop_generic_internalize(const char *, const char *);
struct _prop_object_internalize_context *
_prop_object_internalize_context_alloc(const char *);
void _prop_object_internalize_context_free(
struct _prop_object_internalize_context *);
bool _prop_object_externalize_write_file(const char *,
const char *, size_t, bool);
struct _prop_object_internalize_mapped_file {
char * poimf_xml;
size_t poimf_mapsize;
};
struct _prop_object_internalize_mapped_file *
_prop_object_internalize_map_file(const char *);
void _prop_object_internalize_unmap_file(
struct _prop_object_internalize_mapped_file *);
typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
typedef bool (*prop_object_internalizer_continue_t)(prop_stack_t,
prop_object_t *,
struct _prop_object_internalize_context *,
void *, prop_object_t);
/* These are here because they're required by shared code. */
bool _prop_array_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_bool_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_data_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_dictionary_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_number_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_string_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
struct _prop_object_type {
/* type indicator */
uint32_t pot_type;
/* func to free object */
_prop_object_free_rv_t
(*pot_free)(prop_stack_t, prop_object_t *);
/*
* func to free the child returned by pot_free with stack == NULL.
*
* Must be implemented if pot_free can return anything other than
* _PROP_OBJECT_FREE_DONE.
*/
void (*pot_emergency_free)(prop_object_t);
/* func to externalize object */
bool (*pot_extern)(struct _prop_object_externalize_context *,
void *);
/* func to test quality */
_prop_object_equals_rv_t
(*pot_equals)(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
/*
* func to finish equality iteration.
*
* Must be implemented if pot_equals can return
* _PROP_OBJECT_EQUALS_RECURSE
*/
void (*pot_equals_finish)(prop_object_t, prop_object_t);
void (*pot_lock)(void);
void (*pot_unlock)(void);
};
struct _prop_object {
const struct _prop_object_type *po_type;/* type descriptor */
uint32_t po_refcnt; /* reference count */
};
void _prop_object_init(struct _prop_object *,
const struct _prop_object_type *);
void _prop_object_fini(struct _prop_object *);
struct _prop_object_iterator {
prop_object_t (*pi_next_object)(void *);
void (*pi_reset)(void *);
prop_object_t pi_obj;
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)
/*
* proplib in user space...
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#define _PROP_ASSERT(x) /*LINTED*/assert(x)
#define _PROP_MALLOC(s, t) malloc((s))
#define _PROP_CALLOC(s, t) calloc(1, (s))
#define _PROP_REALLOC(v, s, t) realloc((v), (s))
#define _PROP_FREE(v, t) free((v))
#define _PROP_POOL_GET(p) malloc((p))
#define _PROP_POOL_PUT(p, v) free((v))
#define _PROP_POOL_INIT(p, s, d) static const size_t p = s;
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
/*
* Use pthread mutexes everywhere else.
*/
#include <pthread.h>
#define _PROP_MUTEX_DECL_STATIC(x) static pthread_mutex_t x;
#define _PROP_MUTEX_INIT(x) pthread_mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
#define _PROP_RWLOCK_DECL(x) pthread_rwlock_t x ;
#define _PROP_RWLOCK_INIT(x) pthread_rwlock_init(&(x), NULL)
#define _PROP_RWLOCK_RDLOCK(x) pthread_rwlock_rdlock(&(x))
#define _PROP_RWLOCK_WRLOCK(x) pthread_rwlock_wrlock(&(x))
#define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(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)
#ifndef HAVE_ATOMICS /* NO ATOMIC SUPPORT, USE A MUTEX */
#define _PROP_NEED_REFCNT_MTX
#define _PROP_ATOMIC_INC32(x) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
(*(x))++; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32(x) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
(*(x))--; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_INC32_NV(x, v) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
v = ++(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32_NV(x, v) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
v = --(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#else /* GCC ATOMIC BUILTINS */
#define _PROP_ATOMIC_INC32(x) \
do { \
(void)__sync_fetch_and_add(x, 1); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32(x) \
do { \
(void)__sync_fetch_and_sub(x, 1); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_INC32_NV(x, v) \
do { \
v = __sync_add_and_fetch(x, 1); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32_NV(x, v) \
do { \
v = __sync_sub_and_fetch(x, 1); \
} while (/*CONSTCOND*/0)
#endif /* !HAVE_ATOMICS */
/*
* Language features.
*/
#define _PROP_ARG_UNUSED __attribute__((unused))
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */

View File

@@ -0,0 +1,46 @@
/* $NetBSD: prop_rb_impl.h,v 1.8 2010/09/25 01:42:38 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 _PROP_RB_IMPL_H_
#define _PROP_RB_IMPL_H_
#include <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
#endif /* _PROP_RB_IMPL_H_*/

View File

@@ -0,0 +1,118 @@
/* $NetBSD: prop_stack.c,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* 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 COPYRIGHT HOLDERS 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
* COPYRIGHT HOLDERS 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.
*/
#include "prop_stack.h"
#include "prop_object_impl.h"
void
_prop_stack_init(prop_stack_t stack)
{
stack->used_intern_elems = 0;
SLIST_INIT(&stack->extern_elems);
}
bool
_prop_stack_push(prop_stack_t stack, prop_object_t obj, void *data1,
void *data2, void *data3)
{
struct _prop_stack_extern_elem *eelem;
struct _prop_stack_intern_elem *ielem;
if (stack->used_intern_elems == PROP_STACK_INTERN_ELEMS) {
eelem = _PROP_MALLOC(sizeof(*eelem), M_TEMP);
if (eelem == NULL)
return false;
eelem->object = obj;
eelem->object_data[0] = data1;
eelem->object_data[1] = data2;
eelem->object_data[2] = data3;
SLIST_INSERT_HEAD(&stack->extern_elems, eelem, stack_link);
return true;
}
_PROP_ASSERT(stack->used_intern_elems < PROP_STACK_INTERN_ELEMS);
_PROP_ASSERT(SLIST_EMPTY(&stack->extern_elems));
ielem = &stack->intern_elems[stack->used_intern_elems];
ielem->object = obj;
ielem->object_data[0] = data1;
ielem->object_data[1] = data2;
ielem->object_data[2] = data3;
++stack->used_intern_elems;
return true;
}
bool
_prop_stack_pop(prop_stack_t stack, prop_object_t *obj, void **data1,
void **data2, void **data3)
{
struct _prop_stack_extern_elem *eelem;
struct _prop_stack_intern_elem *ielem;
if (stack->used_intern_elems == 0)
return false;
if ((eelem = SLIST_FIRST(&stack->extern_elems)) != NULL) {
_PROP_ASSERT(stack->used_intern_elems == PROP_STACK_INTERN_ELEMS);
SLIST_REMOVE_HEAD(&stack->extern_elems, stack_link);
if (obj)
*obj = eelem->object;
if (data1)
*data1 = eelem->object_data[0];
if (data2)
*data2 = eelem->object_data[1];
if (data3)
*data3 = eelem->object_data[2];
_PROP_FREE(eelem, M_TEMP);
return true;
}
--stack->used_intern_elems;
ielem = &stack->intern_elems[stack->used_intern_elems];
if (obj)
*obj = ielem->object;
if (data1)
*data1 = ielem->object_data[0];
if (data2)
*data2 = ielem->object_data[1];
if (data3)
*data3 = ielem->object_data[2];
return true;
}

View File

@@ -0,0 +1,64 @@
/* $NetBSD: prop_stack.h,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* 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 COPYRIGHT HOLDERS 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
* COPYRIGHT HOLDERS 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 _PROP_STACK_H
#define _PROP_STACK_H
#include <queue.h>
#include <prop/prop_object.h>
#include <sys/types.h>
struct _prop_stack_intern_elem {
prop_object_t object;
void *object_data[3];
};
struct _prop_stack_extern_elem {
SLIST_ENTRY(_prop_stack_extern_elem) stack_link;
prop_object_t object;
void *object_data[3];
};
#define PROP_STACK_INTERN_ELEMS 16
struct _prop_stack {
struct _prop_stack_intern_elem intern_elems[PROP_STACK_INTERN_ELEMS];
size_t used_intern_elems;
SLIST_HEAD(, _prop_stack_extern_elem) extern_elems;
};
typedef struct _prop_stack *prop_stack_t;
void _prop_stack_init(prop_stack_t);
bool _prop_stack_push(prop_stack_t, prop_object_t, void *, void *, void *);
bool _prop_stack_pop(prop_stack_t, prop_object_t *, void **, void **, void **);
#endif

View File

@@ -0,0 +1,469 @@
/* $NetBSD: prop_string.c,v 1.12 2014/03/26 18:12:46 christos Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* 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.
*/
#include <prop/prop_string.h>
#include "prop_object_impl.h"
struct _prop_string {
struct _prop_object ps_obj;
union {
char * psu_mutable;
const char * psu_immutable;
} ps_un;
#define ps_mutable ps_un.psu_mutable
#define ps_immutable ps_un.psu_immutable
size_t ps_size; /* not including \0 */
int ps_flags;
};
#define PS_F_NOCOPY 0x01
_PROP_POOL_INIT(_prop_string_pool, sizeof(struct _prop_string), "propstng")
static _prop_object_free_rv_t
_prop_string_free(prop_stack_t, prop_object_t *);
static bool _prop_string_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_string_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static const struct _prop_object_type _prop_object_type_string = {
.pot_type = PROP_TYPE_STRING,
.pot_free = _prop_string_free,
.pot_extern = _prop_string_externalize,
.pot_equals = _prop_string_equals,
};
#define prop_object_is_string(x) \
((x) != NULL && (x)->ps_obj.po_type == &_prop_object_type_string)
#define prop_string_contents(x) ((x)->ps_immutable ? (x)->ps_immutable : "")
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_string_free(prop_stack_t stack, prop_object_t *obj)
{
prop_string_t ps = *obj;
if ((ps->ps_flags & PS_F_NOCOPY) == 0 && ps->ps_mutable != NULL)
_PROP_FREE(ps->ps_mutable, M_PROP_STRING);
_PROP_POOL_PUT(_prop_string_pool, ps);
return (_PROP_OBJECT_FREE_DONE);
}
static bool
_prop_string_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_string_t ps = v;
if (ps->ps_size == 0)
return (_prop_object_externalize_empty_tag(ctx, "string"));
if (_prop_object_externalize_start_tag(ctx, "string") == false ||
_prop_object_externalize_append_encoded_cstring(ctx,
ps->ps_immutable) == false ||
_prop_object_externalize_end_tag(ctx, "string") == false)
return (false);
return (true);
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_string_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_string_t str1 = v1;
prop_string_t str2 = v2;
if (str1 == str2)
return (_PROP_OBJECT_EQUALS_TRUE);
if (str1->ps_size != str2->ps_size)
return (_PROP_OBJECT_EQUALS_FALSE);
if (strcmp(prop_string_contents(str1), prop_string_contents(str2)))
return (_PROP_OBJECT_EQUALS_FALSE);
else
return (_PROP_OBJECT_EQUALS_TRUE);
}
static prop_string_t
_prop_string_alloc(void)
{
prop_string_t ps;
ps = _PROP_POOL_GET(_prop_string_pool);
if (ps != NULL) {
_prop_object_init(&ps->ps_obj, &_prop_object_type_string);
ps->ps_mutable = NULL;
ps->ps_size = 0;
ps->ps_flags = 0;
}
return (ps);
}
/*
* prop_string_create --
* Create an empty mutable string.
*/
prop_string_t
prop_string_create(void)
{
return (_prop_string_alloc());
}
/*
* prop_string_create_cstring --
* Create a string that contains a copy of the provided C string.
*/
prop_string_t
prop_string_create_cstring(const char *str)
{
prop_string_t ps;
char *cp;
size_t len;
ps = _prop_string_alloc();
if (ps != NULL) {
len = strlen(str);
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
if (cp == NULL) {
prop_object_release(ps);
return (NULL);
}
strcpy(cp, str);
ps->ps_mutable = cp;
ps->ps_size = len;
}
return (ps);
}
/*
* prop_string_create_cstring_nocopy --
* Create an immutable string that contains a refrence to the
* provided C string.
*/
prop_string_t
prop_string_create_cstring_nocopy(const char *str)
{
prop_string_t ps;
ps = _prop_string_alloc();
if (ps != NULL) {
ps->ps_immutable = str;
ps->ps_size = strlen(str);
ps->ps_flags |= PS_F_NOCOPY;
}
return (ps);
}
/*
* prop_string_copy --
* Copy a string. If the original string is immutable, then the
* copy is also immutable and references the same external data.
*/
prop_string_t
prop_string_copy(prop_string_t ops)
{
prop_string_t ps;
if (! prop_object_is_string(ops))
return (NULL);
ps = _prop_string_alloc();
if (ps != NULL) {
ps->ps_size = ops->ps_size;
ps->ps_flags = ops->ps_flags;
if (ops->ps_flags & PS_F_NOCOPY)
ps->ps_immutable = ops->ps_immutable;
else {
char *cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
if (cp == NULL) {
prop_object_release(ps);
return (NULL);
}
strcpy(cp, prop_string_contents(ops));
ps->ps_mutable = cp;
}
}
return (ps);
}
/*
* prop_string_copy_mutable --
* Copy a string, always returning a mutable copy.
*/
prop_string_t
prop_string_copy_mutable(prop_string_t ops)
{
prop_string_t ps;
char *cp;
if (! prop_object_is_string(ops))
return (NULL);
ps = _prop_string_alloc();
if (ps != NULL) {
ps->ps_size = ops->ps_size;
cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
if (cp == NULL) {
prop_object_release(ps);
return (NULL);
}
strcpy(cp, prop_string_contents(ops));
ps->ps_mutable = cp;
}
return (ps);
}
/*
* prop_string_size --
* Return the size of the string, not including the terminating NUL.
*/
size_t
prop_string_size(prop_string_t ps)
{
if (! prop_object_is_string(ps))
return (0);
return (ps->ps_size);
}
/*
* prop_string_mutable --
* Return true if the string is a mutable string.
*/
bool
prop_string_mutable(prop_string_t ps)
{
if (! prop_object_is_string(ps))
return (false);
return ((ps->ps_flags & PS_F_NOCOPY) == 0);
}
/*
* prop_string_cstring --
* Return a copy of the contents of the string as a C string.
* The string is allocated with the M_TEMP malloc type.
*/
char *
prop_string_cstring(prop_string_t ps)
{
char *cp;
if (! prop_object_is_string(ps))
return (NULL);
cp = _PROP_MALLOC(ps->ps_size + 1, M_TEMP);
if (cp != NULL)
strcpy(cp, prop_string_contents(ps));
return (cp);
}
/*
* prop_string_cstring_nocopy --
* Return an immutable reference to the contents of the string
* as a C string.
*/
const char *
prop_string_cstring_nocopy(prop_string_t ps)
{
if (! prop_object_is_string(ps))
return (NULL);
return (prop_string_contents(ps));
}
/*
* prop_string_append --
* Append the contents of one string to another. Returns true
* upon success. The destination string must be mutable.
*/
bool
prop_string_append(prop_string_t dst, prop_string_t src)
{
char *ocp, *cp;
size_t len;
if (! (prop_object_is_string(dst) &&
prop_object_is_string(src)))
return (false);
if (dst->ps_flags & PS_F_NOCOPY)
return (false);
len = dst->ps_size + src->ps_size;
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
if (cp == NULL)
return (false);
snprintf(cp, len + 1, "%s%s", prop_string_contents(dst),
prop_string_contents(src));
ocp = dst->ps_mutable;
dst->ps_mutable = cp;
dst->ps_size = len;
if (ocp != NULL)
_PROP_FREE(ocp, M_PROP_STRING);
return (true);
}
/*
* prop_string_append_cstring --
* Append a C string to a string. Returns true upon success.
* The destination string must be mutable.
*/
bool
prop_string_append_cstring(prop_string_t dst, const char *src)
{
char *ocp, *cp;
size_t len;
if (! prop_object_is_string(dst))
return (false);
_PROP_ASSERT(src != NULL);
if (dst->ps_flags & PS_F_NOCOPY)
return (false);
len = dst->ps_size + strlen(src);
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
if (cp == NULL)
return (false);
snprintf(cp, len + 1, "%s%s", prop_string_contents(dst), src);
ocp = dst->ps_mutable;
dst->ps_mutable = cp;
dst->ps_size = len;
if (ocp != NULL)
_PROP_FREE(ocp, M_PROP_STRING);
return (true);
}
/*
* prop_string_equals --
* Return true if two strings are equivalent.
*/
bool
prop_string_equals(prop_string_t str1, prop_string_t str2)
{
if (!prop_object_is_string(str1) || !prop_object_is_string(str2))
return (false);
return prop_object_equals(str1, str2);
}
/*
* prop_string_equals_cstring --
* Return true if the string is equivalent to the specified
* C string.
*/
bool
prop_string_equals_cstring(prop_string_t ps, const char *cp)
{
if (! prop_object_is_string(ps))
return (false);
return (strcmp(prop_string_contents(ps), cp) == 0);
}
/*
* _prop_string_internalize --
* Parse a <string>...</string> and return the object created from the
* external representation.
*/
/* ARGSUSED */
bool
_prop_string_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
prop_string_t string;
char *str;
size_t len, alen;
if (ctx->poic_is_empty_element) {
*obj = prop_string_create();
return (true);
}
/* No attributes recognized here. */
if (ctx->poic_tagattr != NULL)
return (true);
/* Compute the length of the result. */
if (_prop_object_internalize_decode_string(ctx, NULL, 0, &len,
NULL) == false)
return (true);
str = _PROP_MALLOC(len + 1, M_PROP_STRING);
if (str == NULL)
return (true);
if (_prop_object_internalize_decode_string(ctx, str, len, &alen,
&ctx->poic_cp) == false ||
alen != len) {
_PROP_FREE(str, M_PROP_STRING);
return (true);
}
str[len] = '\0';
if (_prop_object_internalize_find_tag(ctx, "string",
_PROP_TAG_TYPE_END) == false) {
_PROP_FREE(str, M_PROP_STRING);
return (true);
}
string = _prop_string_alloc();
if (string == NULL) {
_PROP_FREE(str, M_PROP_STRING);
return (true);
}
string->ps_mutable = str;
string->ps_size = len;
*obj = string;
return (true);
}

View File

@@ -0,0 +1,129 @@
/*-
* Copyright (c) 2010-2014 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, objtype) \
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 = NULL; \
z_stream strm; \
unsigned char out[_READ_CHUNK+1]; \
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; \
\
/* If it's an ordinary uncompressed plist we are done */ \
obj = prop ## type ## _internalize(mf->poimf_xml); \
if (prop_object_type(obj) == PROP_TYPE_## objtype) \
goto out; \
\
/* Output buffer (uncompressed) */ \
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
if (uncomp_xml == NULL) \
goto out; \
\
/* 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) \
goto out2; \
\
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: \
case Z_STREAM_ERROR: \
case Z_NEED_DICT: \
case Z_MEM_ERROR: \
errno = EINVAL; \
goto out1; \
} \
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 */ \
out2: \
(void)inflateEnd(&strm); \
out1: \
obj = prop ## type ## _internalize(uncomp_xml); \
_PROP_FREE(uncomp_xml, M_TEMP); \
out: \
_prop_object_internalize_unmap_file(mf); \
\
return obj; \
}
TEMPLATE(_array, ARRAY)
TEMPLATE(_dictionary, DICTIONARY)
#undef TEMPLATE

1315
lib/portableproplib/rb.c Normal file

File diff suppressed because it is too large Load Diff