Some changes that will appear in 0.5.0:
* Add proplib-0.4.1 source and use it in XBPS. This is to avoid an external dependency, so that we depend on the features of the internal library. This also means that proplib is not required anymore. * Added support to read/write gzip compressed plists by default, thanks to proplib-0.4 that gained new functionality. That means that from now, XBPS will be able to write compressed gzip plist files for all metadata related work. This will vastly reduce bandwidth required for fetching remote repo's pkg index file and binary packages. --HG-- extra : convert_revision : xtraeme%40gmail.com-20100420122238-zcb85rudt9p34e10
This commit is contained in:
142
lib/portableproplib/prop/prop_array.h
Normal file
142
lib/portableproplib/prop/prop_array.h
Normal file
@ -0,0 +1,142 @@
|
||||
/* $NetBSD: prop_array.h,v 1.8 2008/09/11 13:15:13 haad 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_ARRAY_H_
|
||||
#define _PROPLIB_PROP_ARRAY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <prop/prop_object.h>
|
||||
|
||||
typedef struct _prop_array *prop_array_t;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
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_get_cstring_nocopy(prop_array_t,
|
||||
unsigned int,
|
||||
const char **);
|
||||
bool prop_array_set_cstring_nocopy(prop_array_t,
|
||||
unsigned int,
|
||||
const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_ARRAY_H_ */
|
49
lib/portableproplib/prop/prop_bool.h
Normal file
49
lib/portableproplib/prop/prop_bool.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_BOOL_H_ */
|
56
lib/portableproplib/prop/prop_data.h
Normal file
56
lib/portableproplib/prop/prop_data.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_DATA_H_ */
|
148
lib/portableproplib/prop/prop_dictionary.h
Normal file
148
lib/portableproplib/prop/prop_dictionary.h
Normal file
@ -0,0 +1,148 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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_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 *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_DICTIONARY_H_ */
|
91
lib/portableproplib/prop/prop_ingest.h
Normal file
91
lib/portableproplib/prop/prop_ingest.h
Normal file
@ -0,0 +1,91 @@
|
||||
/* $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 }
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_INGEST_H_ */
|
57
lib/portableproplib/prop/prop_number.h
Normal file
57
lib/portableproplib/prop/prop_number.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_NUMBER_H_ */
|
67
lib/portableproplib/prop/prop_object.h
Normal file
67
lib/portableproplib/prop/prop_object.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_OBJECT_H_ */
|
62
lib/portableproplib/prop/prop_string.h
Normal file
62
lib/portableproplib/prop/prop_string.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* $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;
|
||||
|
||||
__BEGIN_DECLS
|
||||
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 *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _PROPLIB_PROP_STRING_H_ */
|
45
lib/portableproplib/prop/proplib.h
Normal file
45
lib/portableproplib/prop/proplib.h
Normal 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_ */
|
1044
lib/portableproplib/prop_array.c
Normal file
1044
lib/portableproplib/prop_array.c
Normal file
File diff suppressed because it is too large
Load Diff
240
lib/portableproplib/prop_array_util.c
Normal file
240
lib/portableproplib/prop_array_util.c
Normal file
@ -0,0 +1,240 @@
|
||||
/* $NetBSD: prop_array_util.c,v 1.2 2008/09/11 13:15:13 haad 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/proplib.h>
|
||||
#include "prop_object_impl.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_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
|
223
lib/portableproplib/prop_bool.c
Normal file
223
lib/portableproplib/prop_bool.c
Normal file
@ -0,0 +1,223 @@
|
||||
/* $NetBSD: prop_bool.c,v 1.16 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_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;
|
||||
|
||||
_PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex)
|
||||
static bool _prop_bool_initialized;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static prop_bool_t
|
||||
_prop_bool_alloc(bool val)
|
||||
{
|
||||
prop_bool_t pb;
|
||||
|
||||
if (! _prop_bool_initialized) {
|
||||
_PROP_MUTEX_LOCK(_prop_bool_initialized_mutex);
|
||||
if (! _prop_bool_initialized) {
|
||||
_prop_object_init(&_prop_bool_true.pb_obj,
|
||||
&_prop_object_type_bool);
|
||||
_prop_bool_true.pb_value = true;
|
||||
|
||||
_prop_object_init(&_prop_bool_false.pb_obj,
|
||||
&_prop_object_type_bool);
|
||||
_prop_bool_false.pb_value = false;
|
||||
|
||||
_prop_bool_initialized = true;
|
||||
}
|
||||
_PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex);
|
||||
}
|
||||
|
||||
pb = val ? &_prop_bool_true : &_prop_bool_false;
|
||||
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);
|
||||
}
|
616
lib/portableproplib/prop_data.c
Normal file
616
lib/portableproplib/prop_data.c
Normal file
@ -0,0 +1,616 @@
|
||||
/* $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")
|
||||
|
||||
_PROP_MALLOC_DEFINE(M_PROP_DATA, "prop data",
|
||||
"property data container object")
|
||||
|
||||
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);
|
||||
ch = (unsigned char) *src;
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
1542
lib/portableproplib/prop_dictionary.c
Normal file
1542
lib/portableproplib/prop_dictionary.c
Normal file
File diff suppressed because it is too large
Load Diff
208
lib/portableproplib/prop_dictionary_util.c
Normal file
208
lib/portableproplib/prop_dictionary_util.c
Normal file
@ -0,0 +1,208 @@
|
||||
/* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_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
|
159
lib/portableproplib/prop_ingest.c
Normal file
159
lib/portableproplib/prop_ingest.c
Normal file
@ -0,0 +1,159 @@
|
||||
/* $NetBSD: prop_ingest.c,v 1.3 2008/04/28 20:22:53 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.
|
||||
*/
|
||||
|
||||
#include <prop/proplib.h>
|
||||
#include "prop_object_impl.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 *private)
|
||||
{
|
||||
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 = private;
|
||||
}
|
||||
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);
|
||||
}
|
576
lib/portableproplib/prop_number.c
Normal file
576
lib/portableproplib/prop_number.c
Normal file
@ -0,0 +1,576 @@
|
||||
/* $NetBSD: prop_number.c,v 1.20 2008/11/30 00:17:07 haad 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 {
|
||||
struct _prop_object pn_obj;
|
||||
struct rb_node pn_link;
|
||||
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;
|
||||
} pn_value;
|
||||
};
|
||||
|
||||
#define RBNODE_TO_PN(n) \
|
||||
((struct _prop_number *) \
|
||||
((uintptr_t)n - offsetof(struct _prop_number, pn_link)))
|
||||
|
||||
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
|
||||
|
||||
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
|
||||
_prop_number_rb_compare_nodes(const struct rb_node *n1,
|
||||
const struct rb_node *n2)
|
||||
{
|
||||
const prop_number_t pn1 = RBNODE_TO_PN(n1);
|
||||
const prop_number_t pn2 = RBNODE_TO_PN(n2);
|
||||
|
||||
return (_prop_number_compare_values(&pn1->pn_value, &pn2->pn_value));
|
||||
}
|
||||
|
||||
static int
|
||||
_prop_number_rb_compare_key(const struct rb_node *n,
|
||||
const void *v)
|
||||
{
|
||||
const prop_number_t pn = RBNODE_TO_PN(n);
|
||||
const struct _prop_number_value *pnv = v;
|
||||
|
||||
return (_prop_number_compare_values(&pn->pn_value, pnv));
|
||||
}
|
||||
|
||||
static const struct rb_tree_ops _prop_number_rb_tree_ops = {
|
||||
.rbto_compare_nodes = _prop_number_rb_compare_nodes,
|
||||
.rbto_compare_key = _prop_number_rb_compare_key,
|
||||
};
|
||||
|
||||
static struct rb_tree _prop_number_tree;
|
||||
static bool _prop_number_tree_initialized;
|
||||
|
||||
_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->pn_link);
|
||||
|
||||
_PROP_POOL_PUT(_prop_number_pool, pn);
|
||||
|
||||
return (_PROP_OBJECT_FREE_DONE);
|
||||
}
|
||||
|
||||
static void
|
||||
_prop_number_lock()
|
||||
{
|
||||
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
_prop_number_unlock()
|
||||
{
|
||||
_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 the record:
|
||||
* The original implementation used hex for signed numbers,
|
||||
* but we changed it to be human readable.
|
||||
*/
|
||||
if (pn->pn_value.pnv_is_unsigned)
|
||||
sprintf(tmpstr, "%" PRIu64, pn->pn_value.pnv_unsigned);
|
||||
else
|
||||
sprintf(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;
|
||||
struct rb_node *n;
|
||||
bool rv;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
if (! _prop_number_tree_initialized) {
|
||||
_prop_rb_tree_init(&_prop_number_tree,
|
||||
&_prop_number_rb_tree_ops);
|
||||
_prop_number_tree_initialized = true;
|
||||
} else {
|
||||
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
|
||||
if (n != NULL) {
|
||||
opn = RBNODE_TO_PN(n);
|
||||
prop_object_retain(opn);
|
||||
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||
return (opn);
|
||||
}
|
||||
}
|
||||
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
|
||||
if (n != NULL) {
|
||||
opn = RBNODE_TO_PN(n);
|
||||
prop_object_retain(opn);
|
||||
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||
_PROP_POOL_PUT(_prop_number_pool, pn);
|
||||
return (opn);
|
||||
}
|
||||
rv = _prop_rb_tree_insert_node(&_prop_number_tree, &pn->pn_link);
|
||||
_PROP_ASSERT(rv == true);
|
||||
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
|
||||
return (pn);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
1241
lib/portableproplib/prop_object.c
Normal file
1241
lib/portableproplib/prop_object.c
Normal file
File diff suppressed because it is too large
Load Diff
274
lib/portableproplib/prop_object_impl.h
Normal file
274
lib/portableproplib/prop_object_impl.h
Normal file
@ -0,0 +1,274 @@
|
||||
/* $NetBSD: prop_object_impl.h,v 1.28 2008/11/30 00:17:07 haad 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' || \
|
||||
_PROP_EOF(c))
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 = PTHREAD_MUTEX_INITIALIZER;
|
||||
#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))
|
||||
|
||||
/*
|
||||
* Language features.
|
||||
*/
|
||||
#define _PROP_ARG_UNUSED /* delete */
|
||||
|
||||
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */
|
1056
lib/portableproplib/prop_rb.c
Normal file
1056
lib/portableproplib/prop_rb.c
Normal file
File diff suppressed because it is too large
Load Diff
137
lib/portableproplib/prop_rb_impl.h
Normal file
137
lib/portableproplib/prop_rb_impl.h
Normal file
@ -0,0 +1,137 @@
|
||||
/* $NetBSD: prop_rb_impl.h,v 1.7 2008/06/30 20:14:09 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 <sys/types.h>
|
||||
#include "queue.h"
|
||||
|
||||
struct rb_node {
|
||||
struct rb_node *rb_nodes[3];
|
||||
#define RB_NODE_LEFT 0
|
||||
#define RB_NODE_RIGHT 1
|
||||
#define RB_NODE_OTHER 1
|
||||
#define RB_NODE_PARENT 2
|
||||
#define rb_left rb_nodes[RB_NODE_LEFT]
|
||||
#define rb_right rb_nodes[RB_NODE_RIGHT]
|
||||
#define rb_parent rb_nodes[RB_NODE_PARENT]
|
||||
union {
|
||||
struct {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned int : 28;
|
||||
unsigned int s_root : 1;
|
||||
unsigned int s_position : 1;
|
||||
unsigned int s_color : 1;
|
||||
unsigned int s_sentinel : 1;
|
||||
#endif
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned int s_sentinel : 1;
|
||||
unsigned int s_color : 1;
|
||||
unsigned int s_position : 1;
|
||||
unsigned int s_root : 1;
|
||||
unsigned int : 28;
|
||||
#endif
|
||||
} u_s;
|
||||
unsigned int u_i;
|
||||
} rb_u;
|
||||
#define rb_root rb_u.u_s.s_root
|
||||
#define rb_position rb_u.u_s.s_position
|
||||
#define rb_color rb_u.u_s.s_color
|
||||
#define rb_sentinel rb_u.u_s.s_sentinel
|
||||
#define rb_properties rb_u.u_i
|
||||
#define RB_SENTINEL_P(rb) ((rb)->rb_sentinel + 0)
|
||||
#define RB_LEFT_SENTINEL_P(rb) ((rb)->rb_left->rb_sentinel + 0)
|
||||
#define RB_RIGHT_SENTINEL_P(rb) ((rb)->rb_right->rb_sentinel + 0)
|
||||
#define RB_PARENT_SENTINEL_P(rb) ((rb)->rb_parent->rb_sentinel + 0)
|
||||
#define RB_CHILDLESS_P(rb) (RB_LEFT_SENTINEL_P(rb) \
|
||||
&& RB_RIGHT_SENTINEL_P(rb))
|
||||
#define RB_TWOCHILDREN_P(rb) (!RB_LEFT_SENTINEL_P(rb) \
|
||||
&& !RB_RIGHT_SENTINEL_P(rb))
|
||||
#define RB_ROOT_P(rb) ((rb)->rb_root != false)
|
||||
#define RB_RED_P(rb) ((rb)->rb_color + 0)
|
||||
#define RB_BLACK_P(rb) (!(rb)->rb_color)
|
||||
#define RB_MARK_RED(rb) ((void)((rb)->rb_color = 1))
|
||||
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_color = 0))
|
||||
#define RB_MARK_ROOT(rb) ((void)((rb)->rb_root = 1))
|
||||
#ifdef RBDEBUG
|
||||
TAILQ_ENTRY(rb_node) rb_link;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef RBDEBUG
|
||||
TAILQ_HEAD(rb_node_qh, rb_node);
|
||||
|
||||
#define RB_TAILQ_REMOVE TAILQ_REMOVE
|
||||
#define RB_TAILQ_INIT TAILQ_INIT
|
||||
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD
|
||||
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE
|
||||
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER
|
||||
#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
|
||||
|
||||
typedef int (*rb_compare_nodes_fn)(const struct rb_node *,
|
||||
const struct rb_node *);
|
||||
typedef int (*rb_compare_key_fn)(const struct rb_node *, const void *);
|
||||
|
||||
struct rb_tree_ops {
|
||||
rb_compare_nodes_fn rbto_compare_nodes;
|
||||
rb_compare_key_fn rbto_compare_key;
|
||||
};
|
||||
|
||||
struct rb_tree {
|
||||
struct rb_node *rbt_root;
|
||||
#ifdef RBDEBUG
|
||||
struct rb_node_qh rbt_nodes;
|
||||
#endif
|
||||
const struct rb_tree_ops *rbt_ops;
|
||||
#ifdef RBDEBUG
|
||||
unsigned int rbt_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
void _prop_rb_tree_init(struct rb_tree *, const struct rb_tree_ops *);
|
||||
bool _prop_rb_tree_insert_node(struct rb_tree *, struct rb_node *);
|
||||
struct rb_node *
|
||||
_prop_rb_tree_find(struct rb_tree *, const void *);
|
||||
void _prop_rb_tree_remove_node(struct rb_tree *, struct rb_node *);
|
||||
#ifdef RBDEBUG
|
||||
void _prop_rb_tree_check(const struct rb_tree *, bool);
|
||||
#endif
|
||||
struct rb_node *
|
||||
_prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int);
|
||||
|
||||
#endif /* _PROP_RB_IMPL_H_*/
|
118
lib/portableproplib/prop_stack.c
Normal file
118
lib/portableproplib/prop_stack.c
Normal 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;
|
||||
}
|
64
lib/portableproplib/prop_stack.h
Normal file
64
lib/portableproplib/prop_stack.h
Normal 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
|
471
lib/portableproplib/prop_string.c
Normal file
471
lib/portableproplib/prop_string.c
Normal file
@ -0,0 +1,471 @@
|
||||
/* $NetBSD: prop_string.c,v 1.11 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_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")
|
||||
|
||||
_PROP_MALLOC_DEFINE(M_PROP_STRING, "prop string",
|
||||
"property string container object")
|
||||
|
||||
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);
|
||||
sprintf(cp, "%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);
|
||||
sprintf(cp, "%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);
|
||||
}
|
Reference in New Issue
Block a user