import netbsd libprop

This commit is contained in:
Ben Gras 2011-12-22 17:42:19 +01:00
parent 59ff5cbd87
commit 6b6d114a21
48 changed files with 12256 additions and 2 deletions

View file

@ -0,0 +1,9 @@
# $NetBSD: Makefile.inc,v 1.8 2008/06/30 20:14:09 matt Exp $
.PATH: ${.PARSEDIR}
SRCS+= prop_array.c prop_array_util.c prop_bool.c prop_data.c \
prop_dictionary.c prop_dictionary_util.c prop_ingest.c \
prop_kern.c prop_number.c prop_object.c prop_stack.c prop_string.c
#SRCS+= prop_rb.c

View file

@ -0,0 +1,308 @@
.\" $NetBSD: prop_array.3,v 1.13 2011/09/30 22:08:18 jym Exp $
.\"
.\" Copyright (c) 2006, 2009 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.
.\"
.Dd October 10, 2009
.Dt PROP_ARRAY 3
.Os
.Sh NAME
.Nm prop_array ,
.Nm prop_array_create ,
.Nm prop_array_create_with_capacity ,
.Nm prop_array_copy ,
.Nm prop_array_copy_mutable ,
.Nm prop_array_capacity ,
.Nm prop_array_count ,
.Nm prop_array_ensure_capacity ,
.Nm prop_array_iterator ,
.Nm prop_array_make_immutable ,
.Nm prop_array_mutable ,
.Nm prop_array_get ,
.Nm prop_array_set ,
.Nm prop_array_add ,
.Nm prop_array_remove ,
.Nm prop_array_externalize ,
.Nm prop_array_internalize ,
.Nm prop_array_externalize_to_file ,
.Nm prop_array_internalize_from_file ,
.Nm prop_array_externalize_to_pref ,
.Nm prop_array_internalize_from_pref ,
.Nm prop_array_equals
.Nd array property collection object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_array_t
.Fn prop_array_create "void"
.Ft prop_array_t
.Fn prop_array_create_with_capacity "unsigned int capacity"
.\"
.Ft prop_array_t
.Fn prop_array_copy "prop_array_t array"
.Ft prop_array_t
.Fn prop_array_copy_mutable "prop_array_t array"
.\"
.Ft unsigned int
.Fn prop_array_capacity "prop_array_t array"
.Ft unsigned int
.Fn prop_array_count "prop_array_t array"
.Ft bool
.Fn prop_array_ensure_capacity "prop_array_t array" "unsigned int capacity"
.\"
.Ft prop_object_iterator_t
.Fn prop_array_iterator "prop_array_t array"
.\"
.Ft void
.Fn prop_array_make_immutable "prop_array_t array"
.Ft bool
.Fn prop_array_mutable "prop_array_t array"
.\"
.Ft prop_object_t
.Fn prop_array_get "prop_array_t array" "unsigned int index"
.Ft bool
.Fn prop_array_set "prop_array_t array" "unsigned int index" "prop_object_t obj"
.Ft bool
.Fn prop_array_add "prop_array_t array" "prop_object_t obj"
.Ft void
.Fn prop_array_remove "prop_array_t array" "unsigned int index"
.\"
.Ft char *
.Fn prop_array_externalize "prop_array_t array"
.Ft prop_array_t
.Fn prop_array_internalize "const char *xml"
.\"
.Ft bool
.Fn prop_array_externalize_to_file "prop_array_t array" "const char *path"
.Ft prop_array_t
.Fn prop_array_internalize_from_file "const char *path"
.\"
.Ft bool
.Fn prop_array_externalize_to_pref "prop_array_t array" "struct plistref *pref"
.Ft bool
.Fn prop_array_internalize_from_pref "const struct plistref *pref" \
"prop_array_t *arrayp"
.\"
.Ft bool
.Fn prop_array_equals "prop_array_t array1" "prop_array_t array2"
.Sh DESCRIPTION
The
.Nm prop_array
family of functions operate on the array property collection object type.
An array is an ordered set; an iterated array will return objects in the
same order with which they were stored.
.Bl -tag -width "xxxxx"
.It Fn prop_array_create "void"
Create an empty array.
The array initially has no capacity.
Returns
.Dv NULL
on failure.
.It Fn prop_array_create_with_capacity "unsigned int capacity"
Create an array with the capacity to store
.Fa capacity
objects.
Returns
.Dv NULL
on failure.
.It Fn prop_array_copy "prop_array_t array"
Copy an array.
The new array has an initial capacity equal to the number of objects stored
in the array being copied.
The new array contains references to the original array's objects, not
copies of those objects
.Pq i.e. a shallow copy is made .
If the original array is immutable, the resulting array is also immutable.
Returns
.Dv NULL
on failure.
.It Fn prop_array_copy_mutable "prop_array_t array"
Like
.Fn prop_array_copy ,
except the resulting array is always mutable.
.It Fn prop_array_capacity "prop_array_t array"
Returns the total capacity of the array, including objects already stored
in the array.
If the supplied object isn't an array, zero is returned.
.It Fn prop_array_count "prop_array_t array"
Returns the number of objects stored in the array.
If the supplied object isn't an array, zero is returned.
.It Fn prop_array_ensure_capacity "prop_array_t array" "unsigned int capacity"
Ensure that the array has a total capacity of
.Fa capacity ,
including objects already stored in the array.
Returns
.Dv true
if the capacity of the array is greater or equal to
.Fa capacity
or if expansion of the array's capacity was successful
and
.Dv false
otherwise.
.It Fn prop_array_iterator "prop_array_t array"
Create an iterator for the array.
The array is retained by the iterator.
An array iterator returns the object references stored in the array.
Storing to or removing from the array invalidates any active iterators for
the array.
Returns
.Dv NULL
on failure.
.It Fn prop_array_make_immutable "prop_array_t array"
Make
.Fa array
immutable.
.It Fn prop_array_mutable "prop_array_t array"
Returns
.Dv true
if the array is mutable.
.It Fn prop_array_get "prop_array_t array" "unsigned int index"
Return the object stored at the array index
.Fa index .
Returns
.Dv NULL
on failure.
.It Fn prop_array_set "prop_array_t array" "unsigned int index" \
"prop_object_t obj"
Store a reference to the object
.Fa obj
at the array index
.Fa index .
This function is not allowed to create holes in the array;
the caller must either be setting the object just beyond the existing
count or replacing an already existing object reference.
The object will be retained by the array.
If an existing object reference is being replaced, that object will be
released.
Returns
.Dv true
if storing the object was successful and
.Dv false
otherwise.
.It Fn prop_array_add "prop_array_t array" "prop_object_t obj"
Add a reference to the object
.Fa obj
to the array, appending to the end and growing the array's capacity if
necessary.
The object will be retained by the array.
Returns
.Dv true
if storing the object was successful and
.Dv false
otherwise.
.Pp
During expansion, array's capacity is augmented by the
.Dv EXPAND_STEP
constant, as defined in
.Pa libprop/prop_array.c
file, e.g.
.Pp
.Dl #define EXPAND_STEP 16
.It Fn prop_array_remove "prop_array_t array" "unsigned int index"
Remove the reference to the object stored at array index
.Fa index .
The object will be released and the array compacted following
the removal.
.It Fn prop_array_externalize "prop_array_t array"
Externalizes an array, returning a NUL-terminated buffer containing
the XML representation of the array.
The caller is responsible for freeing the returned buffer.
If converting to the external representation fails for any reason,
.Dv NULL
is returned.
.Pp
In user space, the buffer is allocated using
.Xr malloc 3 .
In the kernel, the buffer is allocated using
.Xr malloc 9
using the malloc type
.Dv M_TEMP .
.It Fn prop_array_internalize "const char *xml"
Parse the XML representation of a property list in the NUL-terminated
buffer
.Fa xml
and return the corresponding array.
Returns
.Dv NULL
if parsing fails for any reason.
.It Fn prop_array_externalize_to_file "prop_array_t array" "const char *path"
Externalizes an array and writes it to the file specified by
.Fa path .
The file is saved with the mode
.Dv 0666
as modified by the process's file creation mask
.Pq see Xr umask 2
and is written atomically.
Returns
.Dv false
if externalizing or writing the array fails for any reason.
.It Fn prop_array_internalize_from_file "const char *path"
Reads the XML property list contained in the file specified by
.Fa path ,
internalizes it, and returns the corresponding array.
Returns
.Dv NULL
on failure.
.It Fn prop_array_externalize_to_pref "prop_array_t array" \
"struct plistref *pref"
Externalizes an array and packs it into the plistref specified by
.Fa pref .
Returns
.Dv false
if externalizing the array fails for any reason.
.It Fn prop_array_internalize_from_pref "const struct plistref *pref" \
"prop_array_t *arrayp"
Reads the plistref specified by
.Fa pref ,
internalizes it, and returns the corresponding array.
Returns
.Dv false
if internalizing or writing the array fails for any reason.
.It Fn prop_array_equals "prop_array_t array1" "prop_array_t array2"
Returns
.Dv true
if the two arrays are equivalent.
If at least one of the supplied objects isn't an array,
.Dv false
is returned.
Note: Objects contained in the array are compared by value, not by reference.
.El
.Sh SEE ALSO
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,911 @@
/* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos Exp $ */
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/prop_array.h>
#include "prop_object_impl.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h>
#endif
struct _prop_array {
struct _prop_object pa_obj;
_PROP_RWLOCK_DECL(pa_rwlock)
prop_object_t * pa_array;
unsigned int pa_capacity;
unsigned int pa_count;
int pa_flags;
uint32_t pa_version;
};
#define PA_F_IMMUTABLE 0x01 /* array is immutable */
_PROP_POOL_INIT(_prop_array_pool, sizeof(struct _prop_array), "proparay")
_PROP_MALLOC_DEFINE(M_PROP_ARRAY, "prop array",
"property array container object")
static _prop_object_free_rv_t
_prop_array_free(prop_stack_t, prop_object_t *);
static void _prop_array_emergency_free(prop_object_t);
static bool _prop_array_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_array_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static void _prop_array_equals_finish(prop_object_t, prop_object_t);
static prop_object_iterator_t
_prop_array_iterator_locked(prop_array_t);
static prop_object_t
_prop_array_iterator_next_object_locked(void *);
static void _prop_array_iterator_reset_locked(void *);
static const struct _prop_object_type _prop_object_type_array = {
.pot_type = PROP_TYPE_ARRAY,
.pot_free = _prop_array_free,
.pot_emergency_free = _prop_array_emergency_free,
.pot_extern = _prop_array_externalize,
.pot_equals = _prop_array_equals,
.pot_equals_finish = _prop_array_equals_finish,
};
#define prop_object_is_array(x) \
((x) != NULL && (x)->pa_obj.po_type == &_prop_object_type_array)
#define prop_array_is_immutable(x) (((x)->pa_flags & PA_F_IMMUTABLE) != 0)
struct _prop_array_iterator {
struct _prop_object_iterator pai_base;
unsigned int pai_index;
};
#define EXPAND_STEP 16
static _prop_object_free_rv_t
_prop_array_free(prop_stack_t stack, prop_object_t *obj)
{
prop_array_t pa = *obj;
prop_object_t po;
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
_PROP_ASSERT((pa->pa_capacity == 0 && pa->pa_array == NULL) ||
(pa->pa_capacity != 0 && pa->pa_array != NULL));
/* The easy case is an empty array, just free and return. */
if (pa->pa_count == 0) {
if (pa->pa_array != NULL)
_PROP_FREE(pa->pa_array, M_PROP_ARRAY);
_PROP_RWLOCK_DESTROY(pa->pa_rwlock);
_PROP_POOL_PUT(_prop_array_pool, pa);
return (_PROP_OBJECT_FREE_DONE);
}
po = pa->pa_array[pa->pa_count - 1];
_PROP_ASSERT(po != NULL);
if (stack == NULL) {
/*
* If we are in emergency release mode,
* just let caller recurse down.
*/
*obj = po;
return (_PROP_OBJECT_FREE_FAILED);
}
/* Otherwise, try to push the current object on the stack. */
if (!_prop_stack_push(stack, pa, NULL, NULL, NULL)) {
/* Push failed, entering emergency release mode. */
return (_PROP_OBJECT_FREE_FAILED);
}
/* Object pushed on stack, caller will release it. */
--pa->pa_count;
*obj = po;
return (_PROP_OBJECT_FREE_RECURSE);
}
static void
_prop_array_emergency_free(prop_object_t obj)
{
prop_array_t pa = obj;
_PROP_ASSERT(pa->pa_count != 0);
--pa->pa_count;
}
static bool
_prop_array_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_array_t pa = v;
struct _prop_object *po;
prop_object_iterator_t pi;
unsigned int i;
bool rv = false;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
if (pa->pa_count == 0) {
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (_prop_object_externalize_empty_tag(ctx, "array"));
}
/* XXXJRT Hint "count" for the internalize step? */
if (_prop_object_externalize_start_tag(ctx, "array") == false ||
_prop_object_externalize_append_char(ctx, '\n') == false)
goto out;
pi = _prop_array_iterator_locked(pa);
if (pi == NULL)
goto out;
ctx->poec_depth++;
_PROP_ASSERT(ctx->poec_depth != 0);
while ((po = _prop_array_iterator_next_object_locked(pi)) != NULL) {
if ((*po->po_type->pot_extern)(ctx, po) == false) {
prop_object_iterator_release(pi);
goto out;
}
}
prop_object_iterator_release(pi);
ctx->poec_depth--;
for (i = 0; i < ctx->poec_depth; i++) {
if (_prop_object_externalize_append_char(ctx, '\t') == false)
goto out;
}
if (_prop_object_externalize_end_tag(ctx, "array") == false)
goto out;
rv = true;
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_array_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_array_t array1 = v1;
prop_array_t array2 = v2;
uintptr_t idx;
_prop_object_equals_rv_t rv = _PROP_OBJECT_EQUALS_FALSE;
if (array1 == array2)
return (_PROP_OBJECT_EQUALS_TRUE);
_PROP_ASSERT(*stored_pointer1 == *stored_pointer2);
idx = (uintptr_t)*stored_pointer1;
/* For the first iteration, lock the objects. */
if (idx == 0) {
if ((uintptr_t)array1 < (uintptr_t)array2) {
_PROP_RWLOCK_RDLOCK(array1->pa_rwlock);
_PROP_RWLOCK_RDLOCK(array2->pa_rwlock);
} else {
_PROP_RWLOCK_RDLOCK(array2->pa_rwlock);
_PROP_RWLOCK_RDLOCK(array1->pa_rwlock);
}
}
if (array1->pa_count != array2->pa_count)
goto out;
if (idx == array1->pa_count) {
rv = _PROP_OBJECT_EQUALS_TRUE;
goto out;
}
_PROP_ASSERT(idx < array1->pa_count);
*stored_pointer1 = (void *)(idx + 1);
*stored_pointer2 = (void *)(idx + 1);
*next_obj1 = array1->pa_array[idx];
*next_obj2 = array2->pa_array[idx];
return (_PROP_OBJECT_EQUALS_RECURSE);
out:
_PROP_RWLOCK_UNLOCK(array1->pa_rwlock);
_PROP_RWLOCK_UNLOCK(array2->pa_rwlock);
return (rv);
}
static void
_prop_array_equals_finish(prop_object_t v1, prop_object_t v2)
{
_PROP_RWLOCK_UNLOCK(((prop_array_t)v1)->pa_rwlock);
_PROP_RWLOCK_UNLOCK(((prop_array_t)v2)->pa_rwlock);
}
static prop_array_t
_prop_array_alloc(unsigned int capacity)
{
prop_array_t pa;
prop_object_t *array;
if (capacity != 0) {
array = _PROP_CALLOC(capacity * sizeof(prop_object_t),
M_PROP_ARRAY);
if (array == NULL)
return (NULL);
} else
array = NULL;
pa = _PROP_POOL_GET(_prop_array_pool);
if (pa != NULL) {
_prop_object_init(&pa->pa_obj, &_prop_object_type_array);
pa->pa_obj.po_type = &_prop_object_type_array;
_PROP_RWLOCK_INIT(pa->pa_rwlock);
pa->pa_array = array;
pa->pa_capacity = capacity;
pa->pa_count = 0;
pa->pa_flags = 0;
pa->pa_version = 0;
} else if (array != NULL)
_PROP_FREE(array, M_PROP_ARRAY);
return (pa);
}
static bool
_prop_array_expand(prop_array_t pa, unsigned int capacity)
{
prop_object_t *array, *oarray;
/*
* Array must be WRITE-LOCKED.
*/
oarray = pa->pa_array;
array = _PROP_CALLOC(capacity * sizeof(*array), M_PROP_ARRAY);
if (array == NULL)
return (false);
if (oarray != NULL)
memcpy(array, oarray, pa->pa_capacity * sizeof(*array));
pa->pa_array = array;
pa->pa_capacity = capacity;
if (oarray != NULL)
_PROP_FREE(oarray, M_PROP_ARRAY);
return (true);
}
static prop_object_t
_prop_array_iterator_next_object_locked(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
prop_object_t po = NULL;
_PROP_ASSERT(prop_object_is_array(pa));
if (pa->pa_version != pai->pai_base.pi_version)
goto out; /* array changed during iteration */
_PROP_ASSERT(pai->pai_index <= pa->pa_count);
if (pai->pai_index == pa->pa_count)
goto out; /* we've iterated all objects */
po = pa->pa_array[pai->pai_index];
pai->pai_index++;
out:
return (po);
}
static prop_object_t
_prop_array_iterator_next_object(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa __unused = pai->pai_base.pi_obj;
prop_object_t po;
_PROP_ASSERT(prop_object_is_array(pa));
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
po = _prop_array_iterator_next_object_locked(pai);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (po);
}
static void
_prop_array_iterator_reset_locked(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa));
pai->pai_index = 0;
pai->pai_base.pi_version = pa->pa_version;
}
static void
_prop_array_iterator_reset(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa __unused = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa));
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
_prop_array_iterator_reset_locked(pai);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
}
/*
* prop_array_create --
* Create an empty array.
*/
prop_array_t
prop_array_create(void)
{
return (_prop_array_alloc(0));
}
/*
* prop_array_create_with_capacity --
* Create an array with the capacity to store N objects.
*/
prop_array_t
prop_array_create_with_capacity(unsigned int capacity)
{
return (_prop_array_alloc(capacity));
}
/*
* prop_array_copy --
* Copy an array. The new array has an initial capacity equal to
* the number of objects stored in the original array. The new
* array contains references to the original array's objects, not
* copies of those objects (i.e. a shallow copy).
*/
prop_array_t
prop_array_copy(prop_array_t opa)
{
prop_array_t pa;
prop_object_t po;
unsigned int idx;
if (! prop_object_is_array(opa))
return (NULL);
_PROP_RWLOCK_RDLOCK(opa->pa_rwlock);
pa = _prop_array_alloc(opa->pa_count);
if (pa != NULL) {
for (idx = 0; idx < opa->pa_count; idx++) {
po = opa->pa_array[idx];
prop_object_retain(po);
pa->pa_array[idx] = po;
}
pa->pa_count = opa->pa_count;
pa->pa_flags = opa->pa_flags;
}
_PROP_RWLOCK_UNLOCK(opa->pa_rwlock);
return (pa);
}
/*
* prop_array_copy_mutable --
* Like prop_array_copy(), but the resulting array is mutable.
*/
prop_array_t
prop_array_copy_mutable(prop_array_t opa)
{
prop_array_t pa;
pa = prop_array_copy(opa);
if (pa != NULL)
pa->pa_flags &= ~PA_F_IMMUTABLE;
return (pa);
}
/*
* prop_array_capacity --
* Return the capacity of the array.
*/
unsigned int
prop_array_capacity(prop_array_t pa)
{
unsigned int rv;
if (! prop_object_is_array(pa))
return (0);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = pa->pa_capacity;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_count --
* Return the number of objects stored in the array.
*/
unsigned int
prop_array_count(prop_array_t pa)
{
unsigned int rv;
if (! prop_object_is_array(pa))
return (0);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = pa->pa_count;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_ensure_capacity --
* Ensure that the array has the capacity to store the specified
* total number of objects (inluding the objects already stored
* in the array).
*/
bool
prop_array_ensure_capacity(prop_array_t pa, unsigned int capacity)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (capacity > pa->pa_capacity)
rv = _prop_array_expand(pa, capacity);
else
rv = true;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
static prop_object_iterator_t
_prop_array_iterator_locked(prop_array_t pa)
{
struct _prop_array_iterator *pai;
if (! prop_object_is_array(pa))
return (NULL);
pai = _PROP_CALLOC(sizeof(*pai), M_TEMP);
if (pai == NULL)
return (NULL);
pai->pai_base.pi_next_object = _prop_array_iterator_next_object;
pai->pai_base.pi_reset = _prop_array_iterator_reset;
prop_object_retain(pa);
pai->pai_base.pi_obj = pa;
_prop_array_iterator_reset_locked(pai);
return (&pai->pai_base);
}
/*
* prop_array_iterator --
* Return an iterator for the array. The array is retained by
* the iterator.
*/
prop_object_iterator_t
prop_array_iterator(prop_array_t pa)
{
prop_object_iterator_t pi;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
pi = _prop_array_iterator_locked(pa);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (pi);
}
/*
* prop_array_make_immutable --
* Make the array immutable.
*/
void
prop_array_make_immutable(prop_array_t pa)
{
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (prop_array_is_immutable(pa) == false)
pa->pa_flags |= PA_F_IMMUTABLE;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
}
/*
* prop_array_mutable --
* Returns true if the array is mutable.
*/
bool
prop_array_mutable(prop_array_t pa)
{
bool rv;
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
rv = prop_array_is_immutable(pa) == false;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_get --
* Return the object stored at the specified array index.
*/
prop_object_t
prop_array_get(prop_array_t pa, unsigned int idx)
{
prop_object_t po = NULL;
if (! prop_object_is_array(pa))
return (NULL);
_PROP_RWLOCK_RDLOCK(pa->pa_rwlock);
if (idx >= pa->pa_count)
goto out;
po = pa->pa_array[idx];
_PROP_ASSERT(po != NULL);
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (po);
}
static bool
_prop_array_add(prop_array_t pa, prop_object_t po)
{
/*
* Array must be WRITE-LOCKED.
*/
_PROP_ASSERT(pa->pa_count <= pa->pa_capacity);
if (prop_array_is_immutable(pa) ||
(pa->pa_count == pa->pa_capacity &&
_prop_array_expand(pa, pa->pa_capacity + EXPAND_STEP) == false))
return (false);
prop_object_retain(po);
pa->pa_array[pa->pa_count++] = po;
pa->pa_version++;
return (true);
}
/*
* prop_array_set --
* Store a reference to an object at the specified array index.
* This method is not allowed to create holes in the array; the
* caller must either be setting the object just beyond the existing
* count or replacing an already existing object reference.
*/
bool
prop_array_set(prop_array_t pa, unsigned int idx, prop_object_t po)
{
prop_object_t opo;
bool rv = false;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
if (prop_array_is_immutable(pa))
goto out;
if (idx == pa->pa_count) {
rv = _prop_array_add(pa, po);
goto out;
}
_PROP_ASSERT(idx < pa->pa_count);
opo = pa->pa_array[idx];
_PROP_ASSERT(opo != NULL);
prop_object_retain(po);
pa->pa_array[idx] = po;
pa->pa_version++;
prop_object_release(opo);
rv = true;
out:
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_add --
* Add a reference to an object to the specified array, appending
* to the end and growing the array's capacity, if necessary.
*/
bool
prop_array_add(prop_array_t pa, prop_object_t po)
{
bool rv;
if (! prop_object_is_array(pa))
return (false);
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
rv = _prop_array_add(pa, po);
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return (rv);
}
/*
* prop_array_remove --
* Remove the reference to an object from an array at the specified
* index. The array will be compacted following the removal.
*/
void
prop_array_remove(prop_array_t pa, unsigned int idx)
{
prop_object_t po;
if (! prop_object_is_array(pa))
return;
_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
_PROP_ASSERT(idx < pa->pa_count);
/* XXX Should this be a _PROP_ASSERT()? */
if (prop_array_is_immutable(pa)) {
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
return;
}
po = pa->pa_array[idx];
_PROP_ASSERT(po != NULL);
for (++idx; idx < pa->pa_count; idx++)
pa->pa_array[idx - 1] = pa->pa_array[idx];
pa->pa_count--;
pa->pa_version++;
_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
prop_object_release(po);
}
/*
* prop_array_equals --
* Return true if the two arrays are equivalent. Note we do a
* by-value comparison of the objects in the array.
*/
bool
prop_array_equals(prop_array_t array1, prop_array_t array2)
{
if (!prop_object_is_array(array1) || !prop_object_is_array(array2))
return (false);
return (prop_object_equals(array1, array2));
}
/*
* prop_array_externalize --
* Externalize an array, return a NUL-terminated buffer
* containing the XML-style representation. The buffer is allocated
* with the M_TEMP memory type.
*/
char *
prop_array_externalize(prop_array_t pa)
{
struct _prop_object_externalize_context *ctx;
char *cp;
ctx = _prop_object_externalize_context_alloc();
if (ctx == NULL)
return (NULL);
if (_prop_object_externalize_header(ctx) == false ||
(*pa->pa_obj.po_type->pot_extern)(ctx, pa) == false ||
_prop_object_externalize_footer(ctx) == false) {
/* We are responsible for releasing the buffer. */
_PROP_FREE(ctx->poec_buf, M_TEMP);
_prop_object_externalize_context_free(ctx);
return (NULL);
}
cp = ctx->poec_buf;
_prop_object_externalize_context_free(ctx);
return (cp);
}
/*
* _prop_array_internalize --
* Parse an <array>...</array> and return the object created from the
* external representation.
*/
static bool _prop_array_internalize_body(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool
_prop_array_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
/* We don't currently understand any attributes. */
if (ctx->poic_tagattr != NULL)
return (true);
*obj = prop_array_create();
/*
* We are done if the create failed or no child elements exist.
*/
if (*obj == NULL || ctx->poic_is_empty_element)
return (true);
/*
* Opening tag is found, now continue to the first element.
*/
return (_prop_array_internalize_body(stack, obj, ctx));
}
static bool
_prop_array_internalize_continue(prop_stack_t stack,
prop_object_t *obj,
struct _prop_object_internalize_context *ctx,
void *data, prop_object_t child)
{
prop_array_t array;
_PROP_ASSERT(data == NULL);
if (child == NULL)
goto bad; /* Element could not be parsed. */
array = *obj;
if (prop_array_add(array, child) == false) {
prop_object_release(child);
goto bad;
}
prop_object_release(child);
/*
* Current element is processed and added, look for next.
*/
return (_prop_array_internalize_body(stack, obj, ctx));
bad:
prop_object_release(*obj);
*obj = NULL;
return (true);
}
static bool
_prop_array_internalize_body(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
prop_array_t array = *obj;
_PROP_ASSERT(array != NULL);
/* Fetch the next tag. */
if (_prop_object_internalize_find_tag(ctx, NULL,
_PROP_TAG_TYPE_EITHER) == false)
goto bad;
/* Check to see if this is the end of the array. */
if (_PROP_TAG_MATCH(ctx, "array") &&
ctx->poic_tag_type == _PROP_TAG_TYPE_END) {
/* It is, so don't iterate any further. */
return (true);
}
if (_prop_stack_push(stack, array,
_prop_array_internalize_continue, NULL, NULL))
return (false);
bad:
prop_object_release(array);
*obj = NULL;
return (true);
}
/*
* prop_array_internalize --
* Create an array by parsing the XML-style representation.
*/
prop_array_t
prop_array_internalize(const char *xml)
{
return _prop_generic_internalize(xml, "array");
}
#if !defined(_KERNEL) && !defined(_STANDALONE)
/*
* prop_array_externalize_to_file --
* Externalize an array to the specified file.
*/
bool
prop_array_externalize_to_file(prop_array_t array, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0; /* XXXGCC -Wuninitialized [mips, ...] */
xml = prop_array_externalize(array);
if (xml == NULL)
return (false);
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml));
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
if (rv == false)
errno = save_errno;
return (rv);
}
/*
* prop_array_internalize_from_file --
* Internalize an array from a file.
*/
prop_array_t
prop_array_internalize_from_file(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_array_t array;
mf = _prop_object_internalize_map_file(fname);
if (mf == NULL)
return (NULL);
array = prop_array_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return (array);
}
#endif /* _KERNEL && !_STANDALONE */

View file

@ -0,0 +1,228 @@
.\" $NetBSD: prop_array_util.3,v 1.7 2011/10/17 09:24:54 wiz 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.
.\"
.Dd March 12, 2011
.Dt PROP_ARRAY_UTIL 3
.Os
.Sh NAME
.Nm prop_array_util ,
.Nm prop_array_get_bool ,
.Nm prop_array_set_bool ,
.Nm prop_array_get_int8 ,
.Nm prop_array_get_uint8 ,
.Nm prop_array_set_int8 ,
.Nm prop_array_set_uint8 ,
.Nm prop_array_get_int16 ,
.Nm prop_array_get_uint16 ,
.Nm prop_array_set_int16 ,
.Nm prop_array_set_uint16 ,
.Nm prop_array_get_int32 ,
.Nm prop_array_get_uint32 ,
.Nm prop_array_set_int32 ,
.Nm prop_array_set_uint32 ,
.Nm prop_array_get_int64 ,
.Nm prop_array_get_uint64 ,
.Nm prop_array_set_int64 ,
.Nm prop_array_set_uint64 ,
.Nm prop_array_add_int8 ,
.Nm prop_array_add_uint8 ,
.Nm prop_array_add_int16 ,
.Nm prop_array_add_uint16 ,
.Nm prop_array_add_int32 ,
.Nm prop_array_add_uint32 ,
.Nm prop_array_add_int64 ,
.Nm prop_array_add_uint64 ,
.Nm prop_array_get_cstring ,
.Nm prop_array_set_cstring ,
.Nm prop_array_get_cstring_nocopy ,
.Nm prop_array_set_cstring_nocopy ,
.Nm prop_array_add_and_rel
.Nd array property collection object utility functions
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft bool
.Fn prop_array_get_bool "prop_array_t dict" "unsigned int indx" \
"bool *valp"
.Ft bool
.Fn prop_array_set_bool "prop_array_t dict" "unsigned int indx" \
"bool val"
.\"
.Ft bool
.Fn prop_array_get_int8 "prop_array_t dict" "unsigned int indx" \
"int8_t *valp"
.Ft bool
.Fn prop_array_get_uint8 "prop_array_t dict" "unsigned int indx" \
"uint8_t *valp"
.Ft bool
.Fn prop_array_set_int8 "prop_array_t dict" "unsigned int indx" \
"int8_t val"
.Ft bool
.Fn prop_array_set_uint8 "prop_array_t dict" "unsigned int indx" \
"uint8_t val"
.\"
.Ft bool
.Fn prop_array_get_int16 "prop_array_t dict" "unsigned int indx" \
"int16_t *valp"
.Ft bool
.Fn prop_array_get_uint16 "prop_array_t dict" "unsigned int indx" \
"uint16_t *valp"
.Ft bool
.Fn prop_array_set_int16 "prop_array_t dict" "unsigned int indx" \
"int16_t val"
.Ft bool
.Fn prop_array_set_uint16 "prop_array_t dict" "unsigned int indx" \
"uint16_t val"
.\"
.Ft bool
.Fn prop_array_get_int32 "prop_array_t dict" "unsigned int indx" \
"int32_t *valp"
.Ft bool
.Fn prop_array_get_uint32 "prop_array_t dict" "unsigned int indx" \
"uint32_t *valp"
.Ft bool
.Fn prop_array_set_int32 "prop_array_t dict" "unsigned int indx" \
"int32_t val"
.Ft bool
.Fn prop_array_set_uint32 "prop_array_t dict" "unsigned int indx" \
"uint32_t val"
.\"
.Ft bool
.Fn prop_array_get_int64 "prop_array_t dict" "unsigned int indx" \
"int64_t *valp"
.Ft bool
.Fn prop_array_get_uint64 "prop_array_t dict" "unsigned int indx" \
"uint64_t *valp"
.Ft bool
.Fn prop_array_set_int64 "prop_array_t dict" "unsigned int indx" \
"int64_t val"
.Ft bool
.Fn prop_array_set_uint64 "prop_array_t dict" "unsigned int indx" \
"uint64_t val"
.\"
.Ft bool
.Fn prop_array_set_int32 "prop_array_t dict" "unsigned int indx" \
"int32_t val"
.Ft bool
.Fn prop_array_set_uint32 "prop_array_t dict" "unsigned int indx" \
"uint32_t val"
.\"
.Ft bool
.Fn prop_array_add_int8 "prop_array_t dict" "int8_t val"
.Ft bool
.Fn prop_array_add_uint8 "prop_array_t dict" "uint8_t val"
.Ft bool
.Fn prop_array_add_int16 "prop_array_t dict" "int16_t val"
.Ft bool
.Fn prop_array_add_uint16 "prop_array_t dict" "uint16_t val"
.Ft bool
.Fn prop_array_add_int32 "prop_array_t dict" "int32_t val"
.Ft bool
.Fn prop_array_add_uint32 "prop_array_t dict" "uint32_t val"
.Ft bool
.Fn prop_array_add_int64 "prop_array_t dict" "int64_t val"
.Ft bool
.Fn prop_array_add_uint64 "prop_array_t dict" "uint64_t val"
.\"
.Ft bool
.Fn prop_array_get_cstring "prop_array_t dict" "unsigned int indx" \
"char **strp"
.Ft bool
.Fn prop_array_set_cstring "prop_array_t dict" "unsigned int indx" \
"const char *str"
.\"
.Ft bool
.Fn prop_array_get_cstring_nocopy "prop_array_t dict" \
"unsigned int indx" "const char **strp"
.Ft bool
.Fn prop_array_set_cstring_nocopy "prop_array_t dict" \
"unsigned int indx" "const char *strp"
.Ft bool
.Fn prop_array_add_and_rel "prop_array_t dict" \
"prop_object_t obj"
.Sh DESCRIPTION
The
.Nm prop_array_util
family of functions are provided to make getting and setting values in
arrays more convenient in some applications.
.Pp
The getters check the type of the returned object and, in some cases, also
ensure that the returned value is within the range implied by the getter's
value type.
.Pp
The setters handle object creation and release for the caller.
.Pp
The
.Fn prop_array_get_cstring
function returns dynamically allocated memory.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_array_get_cstring_nocopy
and
.Fn prop_array_set_cstring_nocopy
functions do not copy the string that is set or returned.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_array_add_and_rel
function adds the object to the end of the array and releases it.
The object is also released on failure.
.Sh RETURN VALUES
The
.Nm prop_array_util
getter functions return
.Dv true
if the object exists in the array and the value is in-range, or
.Dv false
otherwise.
.Pp
The
.Nm prop_array_util
setter functions return
.Dv true
if creating the object and storing it in the array is successful, or
.Dv false
otherwise.
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_number 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,251 @@
/* $NetBSD: prop_array_util.c,v 1.3 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Utility routines to make it more convenient to work with values
* stored in 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" /* hide kernel vs. not-kernel vs. standalone */
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
bool
prop_array_add_and_rel(prop_array_t array, prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_array_add(array, po);
prop_object_release(po);
return ret;
}

View file

@ -0,0 +1,82 @@
.\" $NetBSD: prop_bool.3,v 1.6 2008/08/03 03:11:28 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.
.\"
.Dd April 22, 2006
.Dt PROP_BOOL 3
.Os
.Sh NAME
.Nm prop_bool ,
.Nm prop_bool_create ,
.Nm prop_bool_copy ,
.Nm prop_bool_true
.Nd boolean value property object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_bool_t
.Fn prop_bool_create "bool val"
.Ft prop_bool_t
.Fn prop_bool_copy "prop_bool_t bool"
.\"
.Ft bool
.Fn prop_bool_true "prop_bool_t bool"
.Sh DESCRIPTION
The
.Nm prop_bool
family of functions operate on a boolean value property object type.
.Bl -tag -width "xxxxx"
.It Fn prop_bool_create "bool val"
Create a boolean value object with the value
.Fa val .
.It Fn prop_bool_copy "prop_bool_t bool"
Copy a boolean value object.
If the supplied object isn't a boolean,
.Dv NULL
is returned.
.It Fn prop_bool_true "prop_bool_t bool"
Returns the value of the boolean value object.
If the supplied object isn't a boolean,
.Dv false
is returned.
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,222 @@
/* $NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/prop_bool.h>
#include "prop_object_impl.h"
struct _prop_bool {
struct _prop_object pb_obj;
bool pb_value;
};
static struct _prop_bool _prop_bool_true;
static struct _prop_bool _prop_bool_false;
static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t, prop_object_t *);
static bool _prop_bool_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static const struct _prop_object_type _prop_object_type_bool = {
.pot_type = PROP_TYPE_BOOL,
.pot_free = _prop_bool_free,
.pot_extern = _prop_bool_externalize,
.pot_equals = _prop_bool_equals,
};
#define prop_object_is_bool(x) \
((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t stack, prop_object_t *obj)
{
/*
* This should never happen as we "leak" our initial reference
* count.
*/
/* XXX forced assertion failure? */
return (_PROP_OBJECT_FREE_DONE);
}
static bool
_prop_bool_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_bool_t pb = v;
return (_prop_object_externalize_empty_tag(ctx,
pb->pb_value ? "true" : "false"));
}
/* ARGSUSED */
static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t v1, prop_object_t v2,
void **stored_pointer1, void **stored_pointer2,
prop_object_t *next_obj1, prop_object_t *next_obj2)
{
prop_bool_t b1 = v1;
prop_bool_t b2 = v2;
if (! (prop_object_is_bool(b1) &&
prop_object_is_bool(b2)))
return (_PROP_OBJECT_EQUALS_FALSE);
/*
* Since we only ever allocate one true and one false,
* save ourselves a couple of memory operations.
*/
if (b1 == b2)
return (_PROP_OBJECT_EQUALS_TRUE);
else
return (_PROP_OBJECT_EQUALS_FALSE);
}
_PROP_ONCE_DECL(_prop_bool_init_once)
static int
_prop_bool_init(void)
{
_prop_object_init(&_prop_bool_true.pb_obj,
&_prop_object_type_bool);
_prop_bool_true.pb_value = true;
_prop_object_init(&_prop_bool_false.pb_obj,
&_prop_object_type_bool);
_prop_bool_false.pb_value = false;
return 0;
}
static prop_bool_t
_prop_bool_alloc(bool val)
{
prop_bool_t pb;
_PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
pb = val ? &_prop_bool_true : &_prop_bool_false;
prop_object_retain(pb);
return (pb);
}
/*
* prop_bool_create --
* Create a prop_bool_t and initialize it with the
* provided boolean value.
*/
prop_bool_t
prop_bool_create(bool val)
{
return (_prop_bool_alloc(val));
}
/*
* prop_bool_copy --
* Copy a prop_bool_t.
*/
prop_bool_t
prop_bool_copy(prop_bool_t opb)
{
if (! prop_object_is_bool(opb))
return (NULL);
/*
* Because we only ever allocate one true and one false, this
* can be reduced to a simple retain operation.
*/
prop_object_retain(opb);
return (opb);
}
/*
* prop_bool_true --
* Get the value of a prop_bool_t.
*/
bool
prop_bool_true(prop_bool_t pb)
{
if (! prop_object_is_bool(pb))
return (false);
return (pb->pb_value);
}
/*
* prop_bool_equals --
* Return true if the boolean values are equivalent.
*/
bool
prop_bool_equals(prop_bool_t b1, prop_bool_t b2)
{
if (!prop_object_is_bool(b1) || !prop_object_is_bool(b2))
return (false);
return (prop_object_equals(b1, b2));
}
/*
* _prop_bool_internalize --
* Parse a <true/> or <false/> and return the object created from
* the external representation.
*/
/* ARGSUSED */
bool
_prop_bool_internalize(prop_stack_t stack, prop_object_t *obj,
struct _prop_object_internalize_context *ctx)
{
bool val;
/* No attributes, and it must be an empty element. */
if (ctx->poic_tagattr != NULL ||
ctx->poic_is_empty_element == false)
return (true);
if (_PROP_TAG_MATCH(ctx, "true"))
val = true;
else {
_PROP_ASSERT(_PROP_TAG_MATCH(ctx, "false"));
val = false;
}
*obj = prop_bool_create(val);
return (true);
}

View file

@ -0,0 +1,194 @@
.\" $NetBSD: prop_copyin_ioctl.9,v 1.9 2011/01/20 10:47:33 wiz Exp $
.\"
.\" Copyright (c) 2006, 2009 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.
.\"
.Dd January 17, 2011
.Dt PROP_COPYIN_IOCTL 9
.Os
.Sh NAME
.Nm prop_array_copyin_ioctl ,
.Nm prop_array_copyout_ioctl ,
.Nm prop_array_copyin ,
.Nm prop_array_copyout ,
.Nm prop_dictionary_copyin_ioctl ,
.Nm prop_dictionary_copyout_ioctl ,
.Nm prop_dictionary_copyin ,
.Nm prop_dictionary_copyout
.Nd Copy property lists to and from kernel space
.Sh SYNOPSIS
.In prop/proplib.h
.Ft int
.Fn prop_array_copyin_ioctl "const struct plistref *pref" \
"const u_long cmd" "prop_array_t *arrayp"
.Ft int
.Fn prop_array_copyin "const struct plistref *pref" \
"prop_array_t *arrayp"
.Ft int
.Fn prop_array_copyout_ioctl "struct plistref *pref" \
"const u_long cmd" "prop_array_t array"
.Ft int
.Fn prop_array_copyout "struct plistref *pref" \
"prop_array_t array"
.Ft int
.Fn prop_dictionary_copyin_ioctl "const struct plistref *pref" \
"const u_long cmd" "prop_dictionary_t *dictp"
.Ft int
.Fn prop_dictionary_copyin "const struct plistref *pref" \
"prop_dictionary_t *dictp"
.Ft int
.Fn prop_dictionary_copyout_ioctl "struct plistref *pref" \
"const u_long cmd" "prop_dictionary_t dict"
.Ft int
.Fn prop_dictionary_copyout "struct plistref *pref" \
"prop_dictionary_t dict"
.Sh DESCRIPTION
The
.Nm prop_array_copyin_ioctl ,
.Nm prop_array_copyout_ioctl ,
.Nm prop_dictionary_copyin_ioctl ,
and
.Nm prop_dictionary_copyout_ioctl
functions implement the kernel side of a protocol for copying property lists
to and from the kernel using
.Xr ioctl 2 .
The functions
.Nm prop_array_copyin ,
.Nm prop_array_copyout ,
.Nm prop_dictionary_copyin ,
and
.Nm prop_dictionary_copyout
implement the kernel side of a protocol for copying property lists to the
kernel as arguments of normal system calls.
.Pp
A kernel routine receiving or returning a property list will be passed a
pointer to a
.Vt struct plistref .
This structure encapsulates the reference to the property list in externalized
form.
.Sh RETURN VALUES
If successful, functions return zero.
Otherwise, an error number will be returned to indicate the error.
.Sh EXAMPLES
The following
.Pq simplified
example demonstrates using
.Fn prop_dictionary_copyin_ioctl
and
.Fn prop_dictionary_copyout_ioctl
in an ioctl routine:
.Bd -literal
extern prop_dictionary_t fooprops;
int
fooioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l)
{
prop_dictionary_t dict, odict;
int error;
switch (cmd) {
case FOOSETPROPS: {
const struct plistref *pref = (const struct plistref *) data;
error = prop_dictionary_copyin_ioctl(pref, cmd, \*[Am]dict);
if (error)
return (error);
odict = fooprops;
fooprops = dict;
prop_object_release(odict);
break;
}
case FOOGETPROPS: {
struct plistref *pref = (struct plistref *) data;
error = prop_dictionary_copyout_ioctl(pref, cmd, fooprops);
break;
}
default:
return (EPASSTHROUGH);
}
return (error);
}
.Ed
.Pp
The following
.Pq simplified
example demonstrates using
.Fn prop_array_copyin
in a routine:
.Bd -literal
int
foocopyin(const struct plistref *pref))
{
prop_array_t array;
int error;
error = prop_array_copyin(pref, \*[Am]array);
if (error)
return (error);
...
}
.Ed
.Sh ERRORS
.Fn prop_array_copyin_ioctl
and
.Fn prop_dictionary_copyin_ioctl
will fail if:
.Bl -tag -width Er
.It Bq Er EFAULT
Bad address
.It Bq Er EIO
Input/output error
.It Bq Er ENOMEM
Cannot allocate memory
.It Bq Er ENOTSUP
Not supported
.El
.Pp
.Fn prop_array_copyout_ioctl
and
.Fn prop_dictionary_copyout_ioctl
will fail if:
.Bl -tag -width Er
.It Bq Er EFAULT
Bad address
.It Bq Er ENOMEM
Cannot allocate memory
.It Bq Er ENOTSUP
Not supported
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_send_ioctl 3 ,
.Xr prop_send_syscall 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,148 @@
.\" $NetBSD: prop_data.3,v 1.7 2009/12/14 06:03:23 dholland 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.
.\"
.Dd April 22, 2006
.Dt PROP_DATA 3
.Os
.Sh NAME
.Nm prop_data ,
.Nm prop_data_create_data ,
.Nm prop_data_create_data_nocopy ,
.Nm prop_data_copy ,
.Nm prop_data_size ,
.Nm prop_data_data ,
.Nm prop_data_data_nocopy ,
.Nm prop_data_equals ,
.Nm prop_data_equals_data
.Nd opaque data value property object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_data_t
.Fn prop_data_create_data "const void *blob" "size_t len"
.Ft prop_data_t
.Fn prop_data_create_data_nocopy "const void *blob" "size_t len"
.\"
.Ft prop_data_t
.Fn prop_data_copy "prop_data_t data"
.\"
.Ft size_t
.Fn prop_data_size "prop_data_t data"
.Ft void *
.Fn prop_data_data "prop_data_t data"
.Ft const void *
.Fn prop_data_data_nocopy "prop_data_t data"
.\"
.Ft bool
.Fn prop_data_equals "prop_data_t dat1" "prop_data_t dat2"
.Ft bool
.Fn prop_data_equals_data "prop_data_t data" "const void *blob" "size_t len"
.Sh DESCRIPTION
The
.Nm prop_data
family of functions operate on an opaque data value property object type.
.Bl -tag -width "xxxxx"
.It Fn prop_data_create_data "const void *blob" "size_t len"
Create a data object that contains a copy of
.Fa blob
with size
.Fa len .
Returns
.Dv NULL
on failure.
.It Fn prop_data_create_data_nocopy "const void *blob" "size_t len"
Create a data object that contains a reference to
.Fa blob
with size
.Fa len .
Returns
.Dv NULL
on failure.
.It Fn prop_data_copy "prop_data_t data"
Copy a data object.
If the data object being copied is an external data reference,
then the copy also references the same external data.
Returns
.Dv NULL
on failure.
.It Fn prop_data_size "prop_data_t data"
Returns the size of the data object.
If the supplied object isn't a data object, zero is returned.
.It Fn prop_data_data "prop_data_t data"
Returns a copy of the data object's contents.
The caller is responsible for freeing the returned buffer.
If the supplied object isn't a data object or
if the data container is empty,
.Dv NULL
is returned.
.Pp
In user space, the buffer is allocated using
.Xr malloc 3 .
In the kernel, the buffer is allocated using
.Xr malloc 9
using the malloc type
.Dv M_TEMP .
.It Fn prop_data_data_nocopy "prop_data_t data"
Returns an immutable reference to the contents of the data object.
If the supplied object isn't a data object,
.Dv NULL
is returned.
.It Fn prop_data_equals "prop_data_t dat1" "prop_data_t dat2"
Returns
.Dv true
if the two data objects are equivalent.
If at least one of the supplied objects isn't a data object,
.Dv false
is returned.
.It Fn prop_data_equals_data "prop_data_t data" "const void *blob" "size_t len"
Returns
.Dv true
if the data object's value is equivalent to
.Fa blob
with size
.Fa len .
If the supplied object isn't a data object,
.Dv false
is returned.
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,627 @@
/* $NetBSD: prop_data.c,v 1.14 2009/01/25 06:59:35 cyber 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"
#if defined(_KERNEL)
#include <sys/systm.h>
#elif defined(_STANDALONE)
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#else
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#endif
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);
#ifndef _KERNEL
errno = 0;
#endif
len = strtoul(ctx->poic_tagattrval, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if (len == ULONG_MAX && errno == ERANGE)
return (true);
#endif
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);
}

View file

@ -0,0 +1,353 @@
.\" $NetBSD: prop_dictionary.3,v 1.18 2011/09/30 22:08:18 jym Exp $
.\"
.\" Copyright (c) 2006, 2009 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.
.\"
.Dd December 5, 2009
.Dt PROP_DICTIONARY 3
.Os
.Sh NAME
.Nm prop_dictionary ,
.Nm prop_dictionary_create ,
.Nm prop_dictionary_create_with_capacity ,
.Nm prop_dictionary_copy ,
.Nm prop_dictionary_copy_mutable ,
.Nm prop_dictionary_count ,
.Nm prop_dictionary_ensure_capacity ,
.Nm prop_dictionary_iterator ,
.Nm prop_dictionary_all_keys ,
.Nm prop_dictionary_make_immutable ,
.Nm prop_dictionary_mutable ,
.Nm prop_dictionary_get ,
.Nm prop_dictionary_set ,
.Nm prop_dictionary_remove ,
.Nm prop_dictionary_get_keysym ,
.Nm prop_dictionary_set_keysym ,
.Nm prop_dictionary_remove_keysym ,
.Nm prop_dictionary_externalize ,
.Nm prop_dictionary_internalize ,
.Nm prop_dictionary_externalize_to_file ,
.Nm prop_dictionary_internalize_from_file ,
.Nm prop_dictionary_externalize_to_pref ,
.Nm prop_dictionary_internalize_from_pref ,
.Nm prop_dictionary_equals ,
.Nm prop_dictionary_keysym_cstring_nocopy ,
.Nm prop_dictionary_keysym_equals
.Nd dictionary property collection object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_dictionary_t
.Fn prop_dictionary_create "void"
.Ft prop_dictionary_t
.Fn prop_dictionary_create_with_capacity "unsigned int capacity"
.\"
.Ft prop_dictionary_t
.Fn prop_dictionary_copy "prop_dictionary_t dict"
.Ft prop_dictionary_t
.Fn prop_dictionary_copy_mutable "prop_dictionary_t dict"
.\"
.Ft unsigned int
.Fn prop_dictionary_count "prop_dictionary_t dict"
.Ft bool
.Fn prop_dictionary_ensure_capacity "prop_dictionary_t dict" \
"unsigned int capacity"
.\"
.Ft prop_object_iterator_t
.Fn prop_dictionary_iterator "prop_dictionary_t dict"
.Ft prop_array_t
.Fn prop_dictionary_all_keys "prop_dictionary_t dict"
.\"
.Ft void
.Fn prop_dictionary_make_immutable "prop_dictionary_t dict"
.Ft bool
.Fn prop_dictionary_mutable "prop_dictionary_t dict"
.\"
.Ft prop_object_t
.Fn prop_dictionary_get "prop_dictionary_t dict" "const char *key"
.Ft bool
.Fn prop_dictionary_set "prop_dictionary_t dict" "const char *key" \
"prop_object_t obj"
.Ft void
.Fn prop_dictionary_remove "prop_dictionary_t dict" "const char *key"
.\"
.Ft prop_object_t
.Fn prop_dictionary_get_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t keysym"
.Ft bool
.Fn prop_dictionary_set_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t keysym" "prop_object_t obj"
.Ft void
.Fn prop_dictionary_remove_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t keysym"
.\"
.Ft bool
.Fn prop_dictionary_equals "prop_dictionary_t dict1" "prop_dictionary_t dict2"
.\"
.Ft const char *
.Fn prop_dictionary_keysym_cstring_nocopy "prop_dictionary_keysym_t sym"
.\"
.Ft bool
.Fn prop_dictionary_keysym_equals "prop_dictionary_keysym_t keysym1" \
"prop_dictionary_keysym_t keysym2"
.\"
.Ft char *
.Fn prop_dictionary_externalize "prop_dictionary_t dict"
.Ft prop_dictionary_t
.Fn prop_dictionary_internalize "const char *xml"
.\"
.Ft bool
.Fn prop_dictionary_externalize_to_file "prop_dictionary_t dict" \
"const char *path"
.Ft prop_dictionary_t
.Fn prop_dictionary_internalize_from_file "const char *path"
.\"
.Ft bool
.Fn prop_dictionary_externalize_to_pref "prop_dictionary_t dict" \
"struct plistref *pref"
.Ft bool
.Fn prop_dictionary_internalize_from_pref "const struct plistref *pref" \
"prop_dictionary_t *dictp"
.\"
.Sh DESCRIPTION
The
.Nm prop_dictionary
family of functions operate on the dictionary property collection object type.
A dictionary is an unordered set of objects stored as key-value pairs.
.Bl -tag -width "xxxxx"
.It Fn prop_dictionary_create "void"
Create an empty dictionary.
The dictionary initially has no capacity.
Returns
.Dv NULL
on failure.
.It Fn prop_dictionary_create_with_capacity "unsigned int capacity"
Create a dictionary with the capacity to store
.Fa capacity
objects.
Returns
.Dv NULL
on failure.
.It Fn prop_dictionary_copy "prop_dictionary_t dict"
Copy a dictionary.
The new dictionary has an initial capacity equal to the number of objects
stored in the dictionary being copied.
The new dictionary contains references to the original dictionary's objects,
not copies of those objects
.Pq i.e. a shallow copy is made .
If the original dictionary is immutable, the resulting dictionary is also
immutable.
.It Fn prop_dictionary_copy_mutable "prop_dictionary_t dict"
Like
.Fn prop_dictionary_copy ,
except the resulting dictionary is always mutable.
.It Fn prop_dictionary_count "prop_dictionary_t dict"
Returns the number of objects stored in the dictionary.
.It Fn prop_dictionary_ensure_capacity "prop_dictionary_t dict" \
"unsigned int capacity"
Ensure that the dictionary has a total capacity of
.Fa capacity ,
including objects already stored in the dictionary.
Returns
.Dv true
if the capacity of the dictionary is greater or equal to
.Fa capacity
or if the expansion of the dictionary's capacity was successful
and
.Dv false
otherwise.
If the supplied object isn't a dictionary,
.Dv false
is returned.
.It Fn prop_dictionary_iterator "prop_dictionary_t dict"
Create an iterator for the dictionary.
The dictionary is retained by the iterator.
A dictionary iterator returns the key symbols used to look up objects stored
in the dictionary; to get the object itself, a dictionary lookup using this
key symbol must be performed.
Storing to or removing from the dictionary invalidates any active iterators for
the dictionary.
Returns
.Dv NULL
on failure.
.It Fn prop_dictionary_all_keys "prop_dictionary_t dict"
Return an array of all of the dictionary key symbols
.Pq prop_dictionary_keysym_t
in the dictionary.
This provides a way to iterate over the items in the dictionary while
retaining the ability to mutate the dictionary; instead of iterating
over the dictionary itself, iterate over the array of keys.
The caller is responsible for releasing the array.
Returns
.Dv NULL
on failure.
.It Fn prop_dictionary_make_immutable "prop_dictionary_t dict"
Make
.Fa dict
immutable.
.It Fn prop_dictionary_mutable "prop_dictionary_t dict"
Returns
.Dv true
if the dictionary is mutable.
.It Fn prop_dictionary_get "prop_dictionary_t dict" "const char *key"
Return the object stored in the dictionary with the key
.Fa key .
If no object is stored with the specified key,
.Dv NULL
is returned.
.It Fn prop_dictionary_set "prop_dictionary_t dict" "const char *key" \
"prop_object_t obj"
Store a reference to the object
.Fa obj
with the key
.Fa key .
The object will be retained by the dictionary.
If the key already exists in the dictionary, the object associated with
that key will be released and replaced with the new object.
Returns
.Dv true
if storing the object was successful and
.Dv false
otherwise.
.It Fn prop_dictionary_remove "prop_dictionary_t dict" "const char *key"
Remove the reference to the object stored in the dictionary with the key
.Fa key .
The object will be released.
.It Fn prop_dictionary_get_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t sym"
Like
.Fn prop_dictionary_get ,
but the lookup is performed using a key symbol returned by a dictionary
iterator.
The results are undefined if the iterator used to obtain the key symbol
is not associated with
.Fa dict .
.It Fn prop_dictionary_set_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t sym" "prop_object_t obj"
Like
.Fn prop_dictionary_set ,
but the lookup of the object to replace is performed using a key symbol
returned by a dictionary iterator.
The results are undefined if the iterator used to obtain the key symbol
is not associated with
.Fa dict .
.It Fn prop_dictionary_remove_keysym "prop_dictionary_t dict" \
"prop_dictionary_keysym_t sym"
Like
.Fn prop_dictionary_remove ,
but the lookup of the object to remove is performed using a key symbol
returned by a dictionary iterator.
The results are undefined if the iterator used to obtain the key symbol
is not associated with
.Fa dict .
.It Fn prop_dictionary_equals "prop_dictionary_t dict1" \
"prop_dictionary_t dict2"
Returns
.Dv true
if the two dictionaries are equivalent.
Note: Objects contained in the dictionary are compared by value, not by
reference.
.It Fn prop_dictionary_keysym_cstring_nocopy "prop_dictionary_keysym_t keysym"
Returns an immutable reference to the dictionary key symbol's string value.
.It Fn prop_dictionary_keysym_equals "prop_dictionary_keysym_t keysym1" \
"prop_dictionary_keysym_t keysym2"
Returns
.Dv true
if the two dictionary key symbols are equivalent.
.It Fn prop_dictionary_externalize "prop_dictionary_t dict"
Externalizes a dictionary, returning a NUL-terminated buffer containing
the XML representation of the dictionary.
The caller is responsible for freeing the returned buffer.
If converting to the external representation fails for any reason,
.Dv NULL
is returned.
.Pp
In user space, the buffer is allocated using
.Xr malloc 3 .
In the kernel, the buffer is allocated using
.Xr malloc 9
using the malloc type
.Dv M_TEMP .
.It Fn prop_dictionary_internalize "const char *xml"
Parse the XML representation of a property list in the NUL-terminated
buffer
.Fa xml
and return the corresponding dictionary.
Returns
.Dv NULL
if parsing fails for any reason.
.It Fn prop_dictionary_externalize_to_file "prop_dictionary_t dict" \
"const char *path"
Externalizes a dictionary and writes it to the file specified by
.Fa path .
The file is saved with the mode
.Dv 0666
as modified by the process's file creation mask
.Pq see Xr umask 2
and is written atomically.
Returns
.Dv false
if externalizing or writing the dictionary fails for any reason.
.It Fn prop_dictionary_internalize_from_file "const char *path"
Reads the XML property list contained in the file specified by
.Fa path ,
internalizes it, and returns the corresponding dictionary.
Returns
.Dv NULL
on failure.
.It Fn prop_dictionary_externalize_to_pref "prop_dictionary_t dict" \
"struct plistref *pref"
Externalizes a dictionary and packs it into the plistref specified by
.Fa pref .
Returns
.Dv false
if externalizing the dictionary fails for any reason.
.It Fn prop_dictionary_internalize_from_pref "const struct plistref *pref" \
"prop_dictionary_t *dictp"
Reads the plistref specified by
.Fa pref ,
internalizes it, and returns the corresponding dictionary.
Returns
.Dv false
if internalizing or writing the dictionary fails for any reason.
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary_util 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,200 @@
.\" $NetBSD: prop_dictionary_util.3,v 1.8 2011/10/17 09:24:54 wiz 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.
.\"
.Dd August 7, 2011
.Dt PROP_DICTIONARY_UTIL 3
.Os
.Sh NAME
.Nm prop_dictionary_util ,
.Nm prop_dictionary_get_dict ,
.Nm prop_dictionary_get_bool ,
.Nm prop_dictionary_set_bool ,
.Nm prop_dictionary_get_int8 ,
.Nm prop_dictionary_get_uint8 ,
.Nm prop_dictionary_set_int8 ,
.Nm prop_dictionary_set_uint8 ,
.Nm prop_dictionary_get_int16 ,
.Nm prop_dictionary_get_uint16 ,
.Nm prop_dictionary_set_int16 ,
.Nm prop_dictionary_set_uint16 ,
.Nm prop_dictionary_get_int32 ,
.Nm prop_dictionary_get_uint32 ,
.Nm prop_dictionary_set_int32 ,
.Nm prop_dictionary_set_uint32 ,
.Nm prop_dictionary_get_int64 ,
.Nm prop_dictionary_get_uint64 ,
.Nm prop_dictionary_set_int64 ,
.Nm prop_dictionary_set_uint64 ,
.Nm prop_dictionary_get_cstring ,
.Nm prop_dictionary_set_cstring ,
.Nm prop_dictionary_get_cstring_nocopy ,
.Nm prop_dictionary_set_cstring_nocopy ,
.Nm prop_dictionary_set_and_rel
.Nd dictionary property collection object utility functions
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft bool
.Fn prop_dictionary_get_dict "prop_dictionary_t dict" "const char *key" \
"prop_dictionary_t *dictp"
.Ft bool
.Fn prop_dictionary_get_bool "prop_dictionary_t dict" "const char *key" \
"bool *valp"
.Ft bool
.Fn prop_dictionary_set_bool "prop_dictionary_t dict" "const char *key" \
"bool val"
.\"
.Ft bool
.Fn prop_dictionary_get_int8 "prop_dictionary_t dict" "const char *key" \
"int8_t *valp"
.Ft bool
.Fn prop_dictionary_get_uint8 "prop_dictionary_t dict" "const char *key" \
"uint8_t *valp"
.Ft bool
.Fn prop_dictionary_set_int8 "prop_dictionary_t dict" "const char *key" \
"int8_t val"
.Ft bool
.Fn prop_dictionary_set_uint8 "prop_dictionary_t dict" "const char *key" \
"uint8_t val"
.\"
.Ft bool
.Fn prop_dictionary_get_int16 "prop_dictionary_t dict" "const char *key" \
"int16_t *valp"
.Ft bool
.Fn prop_dictionary_get_uint16 "prop_dictionary_t dict" "const char *key" \
"uint16_t *valp"
.Ft bool
.Fn prop_dictionary_set_int16 "prop_dictionary_t dict" "const char *key" \
"int16_t val"
.Ft bool
.Fn prop_dictionary_set_uint16 "prop_dictionary_t dict" "const char *key" \
"uint16_t val"
.\"
.Ft bool
.Fn prop_dictionary_get_int32 "prop_dictionary_t dict" "const char *key" \
"int32_t *valp"
.Ft bool
.Fn prop_dictionary_get_uint32 "prop_dictionary_t dict" "const char *key" \
"uint32_t *valp"
.Ft bool
.Fn prop_dictionary_set_int32 "prop_dictionary_t dict" "const char *key" \
"int32_t val"
.Ft bool
.Fn prop_dictionary_set_uint32 "prop_dictionary_t dict" "const char *key" \
"uint32_t val"
.\"
.Ft bool
.Fn prop_dictionary_get_int64 "prop_dictionary_t dict" "const char *key" \
"int64_t *valp"
.Ft bool
.Fn prop_dictionary_get_uint64 "prop_dictionary_t dict" "const char *key" \
"uint64_t *valp"
.Ft bool
.Fn prop_dictionary_set_int64 "prop_dictionary_t dict" "const char *key" \
"int64_t val"
.Ft bool
.Fn prop_dictionary_set_uint64 "prop_dictionary_t dict" "const char *key" \
"uint64_t val"
.\"
.Ft bool
.Fn prop_dictionary_get_cstring "prop_dictionary_t dict" "const char *key" \
"char **strp"
.Ft bool
.Fn prop_dictionary_set_cstring "prop_dictionary_t dict" "const char *key" \
"const char *str"
.\"
.Ft bool
.Fn prop_dictionary_get_cstring_nocopy "prop_dictionary_t dict" \
"const char *key" "const char **strp"
.Ft bool
.Fn prop_dictionary_set_cstring_nocopy "prop_dictionary_t dict" \
"const char *key" "const char *strp"
.Ft bool
.Fn prop_dictionary_set_and_rel "prop_dictionary_t dict" \
"const char *key" "prop_object_t obj"
.Sh DESCRIPTION
The
.Nm prop_dictionary_util
family of functions are provided to make getting and setting values in
dictionaries more convenient in some applications.
.Pp
The getters check the type of the returned object and, in some cases, also
ensure that the returned value is within the range implied by the getter's
value type.
.Pp
The setters handle object creation and release for the caller.
.Pp
The
.Fn prop_dictionary_get_cstring
function returns dynamically allocated memory.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_dictionary_get_cstring_nocopy
and
.Fn prop_dictionary_set_cstring_nocopy
functions do not copy the string that is set or returned.
See
.Xr prop_string 3
for more information.
.Pp
The
.Fn prop_dictionary_set_and_rel
function adds the object to the dictionary and releases it.
The object is also released on failure.
.Sh RETURN VALUES
The
.Nm prop_dictionary_util
getter functions return
.Dv true
if the object exists in the dictionary and the value is in-range, or
.Dv false
otherwise.
.Pp
The
.Nm prop_dictionary_util
setter functions return
.Dv true
if creating the object and storing it in the dictionary is successful, or
.Dv false
otherwise.
.Sh SEE ALSO
.Xr prop_bool 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,232 @@
/* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*
* Note: There is no special magic going on here. We use the standard
* proplib(3) APIs to do all of this work. Any application could do
* exactly what we're doing here.
*/
#include <prop/proplib.h>
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
bool
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp)
{
prop_object_t o;
o = prop_dictionary_get(dict, key);
if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
return false;
*dp = o;
return true;
}
bool
prop_dictionary_get_bool(prop_dictionary_t dict,
const char *key,
bool *valp)
{
prop_bool_t b;
b = prop_dictionary_get(dict, key);
if (prop_object_type(b) != PROP_TYPE_BOOL)
return (false);
*valp = prop_bool_true(b);
return (true);
}
bool
prop_dictionary_set_bool(prop_dictionary_t dict,
const char *key,
bool val)
{
prop_bool_t b;
int rv;
b = prop_bool_create(val);
if (b == NULL)
return (false);
rv = prop_dictionary_set(dict, key, b);
prop_object_release(b);
return (rv);
}
#define TEMPLATE(size) \
bool \
prop_dictionary_get_int ## size (prop_dictionary_t dict, \
const char *key, \
int ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_dictionary_get(dict, key); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) && \
prop_number_unsigned_integer_value(num) > \
/*CONSTCOND*/((size) == 8 ? INT8_MAX : \
(size) == 16 ? INT16_MAX : \
(size) == 32 ? INT32_MAX : INT64_MAX)) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (int ## size ## _t) prop_number_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_dictionary_get_uint ## size (prop_dictionary_t dict, \
const char *key, \
uint ## size ## _t *valp) \
{ \
prop_number_t num; \
\
num = prop_dictionary_get(dict, key); \
if (prop_object_type(num) != PROP_TYPE_NUMBER) \
return (false); \
\
if (prop_number_unsigned(num) == false && \
prop_number_integer_value(num) < 0) { \
return (false); \
} \
\
if (prop_number_size(num) > (size)) \
return (false); \
\
*valp = (uint ## size ## _t) \
prop_number_unsigned_integer_value(num); \
\
return (true); \
} \
\
bool \
prop_dictionary_set_int ## size (prop_dictionary_t dict, \
const char *key, \
int ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_integer((int64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, num); \
prop_object_release(num); \
\
return (rv); \
} \
\
bool \
prop_dictionary_set_uint ## size (prop_dictionary_t dict, \
const char *key, \
uint ## size ## _t val) \
{ \
prop_number_t num; \
int rv; \
\
num = prop_number_create_unsigned_integer((uint64_t) val); \
if (num == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, num); \
prop_object_release(num); \
\
return (rv); \
}
TEMPLATE(8)
TEMPLATE(16)
TEMPLATE(32)
TEMPLATE(64)
#undef TEMPLATE
#define TEMPLATE(variant, qualifier) \
bool \
prop_dictionary_get_cstring ## variant (prop_dictionary_t dict, \
const char *key, \
qualifier char **cpp) \
{ \
prop_string_t str; \
\
str = prop_dictionary_get(dict, key); \
if (prop_object_type(str) != PROP_TYPE_STRING) \
return (false); \
\
*cpp = prop_string_cstring ## variant (str); \
\
return (*cpp == NULL ? false : true); \
} \
\
bool \
prop_dictionary_set_cstring ## variant (prop_dictionary_t dict, \
const char *key, \
const char *cp) \
{ \
prop_string_t str; \
int rv; \
\
str = prop_string_create_cstring ## variant (cp); \
if (str == NULL) \
return (false); \
rv = prop_dictionary_set(dict, key, str); \
prop_object_release(str); \
\
return (rv); \
}
TEMPLATE(,)
TEMPLATE(_nocopy,const)
#undef TEMPLATE
bool
prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_dictionary_set(dict, key, po);
prop_object_release(po);
return ret;
}

View file

@ -0,0 +1,181 @@
.\" $NetBSD: prop_ingest.3,v 1.6 2010/02/18 14:00:39 wiz 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.
.\"
.Dd January 21, 2008
.Dt PROP_INGEST 3
.Os
.Sh NAME
.Nm prop_ingest_context_alloc ,
.Nm prop_ingest_context_free ,
.Nm prop_ingest_context_error ,
.Nm prop_ingest_context_type ,
.Nm prop_ingest_context_key ,
.Nm prop_ingest_context_private ,
.Nm prop_dictionary_ingest
.Nd Ingest a dictionary into an arbitrary binary format
.Sh SYNOPSIS
.In prop/proplib.h
.Ft prop_ingest_context_t
.Fn prop_ingest_context_alloc "void *private"
.Ft void
.Fn prop_ingest_context_free "prop_ingest_context_t ctx"
.Ft prop_ingest_error_t
.Fn prop_ingest_context_error "prop_ingest_context_t ctx"
.Ft prop_type_t
.Fn prop_ingest_context_type "prop_ingest_context_t ctx"
.Ft const char *
.Fn prop_ingest_context_key "prop_ingest_context_t ctx"
.Ft void *
.Fn prop_ingest_context_private "prop_ingest_context_t ctx"
.Ft bool
.Fn prop_dictionary_ingest "prop_dictionary_t dict" \
"const prop_ingest_table_entry rules[]" \
"prop_ingest_context_t ctx"
.Pp
.Ft typedef bool
.Fn (*prop_ingest_handler_t) "prop_ingest_context_t" "prop_object_t"
.Sh DESCRIPTION
The
.Nm prop_dictionary_ingest
function provides a convenient way to convert a property list into
an arbitrary binary format or to extract values from dictionaries in a
way that is convenient to an application
.Pq for configuration files, for example .
.Pp
.Nm prop_dictionary_ingest
is driven by a table of rules provided by the application.
Each rule consists of three items:
.Bl -bullet
.It
A C string containing a key to be looked up in the dictionary.
.It
The expected property type of the object associated with the key
(or
.Dv PROP_TYPE_UNKNOWN
to specify that any type is allowed).
.It
A callback function of type
.Dv prop_ingest_handler_t
that will perform the translation for the application.
.El
.Pp
The table is constructed using a series of macros as follows:
.Bd -literal
static const prop_ingest_table_entry ingest_rules[] = {
PROP_INGEST("file-name", PROP_TYPE_STRING, ingest_filename),
PROP_INGEST("count", PROP_TYPE_NUMBER, ingest_count),
PROP_INGEST_OPTIONAL("required", PROP_TYPE_BOOL, ingest_required),
PROP_INGEST_OPTIONAL("extra", PROP_TYPE_UNKNOWN, ingest_extra),
PROP_INGEST_END
};
.Ed
.Pp
The
.Dv PROP_INGEST
macro specifies that the key is required to be present in the dictionary.
The
.Dv PROP_INGEST_OPTIONAL
macro specifies that the presence of the key in the dictionary is optional.
The
.Dv PROP_INGEST_END
macro marks the end of the rules table.
.Pp
In each case,
.Nm prop_dictionary_ingest
looks up the rule's key in the dictionary.
If an object is present in the dictionary at that key, its type is checked
against the type specified in the rule.
A type specification of
.Dv PROP_TYPE_UNKNOWN
allows the object to be of any type.
If the object does not exist and the rule is not marked as optional, then
an error is returned.
Otherwise, the handler specified in the rule is invoked with the ingest
context and the object
(or
.Dv NULL
if the key does not exist in the dictionary).
The handler should return
.Dv false
if the value of the object is invalid to indicate failure and
.Dv true
otherwise.
.Pp
The ingest context contains several pieces of information that are
useful during the ingest process.
The context also provides specific error information should the ingest
fail.
.Bl -tag -width "xxxxx"
.It Fn prop_ingest_context_alloc "void *private"
Allocate an ingest context.
The argument
.Fa private
may be used to pass application-specific context to the ingest handlers.
Note that an ingest context can be re-used to perform multiple ingests.
Returns
.Dv NULL
on failure.
.It Fn prop_ingest_context_free "prop_ingest_context_t ctx"
Free an ingest context.
.It Fn prop_ingest_context_error "prop_ingest_context_t ctx"
Returns the code indicating the error encountered during ingest.
The following error codes are defined:
.Pp
.Bl -tag -width "PROP_INGEST_ERROR_HANDLER_FAILED" -compact
.It Dv PROP_INGEST_ERROR_NO_ERROR
No error was encountered during ingest.
.It Dv PROP_INGEST_ERROR_NO_KEY
A non-optional key was not found in the dictionary.
.It Dv PROP_INGEST_ERROR_WRONG_TYPE
An object in the dictionary was not the same type specified in the rules.
.It Dv PROP_INGEST_ERROR_HANDLER_FAILED
An object's handler returned
.Dv false .
.El
.Pp
.It Fn prop_ingest_context_type "prop_ingest_context_t ctx"
Returns the type of the last object visited during an ingest.
When called by an ingest handler, it returns the type of the object
currently being processed.
.It Fn prop_ingest_context_key "prop_ingest_context_t ctx"
Returns the last dictionary key looked up during an ingest.
When called by an ingest handler, it returns the dictionary key corresponding
to the object currently being processed.
.It Fn prop_ingest_context_private "prop_ingest_context_t ctx"
Returns the private data set when the context was allocated with
.Fn prop_ingest_context_alloc .
.El
.Sh SEE ALSO
.Xr prop_dictionary 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View 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);
}

View file

@ -0,0 +1,612 @@
/* $NetBSD: prop_kern.c,v 1.17 2011/09/30 22:08:18 jym Exp $ */
/*-
* Copyright (c) 2006, 2009 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.
*/
#if defined(__NetBSD__)
#include <sys/types.h>
#include <sys/ioctl.h>
#include <prop/proplib.h>
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef RUMP_ACTION
#include <rump/rump_syscalls.h>
#define ioctl(a,b,c) rump_sys_ioctl(a,b,c)
#endif
static int
_prop_object_externalize_to_pref(prop_object_t obj, struct plistref *pref,
char **bufp)
{
char *buf;
switch (prop_object_type(obj)) {
case PROP_TYPE_DICTIONARY:
buf = prop_dictionary_externalize(obj);
break;
case PROP_TYPE_ARRAY:
buf = prop_array_externalize(obj);
break;
default:
return (ENOTSUP);
}
if (buf == NULL) {
/* Assume we ran out of memory. */
return (ENOMEM);
}
pref->pref_plist = buf;
pref->pref_len = strlen(buf) + 1;
*bufp = buf;
return (0);
}
bool
prop_array_externalize_to_pref(prop_array_t array, struct plistref *prefp)
{
char *buf;
int rv;
rv = _prop_object_externalize_to_pref(array, prefp, &buf);
if (rv != 0)
errno = rv; /* pass up error value in errno */
return (rv == 0);
}
/*
* prop_array_externalize_to_pref --
* Externalize an array into a plistref for sending to the kernel.
*/
int
prop_array_send_syscall(prop_array_t array, struct plistref *prefp)
{
if (prop_array_externalize_to_pref(array, prefp))
return 0;
else
return errno;
}
bool
prop_dictionary_externalize_to_pref(prop_dictionary_t dict,
struct plistref *prefp)
{
char *buf;
int rv;
rv = _prop_object_externalize_to_pref(dict, prefp, &buf);
if (rv != 0)
errno = rv; /* pass up error value in errno */
return (rv == 0);
}
/*
* prop_dictionary_externalize_to_pref --
* Externalize an dictionary into a plistref for sending to the kernel.
*/
int
prop_dictionary_send_syscall(prop_dictionary_t dict,
struct plistref *prefp)
{
if (prop_dictionary_externalize_to_pref(dict, prefp))
return 0;
else
return errno;
}
static int
_prop_object_send_ioctl(prop_object_t obj, int fd, unsigned long cmd)
{
struct plistref pref;
char *buf;
int error;
error = _prop_object_externalize_to_pref(obj, &pref, &buf);
if (error)
return (error);
if (ioctl(fd, cmd, &pref) == -1)
error = errno;
else
error = 0;
free(buf);
return (error);
}
/*
* prop_array_send_ioctl --
* Send an array to the kernel using the specified ioctl.
*/
int
prop_array_send_ioctl(prop_array_t array, int fd, unsigned long cmd)
{
int rv;
rv = _prop_object_send_ioctl(array, fd, cmd);
if (rv != 0) {
errno = rv; /* pass up error value in errno */
return rv;
} else
return 0;
}
/*
* prop_dictionary_send_ioctl --
* Send a dictionary to the kernel using the specified ioctl.
*/
int
prop_dictionary_send_ioctl(prop_dictionary_t dict, int fd, unsigned long cmd)
{
int rv;
rv = _prop_object_send_ioctl(dict, fd, cmd);
if (rv != 0) {
errno = rv; /* pass up error value in errno */
return rv;
} else
return 0;
}
static int
_prop_object_internalize_from_pref(const struct plistref *pref,
prop_type_t type, prop_object_t *objp)
{
prop_object_t obj = NULL;
char *buf;
int error = 0;
if (pref->pref_len == 0) {
/*
* This should never happen; we should always get the XML
* for an empty dictionary if it's really empty.
*/
error = EIO;
goto out;
} else {
buf = pref->pref_plist;
buf[pref->pref_len - 1] = '\0'; /* extra insurance */
switch (type) {
case PROP_TYPE_DICTIONARY:
obj = prop_dictionary_internalize(buf);
break;
case PROP_TYPE_ARRAY:
obj = prop_array_internalize(buf);
break;
default:
error = ENOTSUP;
}
(void) munmap(buf, pref->pref_len);
if (obj == NULL && error == 0)
error = EIO;
}
out:
if (error == 0)
*objp = obj;
return (error);
}
/*
* prop_array_internalize_from_pref --
* Internalize a pref into a prop_array_t object.
*/
bool
prop_array_internalize_from_pref(const struct plistref *prefp,
prop_array_t *arrayp)
{
int rv;
rv = _prop_object_internalize_from_pref(prefp, PROP_TYPE_ARRAY,
(prop_object_t *)arrayp);
if (rv != 0)
errno = rv; /* pass up error value in errno */
return (rv == 0);
}
/*
* prop_array_recv_syscall --
* Internalize an array received from the kernel as pref.
*/
int
prop_array_recv_syscall(const struct plistref *prefp,
prop_array_t *arrayp)
{
if (prop_array_internalize_from_pref(prefp, arrayp))
return 0;
else
return errno;
}
/*
* prop_dictionary_internalize_from_pref --
* Internalize a pref into a prop_dictionary_t object.
*/
bool
prop_dictionary_internalize_from_pref(const struct plistref *prefp,
prop_dictionary_t *dictp)
{
int rv;
rv = _prop_object_internalize_from_pref(prefp, PROP_TYPE_DICTIONARY,
(prop_object_t *)dictp);
if (rv != 0)
errno = rv; /* pass up error value in errno */
return (rv == 0);
}
/*
* prop_dictionary_recv_syscall --
* Internalize a dictionary received from the kernel as pref.
*/
int
prop_dictionary_recv_syscall(const struct plistref *prefp,
prop_dictionary_t *dictp)
{
if (prop_dictionary_internalize_from_pref(prefp, dictp))
return 0;
else
return errno;
}
/*
* prop_array_recv_ioctl --
* Receive an array from the kernel using the specified ioctl.
*/
int
prop_array_recv_ioctl(int fd, unsigned long cmd, prop_array_t *arrayp)
{
int rv;
struct plistref pref;
rv = ioctl(fd, cmd, &pref);
if (rv == -1)
return errno;
rv = _prop_object_internalize_from_pref(&pref, PROP_TYPE_ARRAY,
(prop_object_t *)arrayp);
if (rv != 0) {
errno = rv; /* pass up error value in errno */
return rv;
} else
return 0;
}
/*
* prop_dictionary_recv_ioctl --
* Receive a dictionary from the kernel using the specified ioctl.
*/
int
prop_dictionary_recv_ioctl(int fd, unsigned long cmd, prop_dictionary_t *dictp)
{
int rv;
struct plistref pref;
rv = ioctl(fd, cmd, &pref);
if (rv == -1)
return errno;
rv = _prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
(prop_object_t *)dictp);
if (rv != 0) {
errno = rv; /* pass up error value in errno */
return rv;
} else
return 0;
}
/*
* prop_dictionary_sendrecv_ioctl --
* Combination send/receive a dictionary to/from the kernel using
* the specified ioctl.
*/
int
prop_dictionary_sendrecv_ioctl(prop_dictionary_t dict, int fd,
unsigned long cmd, prop_dictionary_t *dictp)
{
struct plistref pref;
char *buf;
int error;
error = _prop_object_externalize_to_pref(dict, &pref, &buf);
if (error != 0) {
errno = error;
return error;
}
if (ioctl(fd, cmd, &pref) == -1)
error = errno;
else
error = 0;
free(buf);
if (error != 0)
return error;
error = _prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
(prop_object_t *)dictp);
if (error != 0) {
errno = error; /* pass up error value in errno */
return error;
} else
return 0;
}
#endif /* !_KERNEL && !_STANDALONE */
#if defined(_KERNEL)
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/pool.h>
#include <uvm/uvm.h>
#include "prop_object_impl.h"
/* Arbitrary limit ioctl input to 64KB */
unsigned int prop_object_copyin_limit = 65536;
/* initialize proplib for use in the kernel */
void
prop_kern_init(void)
{
__link_set_decl(prop_linkpools, struct prop_pool_init);
struct prop_pool_init * const *pi;
__link_set_foreach(pi, prop_linkpools)
pool_init((*pi)->pp, (*pi)->size, 0, 0, 0, (*pi)->wchan,
&pool_allocator_nointr, IPL_NONE);
}
static int
_prop_object_copyin(const struct plistref *pref, const prop_type_t type,
prop_object_t *objp)
{
prop_object_t obj = NULL;
char *buf;
int error;
/*
* Allocate an extra byte so we can guarantee NUL-termination.
*
* Allow malloc to fail in case pmap would be exhausted.
*/
buf = malloc(pref->pref_len + 1, M_TEMP, M_WAITOK | M_CANFAIL);
if (buf == NULL)
return (ENOMEM);
error = copyin(pref->pref_plist, buf, pref->pref_len);
if (error) {
free(buf, M_TEMP);
return (error);
}
buf[pref->pref_len] = '\0';
switch (type) {
case PROP_TYPE_ARRAY:
obj = prop_array_internalize(buf);
break;
case PROP_TYPE_DICTIONARY:
obj = prop_dictionary_internalize(buf);
break;
default:
error = ENOTSUP;
}
free(buf, M_TEMP);
if (obj == NULL) {
if (error == 0)
error = EIO;
} else {
*objp = obj;
}
return (error);
}
static int
_prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
const u_long cmd, prop_object_t *objp)
{
if ((cmd & IOC_IN) == 0)
return (EFAULT);
return _prop_object_copyin(pref, type, objp);
}
/*
* prop_array_copyin --
* Copy in an array passed as a syscall arg.
*/
int
prop_array_copyin(const struct plistref *pref, prop_array_t *arrayp)
{
return (_prop_object_copyin(pref, PROP_TYPE_ARRAY,
(prop_object_t *)arrayp));
}
/*
* prop_dictionary_copyin --
* Copy in a dictionary passed as a syscall arg.
*/
int
prop_dictionary_copyin(const struct plistref *pref, prop_dictionary_t *dictp)
{
return (_prop_object_copyin(pref, PROP_TYPE_DICTIONARY,
(prop_object_t *)dictp));
}
/*
* prop_array_copyin_ioctl --
* Copy in an array send with an ioctl.
*/
int
prop_array_copyin_ioctl(const struct plistref *pref, const u_long cmd,
prop_array_t *arrayp)
{
return (_prop_object_copyin_ioctl(pref, PROP_TYPE_ARRAY,
cmd, (prop_object_t *)arrayp));
}
/*
* prop_dictionary_copyin_ioctl --
* Copy in a dictionary sent with an ioctl.
*/
int
prop_dictionary_copyin_ioctl(const struct plistref *pref, const u_long cmd,
prop_dictionary_t *dictp)
{
return (_prop_object_copyin_ioctl(pref, PROP_TYPE_DICTIONARY,
cmd, (prop_object_t *)dictp));
}
static int
_prop_object_copyout(struct plistref *pref, prop_object_t obj)
{
struct lwp *l = curlwp; /* XXX */
struct proc *p = l->l_proc;
char *buf;
size_t len, rlen;
int error = 0;
vaddr_t uaddr;
switch (prop_object_type(obj)) {
case PROP_TYPE_ARRAY:
buf = prop_array_externalize(obj);
break;
case PROP_TYPE_DICTIONARY:
buf = prop_dictionary_externalize(obj);
break;
default:
return (ENOTSUP);
}
if (buf == NULL)
return (ENOMEM);
len = strlen(buf) + 1;
rlen = round_page(len);
/*
* See sys_mmap() in sys/uvm/uvm_mmap.c.
* Let's act as if we were calling mmap(0, ...)
*/
uaddr = p->p_emul->e_vm_default_addr(p,
(vaddr_t)p->p_vmspace->vm_daddr, rlen);
error = uvm_mmap(&p->p_vmspace->vm_map,
&uaddr, rlen,
VM_PROT_READ|VM_PROT_WRITE,
VM_PROT_READ|VM_PROT_WRITE,
MAP_PRIVATE|MAP_ANON,
NULL, 0,
p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
if (error == 0) {
error = copyout(buf, (char *)uaddr, len);
if (error == 0) {
pref->pref_plist = (char *)uaddr;
pref->pref_len = len;
}
}
free(buf, M_TEMP);
return (error);
}
/*
* prop_array_copyout --
* Copy out an array to a syscall arg.
*/
int
prop_array_copyout(struct plistref *pref, prop_array_t array)
{
return (_prop_object_copyout(pref, array));
}
/*
* prop_dictionary_copyout --
* Copy out a dictionary to a syscall arg.
*/
int
prop_dictionary_copyout(struct plistref *pref, prop_dictionary_t dict)
{
return (_prop_object_copyout(pref, dict));
}
static int
_prop_object_copyout_ioctl(struct plistref *pref, const u_long cmd,
prop_object_t obj)
{
if ((cmd & IOC_OUT) == 0)
return (EFAULT);
return _prop_object_copyout(pref, obj);
}
/*
* prop_array_copyout_ioctl --
* Copy out an array being received with an ioctl.
*/
int
prop_array_copyout_ioctl(struct plistref *pref, const u_long cmd,
prop_array_t array)
{
return (_prop_object_copyout_ioctl(pref, cmd, array));
}
/*
* prop_dictionary_copyout_ioctl --
* Copy out a dictionary being received with an ioctl.
*/
int
prop_dictionary_copyout_ioctl(struct plistref *pref, const u_long cmd,
prop_dictionary_t dict)
{
return (
_prop_object_copyout_ioctl(pref, cmd, dict));
}
#endif /* _KERNEL */
#endif /* __NetBSD__ */

View file

@ -0,0 +1,210 @@
.\" $NetBSD: prop_number.3,v 1.10 2011/01/20 10:44:42 wiz 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.
.\"
.Dd January 21, 2008
.Dt PROP_NUMBER 3
.Os
.Sh NAME
.Nm prop_number ,
.Nm prop_number_create_integer ,
.Nm prop_number_create_unsigned_integer ,
.Nm prop_number_copy ,
.Nm prop_number_size ,
.Nm prop_number_unsigned ,
.Nm prop_number_integer_value ,
.Nm prop_number_unsigned_integer_value ,
.Nm prop_number_equals ,
.Nm prop_number_equals_integer ,
.Nm prop_number_equals_unsigned_integer
.Nd numeric value property object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_number_t
.Fn prop_number_create_integer "int64_t val"
.Ft prop_number_t
.Fn prop_number_create_unsigned_integer "uint64_t val"
.Ft prop_number_t
.Fn prop_number_copy "prop_number_t number"
.\"
.Ft int
.Fn prop_number_size "prop_number_t number"
.Ft bool
.Fn prop_number_unsigned "prop_number_t number"
.Ft int64_t
.Fn prop_number_integer_value "prop_number_t number"
.Ft uint64_t
.Fn prop_number_unsigned_integer_value "prop_number_t number"
.\"
.Ft bool
.Fn prop_number_equals "prop_number_t num1" "prop_number_t num2"
.Ft bool
.Fn prop_number_equals_integer "prop_number_t number" "int64_t val"
.Ft bool
.Fn prop_number_equals_unsigned_integer "prop_number_t number" "uint64_t val"
.Sh DESCRIPTION
The
.Nm prop_number
family of functions operate on a numeric value property object type.
Values are either signed or unsigned, and promoted to a 64-bit type
.Pq int64_t or uint64_t , respectively .
.Pp
It is possible to compare number objects that differ in sign.
Such comparisons first test to see if each object is within the valid
number range of the other:
.Bl -bullet
.It
Signed numbers that are greater than or equal to 0 can be compared to
unsigned numbers.
.It
Unsigned numbers that are less than or equal to the largest signed 64-bit
value
.Pq Dv INT64_MAX
can be compared to signed numbers.
.El
.Pp
Number objects have a different externalized representation depending
on their sign:
.Bl -bullet
.It
Signed numbers are externalized in base-10
.Pq decimal .
.It
Unsigned numbers are externalized in base-16
.Pq hexadecimal .
.El
.Pp
When numbers are internalized, the sign of the resulting number object
.Pq and thus its valid range
is determined by a set of rules evaluated in the following order:
.Bl -bullet
.It
If the first character of the number is a
.Sq -
then the number is signed.
.It
If the first two characters of the number are
.Sq 0x
then the number is unsigned.
.It
If the number value fits into the range of a signed number then the
number is signed.
.It
In all other cases, the number is unsigned.
.El
.Bl -tag -width "xxxxx"
.It Fn prop_number_create_integer "int64_t val"
Create a numeric value object with the signed value
.Fa val .
Returns
.Dv NULL
on failure.
.It Fn prop_number_create_unsigned_integer "uint64_t val"
Create a numeric value object with the unsigned value
.Fa val .
Returns
.Dv NULL
on failure.
.It Fn prop_number_copy "prop_number_t number"
Copy a numeric value object.
If the supplied object isn't a numeric value,
.Dv NULL
is returned.
.It Fn prop_number_size "prop_number_t number"
Returns 8, 16, 32, or 64, representing the number of bits required to
hold the value of the object.
If the supplied object isn't a numeric value,
.Dv NULL
is returned.
.It Fn prop_number_unsigned "prop_number_t number"
Returns
.Dv true
if the numeric value object has an unsigned value.
.It Fn prop_number_integer_value "prop_number_t number"
Returns the signed integer value of the numeric value object.
If the supplied object isn't a numeric value, zero is returned.
Thus,
it is not possible to distinguish between
.Dq not a prop_number_t
and
.Dq prop_number_t has a value of 0 .
.It Fn prop_number_unsigned_integer_value "prop_number_t number"
Returns the unsigned integer value of the numeric value object.
If the supplied object isn't a numeric value, zero is returned.
Thus,
it is not possible to distinguish between
.Dq not a prop_number_t
and
.Dq prop_number_t has a value of 0 .
.It Fn prop_number_equals "prop_number_t num1" "prop_number_t num2"
Returns
.Dv true
if the two numeric value objects are equivalent.
If at least one of the supplied objects isn't a numeric value,
.Dv false
is returned.
.It Fn prop_number_equals_integer "prop_number_t number" "int64_t val"
Returns
.Dv true
if the object's value is equivalent to the signed value
.Fa val .
If the supplied object isn't a numerical value or if
.Fa val
exceeds
.Dv INT64_MAX ,
.Dv false
is returned.
.It Fn prop_number_equals_unsigned_integer "prop_number_t number" \
"uint64_t val"
Returns
.Dv true
if the object's value is equivalent to the unsigned value
.Fa val .
If the supplied object isn't a numerical value or if
.Fa val
exceeds
.Dv INT64_MAX ,
.Dv false
is returned.
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_object 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,592 @@
/* $NetBSD: prop_number.c,v 1.23 2010/09/24 22:51:52 rmind 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"
#if defined(_KERNEL)
#include <sys/systm.h>
#elif defined(_STANDALONE)
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#else
#include <errno.h>
#include <stdlib.h>
#endif
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;
};
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
static _prop_object_free_rv_t
_prop_number_free(prop_stack_t, prop_object_t *);
static bool _prop_number_externalize(
struct _prop_object_externalize_context *,
void *);
static _prop_object_equals_rv_t
_prop_number_equals(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
static void _prop_number_lock(void);
static void _prop_number_unlock(void);
static const struct _prop_object_type _prop_object_type_number = {
.pot_type = PROP_TYPE_NUMBER,
.pot_free = _prop_number_free,
.pot_extern = _prop_number_externalize,
.pot_equals = _prop_number_equals,
.pot_lock = _prop_number_lock,
.pot_unlock = _prop_number_unlock,
};
#define prop_object_is_number(x) \
((x) != NULL && (x)->pn_obj.po_type == &_prop_object_type_number)
/*
* Number objects are immutable, and we are likely to have many number
* objects that have the same value. So, to save memory, we unique'ify
* numbers so we only have one copy of each.
*/
static int
_prop_number_compare_values(const struct _prop_number_value *pnv1,
const struct _prop_number_value *pnv2)
{
/* Signed numbers are sorted before unsigned numbers. */
if (pnv1->pnv_is_unsigned) {
if (! pnv2->pnv_is_unsigned)
return (1);
if (pnv1->pnv_unsigned < pnv2->pnv_unsigned)
return (-1);
if (pnv1->pnv_unsigned > pnv2->pnv_unsigned)
return (1);
return (0);
}
if (pnv2->pnv_is_unsigned)
return (-1);
if (pnv1->pnv_signed < pnv2->pnv_signed)
return (-1);
if (pnv1->pnv_signed > pnv2->pnv_signed)
return (1);
return (0);
}
static int
/*ARGSUSED*/
_prop_number_rb_compare_nodes(void *ctx __unused,
const void *n1, const void *n2)
{
const struct _prop_number *pn1 = n1;
const struct _prop_number *pn2 = n2;
return _prop_number_compare_values(&pn1->pn_value, &pn2->pn_value);
}
static int
/*ARGSUSED*/
_prop_number_rb_compare_key(void *ctx __unused, const void *n, const void *v)
{
const struct _prop_number *pn = n;
const struct _prop_number_value *pnv = v;
return _prop_number_compare_values(&pn->pn_value, pnv);
}
static const rb_tree_ops_t _prop_number_rb_tree_ops = {
.rbto_compare_nodes = _prop_number_rb_compare_nodes,
.rbto_compare_key = _prop_number_rb_compare_key,
.rbto_node_offset = offsetof(struct _prop_number, pn_link),
.rbto_context = NULL
};
static struct rb_tree _prop_number_tree;
_PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex)
/* ARGSUSED */
static _prop_object_free_rv_t
_prop_number_free(prop_stack_t stack, prop_object_t *obj)
{
prop_number_t pn = *obj;
_prop_rb_tree_remove_node(&_prop_number_tree, pn);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (_PROP_OBJECT_FREE_DONE);
}
_PROP_ONCE_DECL(_prop_number_init_once)
static int
_prop_number_init(void)
{
_PROP_MUTEX_INIT(_prop_number_tree_mutex);
_prop_rb_tree_init(&_prop_number_tree, &_prop_number_rb_tree_ops);
return 0;
}
static void
_prop_number_lock(void)
{
/* XXX: init necessary? */
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
}
static void
_prop_number_unlock(void)
{
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
}
static bool
_prop_number_externalize(struct _prop_object_externalize_context *ctx,
void *v)
{
prop_number_t pn = v;
char tmpstr[32];
/*
* For unsigned numbers, we output in hex. For signed numbers,
* we output in decimal.
*/
if (pn->pn_value.pnv_is_unsigned)
sprintf(tmpstr, "0x%" PRIx64, 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, rpn;
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
/*
* Check to see if this already exists in the tree. If it does,
* we just retain it and return it.
*/
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (opn);
}
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
/*
* Not in the tree. Create it now.
*/
pn = _PROP_POOL_GET(_prop_number_pool);
if (pn == NULL)
return (NULL);
_prop_object_init(&pn->pn_obj, &_prop_object_type_number);
pn->pn_value = *pnv;
/*
* We dropped the mutex when we allocated the new object, so
* we have to check again if it is in the tree.
*/
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (opn);
}
rpn = _prop_rb_tree_insert_node(&_prop_number_tree, pn);
_PROP_ASSERT(rpn == pn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (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));
#ifndef _KERNEL
errno = 0;
#endif
pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE)
return (false);
#endif
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));
#ifndef _KERNEL
errno = 0;
#endif
pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) &&
errno == ERANGE)
return (false);
#endif
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);
}

View file

@ -0,0 +1,141 @@
.\" $NetBSD: prop_object.3,v 1.8 2011/01/20 10:44:42 wiz 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.
.\"
.Dd August 21, 2006
.Dt PROP_OBJECT 3
.Os
.Sh NAME
.Nm prop_object ,
.Nm prop_object_retain ,
.Nm prop_object_release ,
.Nm prop_object_type ,
.Nm prop_object_equals ,
.Nm prop_object_iterator_next ,
.Nm prop_object_iterator_reset ,
.Nm prop_object_iterator_release
.Nd general property container object functions
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft void
.Fn prop_object_retain "prop_object_t obj"
.Ft void
.Fn prop_object_release "prop_object_t obj"
.\"
.Ft prop_type_t
.Fn prop_object_type "prop_object_t obj"
.Ft bool
.Fn prop_object_equals "prop_object_t obj1" "prop_object_t obj2"
.\"
.Ft prop_object_t
.Fn prop_object_iterator_next "prop_object_iterator_t iter"
.Ft void
.Fn prop_object_iterator_reset "prop_object_iterator_t iter"
.Ft void
.Fn prop_object_iterator_release "prop_object_iterator_t iter"
.Sh DESCRIPTION
The
.Nm prop_object
family of functions operate on all property container object types.
.Bl -tag -width ""
.It Fn prop_object_retain "prop_object_t obj"
Increment the reference count on an object.
.It Fn prop_object_release "prop_object_t obj"
Decrement the reference count on an object.
If the last reference is dropped, the object is freed.
.It Fn prop_object_type "prop_object_t obj"
Determine the type of the object.
Objects are one of the following types:
.Pp
.Bl -tag -width "PROP_TYPE_DICT_KEYSYM" -compact
.It Dv PROP_TYPE_BOOL
Boolean value
.Pq prop_bool_t
.It Dv PROP_TYPE_NUMBER
Number
.Pq prop_number_t
.It Dv PROP_TYPE_STRING
String
.Pq prop_string_t
.It Dv PROP_TYPE_DATA
Opaque data
.Pq prop_data_t
.It Dv PROP_TYPE_ARRAY
Array
.Pq prop_array_t
.It Dv PROP_TYPE_DICTIONARY
Dictionary
.Pq prop_dictionary_t
.It Dv PROP_TYPE_DICT_KEYSYM
Dictionary key symbol
.Pq prop_dictionary_keysym_t
.El
.Pp
If
.Fa obj
is
.Dv NULL ,
then
.Dv PROP_TYPE_UNKNOWN
is returned.
.It Fn prop_object_equals "prop_object_t obj1" "prop_object_t obj2"
Returns
.Dv true
if the two objects are of the same type and are equivalent.
.It Fn prop_object_iterator_next "prop_object_iterator_t iter"
Return the next object in the collection
.Pq array or dictionary
being iterated by the iterator
.Fa iter .
If there are no more objects in the collection,
.Dv NULL
is returned.
.It Fn prop_object_iterator_reset "prop_object_iterator_t iter"
Reset the iterator to the first object in the collection being iterated
by the iterator
.Fa iter .
.It Fn prop_object_iterator_release "prop_object_iterator_t iter"
Release the iterator
.Fa iter .
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr prop_string 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,436 @@
/* $NetBSD: prop_object_impl.h,v 1.30 2009/09/13 18:45:10 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PROPLIB_PROP_OBJECT_IMPL_H_
#define _PROPLIB_PROP_OBJECT_IMPL_H_
#if defined(_KERNEL) || defined(_STANDALONE)
#include <lib/libkern/libkern.h>
#else
#include <inttypes.h>
#endif
#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 *);
#if !defined(_KERNEL) && !defined(_STANDALONE)
bool _prop_object_externalize_write_file(const char *,
const char *, size_t);
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 *);
#endif /* !_KERNEL && !_STANDALONE */
typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
typedef bool (*prop_object_internalizer_continue_t)(prop_stack_t,
prop_object_t *,
struct _prop_object_internalize_context *,
void *, prop_object_t);
/* These are here because they're required by shared code. */
bool _prop_array_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_bool_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_data_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_dictionary_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_number_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
bool _prop_string_internalize(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
struct _prop_object_type {
/* type indicator */
uint32_t pot_type;
/* func to free object */
_prop_object_free_rv_t
(*pot_free)(prop_stack_t, prop_object_t *);
/*
* func to free the child returned by pot_free with stack == NULL.
*
* Must be implemented if pot_free can return anything other than
* _PROP_OBJECT_FREE_DONE.
*/
void (*pot_emergency_free)(prop_object_t);
/* func to externalize object */
bool (*pot_extern)(struct _prop_object_externalize_context *,
void *);
/* func to test quality */
_prop_object_equals_rv_t
(*pot_equals)(prop_object_t, prop_object_t,
void **, void **,
prop_object_t *, prop_object_t *);
/*
* func to finish equality iteration.
*
* Must be implemented if pot_equals can return
* _PROP_OBJECT_EQUALS_RECURSE
*/
void (*pot_equals_finish)(prop_object_t, prop_object_t);
void (*pot_lock)(void);
void (*pot_unlock)(void);
};
struct _prop_object {
const struct _prop_object_type *po_type;/* type descriptor */
uint32_t po_refcnt; /* reference count */
};
void _prop_object_init(struct _prop_object *,
const struct _prop_object_type *);
void _prop_object_fini(struct _prop_object *);
struct _prop_object_iterator {
prop_object_t (*pi_next_object)(void *);
void (*pi_reset)(void *);
prop_object_t pi_obj;
uint32_t pi_version;
};
#define _PROP_NOTHREAD_ONCE_DECL(x) static bool x = false;
#define _PROP_NOTHREAD_ONCE_RUN(x,f) \
do { \
if ((x) == false) { \
f(); \
x = true; \
} \
} while (/*CONSTCOND*/0)
#if defined(_KERNEL)
/*
* proplib in the kernel...
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/systm.h>
#include <sys/rwlock.h>
#include <sys/once.h>
#define _PROP_ASSERT(x) KASSERT(x)
#define _PROP_MALLOC(s, t) malloc((s), (t), M_WAITOK)
#define _PROP_CALLOC(s, t) malloc((s), (t), M_WAITOK | M_ZERO)
#define _PROP_REALLOC(v, s, t) realloc((v), (s), (t), M_WAITOK)
#define _PROP_FREE(v, t) free((v), (t))
#define _PROP_POOL_GET(p) pool_get(&(p), PR_WAITOK)
#define _PROP_POOL_PUT(p, v) pool_put(&(p), (v))
struct prop_pool_init {
struct pool *pp;
size_t size;
const char *wchan;
};
#define _PROP_POOL_INIT(pp, size, wchan) \
struct pool pp; \
static const struct prop_pool_init _link_ ## pp[1] = { \
{ &pp, size, wchan } \
}; \
__link_set_add_rodata(prop_linkpools, _link_ ## pp);
#define _PROP_MALLOC_DEFINE(t, s, l) \
MALLOC_DEFINE(t, s, l);
#define _PROP_MUTEX_DECL_STATIC(x) static kmutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x),MUTEX_DEFAULT,IPL_NONE)
#define _PROP_MUTEX_LOCK(x) mutex_enter(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_exit(&(x))
#define _PROP_RWLOCK_DECL(x) krwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rw_init(&(x))
#define _PROP_RWLOCK_RDLOCK(x) rw_enter(&(x), RW_READER)
#define _PROP_RWLOCK_WRLOCK(x) rw_enter(&(x), RW_WRITER)
#define _PROP_RWLOCK_UNLOCK(x) rw_exit(&(x))
#define _PROP_RWLOCK_DESTROY(x) rw_destroy(&(x))
#define _PROP_ONCE_DECL(x) static ONCE_DECL(x);
#define _PROP_ONCE_RUN(x,f) RUN_ONCE(&(x), f)
#elif defined(_STANDALONE)
/*
* proplib in a standalone environment...
*/
#include <lib/libsa/stand.h>
void * _prop_standalone_calloc(size_t);
void * _prop_standalone_realloc(void *, size_t);
#define _PROP_ASSERT(x) /* nothing */
#define _PROP_MALLOC(s, t) alloc((s))
#define _PROP_CALLOC(s, t) _prop_standalone_calloc((s))
#define _PROP_REALLOC(v, s, t) _prop_standalone_realloc((v), (s))
#define _PROP_FREE(v, t) dealloc((v), 0) /* XXX */
#define _PROP_POOL_GET(p) alloc((p))
#define _PROP_POOL_PUT(p, v) dealloc((v), (p))
#define _PROP_POOL_INIT(p, s, d) static const size_t p = s;
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/*
* proplib in user space...
*/
#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 */
#if (defined(__NetBSD__) && defined(_LIBPROP))
/*
* Use the same mechanism as libc; we get pthread mutexes for threaded
* programs and do-nothing stubs for non-threaded programs.
*/
#include "reentrant.h"
#define _PROP_MUTEX_DECL_STATIC(x) static mutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_unlock(&(x))
#define _PROP_RWLOCK_DECL(x) rwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rwlock_init(&(x), NULL)
#define _PROP_RWLOCK_RDLOCK(x) rwlock_rdlock(&(x))
#define _PROP_RWLOCK_WRLOCK(x) rwlock_wrlock(&(x))
#define _PROP_RWLOCK_UNLOCK(x) rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) thr_once(&(x), (void(*)(void))f);
#elif defined(HAVE_NBTOOL_CONFIG_H) || defined(__minix)
/*
* None of NetBSD's build tools are multi-threaded.
*/
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/*
* Use pthread mutexes everywhere else.
*/
#include <pthread.h>
#define _PROP_MUTEX_DECL_STATIC(x) static pthread_mutex_t x;
#define _PROP_MUTEX_INIT(x) pthread_mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
#define _PROP_RWLOCK_DECL(x) pthread_rwlock_t x ;
#define _PROP_RWLOCK_INIT(x) pthread_rwlock_init(&(x), NULL)
#define _PROP_RWLOCK_RDLOCK(x) pthread_rwlock_rdlock(&(x))
#define _PROP_RWLOCK_WRLOCK(x) pthread_rwlock_wrlock(&(x))
#define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) pthread_rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f)
#endif
#endif /* _KERNEL */
/*
* Language features.
*/
#if defined(__NetBSD__)
#include <sys/cdefs.h>
#define _PROP_ARG_UNUSED __unused
#else
#define _PROP_ARG_UNUSED /* delete */
#endif /* __NetBSD__ */
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */

1057
common/lib/libprop/prop_rb.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,154 @@
/* $NetBSD: prop_rb_impl.h,v 1.8 2010/09/25 01:42:38 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PROP_RB_IMPL_H_
#define _PROP_RB_IMPL_H_
#if defined(__NetBSD__) || defined(__minix)
#include <sys/rbtree.h>
/*
* Define local names for common rb_tree functions.
*/
#define _prop_rb_tree_init rb_tree_init
#define _prop_rb_tree_insert_node rb_tree_insert_node
#define _prop_rb_tree_find rb_tree_find_node
#define _prop_rb_tree_remove_node rb_tree_remove_node
#define _prop_rb_tree_iterate rb_tree_iterate
#else /* __NetBSD__ */
#include <sys/types.h>
#include <sys/queue.h>
#include <machine/endian.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 /* __NetBSD__ */
#endif /* _PROP_RB_IMPL_H_*/

View file

@ -0,0 +1,151 @@
.\" $NetBSD: prop_send_ioctl.3,v 1.8 2011/09/27 11:12:49 jym 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.
.\"
.Dd January 21, 2008
.Dt PROP_SEND_IOCTL 3
.Os
.Sh NAME
.Nm prop_array_send_ioctl ,
.Nm prop_array_recv_ioctl ,
.Nm prop_dictionary_send_ioctl ,
.Nm prop_dictionary_recv_ioctl ,
.Nm prop_dictionary_sendrecv_ioctl
.Nd Send and receive propertly lists to and from the kernel using ioctl
.Sh SYNOPSIS
.In prop/proplib.h
.Ft int
.Fn prop_array_send_ioctl "prop_array_t array" "int fd" "unsigned long cmd"
.Ft int
.Fn prop_array_recv_ioctl "int fd" "unsigned long cmd" "prop_array_t *arrayp"
.Ft int
.Fn prop_dictionary_send_ioctl "prop_dictionary_t dict" "int fd" \
"unsigned long cmd"
.Ft int
.Fn prop_dictionary_recv_ioctl "int fd" "unsigned long cmd" \
"prop_dictionary_t *dictp"
.Ft int
.Fn prop_dictionary_sendrecv_ioctl "prop_dictionary_t dict" "int fd" \
"unsigned long cmd" "prop_dictionary_t *dictp"
.Sh DESCRIPTION
The
.Nm prop_array_send_ioctl ,
.Nm prop_array_recv_ioctl ,
.Nm prop_dictionary_send_ioctl ,
.Nm prop_dictionary_recv_ioctl ,
and
.Nm prop_dictionary_sendrecv_ioctl
functions implement the user space side of a protocol for sending property
lists to and from the kernel using
.Xr ioctl 2 .
.Sh RETURN VALUES
If successful, functions return zero.
Otherwise, an error number is returned to indicate the error.
.Sh EXAMPLES
The following
.Pq simplified
example demonstrates using
.Fn prop_dictionary_send_ioctl
and
.Fn prop_dictionary_recv_ioctl
in an application:
.Bd -literal
void
foo_setprops(prop_dictionary_t dict)
{
int fd;
fd = open("/dev/foo", O_RDWR, 0640);
if (fd == -1)
return;
(void) prop_dictionary_send_ioctl(dict, fd, FOOSETPROPS);
(void) close(fd);
}
prop_dictionary_t
foo_getprops(void)
{
prop_dictionary_t dict;
int fd;
fd = open("/dev/foo", O_RDONLY, 0640);
if (fd == -1)
return (NULL);
if (prop_dictionary_recv_ioctl(fd, FOOGETPROPS, \*[Am]dict) != 0)
return (NULL);
(void) close(fd);
return (dict);
}
.Ed
.Pp
The
.Nm prop_dictionary_sendrecv_ioctl
function combines the send and receive functionality, allowing for
ioctls that require two-way communication
.Pq for example to specify arguments for the ioctl operation .
.Sh ERRORS
.Fn prop_array_send_ioctl
and
.Fn prop_dictionary_send_ioctl
will fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Cannot allocate memory
.It Bq Er ENOTSUP
Not supported
.El
.Pp
.Fn prop_array_recv_ioctl
and
.Fn prop_dictionary_recv_ioctl
will fail if:
.Bl -tag -width Er
.It Bq Er EIO
Input/output error
.It Bq Er ENOTSUP
Not supported
.El
.Pp
In addition to these,
.Xr ioctl 2
errors may be returned.
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_dictionary 3 ,
.Xr proplib 3 ,
.Xr prop_copyin_ioctl 9
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,128 @@
.\" $NetBSD: prop_send_syscall.3,v 1.5 2011/09/30 22:08:18 jym 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.
.\"
.Dd January 17, 2011
.Dt PROP_SEND_SYCALL 3
.Os
.Sh NAME
.Nm prop_array_send_syscall ,
.Nm prop_array_recv_syscall ,
.Nm prop_dictionary_send_syscall ,
.Nm prop_dictionary_recv_syscall
.Nd send and receive property lists to and from the kernel using syscalls
.Sh SYNOPSIS
.In prop/proplib.h
.Ft int
.Fn prop_array_send_syscall "prop_array_t array" "struct plistref *prefp"
.Ft int
.Fn prop_array_recv_syscall "const struct plistref *prefp" \
"prop_array_t *arrayp"
.Ft int
.Fn prop_dictionary_send_syscall "prop_dictionary_t dict" \
"struct plistref *prefp"
.Ft int
.Fn prop_dictionary_recv_syscall "const struct plistref *prefp" \
"prop_dictionary_t *dictp"
.Sh DESCRIPTION
The
.Nm prop_array_send_syscall ,
.Nm prop_array_recv_syscall ,
.Nm prop_dictionary_send_syscall ,
and
.Nm prop_dictionary_recv_syscall
functions implement the user space side of a protocol for sending property
lists to and from the kernel using
.Xr syscall 2 .
.Sh RETURN VALUES
If successful, functions return zero.
Otherwise, an error number is returned to indicate the error.
.Sh EXAMPLES
The following
.Pq simplified
example demonstrates using
.Fn prop_dictionary_send_syscall
and
.Fn prop_dictionary_recv_syscall
in an application:
.Bd -literal
void
foo_setprops(prop_dictionary_t dict)
{
struct pref pref;
(void) prop_dictionary_send_syscall(dict, \*[Am]pref);
(void) my_syscall_set(\*[Am]pref);
}
prop_dictionary_t
foo_getprops(void)
{
prop_dictionary_t dict;
struct pref pref;
(void) my_syscall_get(\*[Am]pref);
if (prop_dictionary_recv_syscall(\*[Am]pref, \*[Am]dict) != 0)
return (NULL);
return (dict);
}
.Ed
.Sh ERRORS
.Fn prop_array_send_syscall
and
.Fn prop_dictionary_send_syscall
will fail if:
.Bl -tag -width Er
.It Bq Er ENOMEM
Cannot allocate memory
.It Bq Er ENOTSUP
Not supported
.El
.Pp
.Fn prop_array_recv_syscall
and
.Fn prop_dictionary_recv_syscall
will fail if:
.Bl -tag -width Er
.It Bq Er EIO
Input/output error
.It Bq Er ENOTSUP
Not supported
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_dictionary 3 ,
.Xr proplib 3 ,
.Xr prop_copyin_ioctl 9
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View file

@ -0,0 +1,118 @@
/* $NetBSD: prop_stack.c,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "prop_stack.h"
#include "prop_object_impl.h"
void
_prop_stack_init(prop_stack_t stack)
{
stack->used_intern_elems = 0;
SLIST_INIT(&stack->extern_elems);
}
bool
_prop_stack_push(prop_stack_t stack, prop_object_t obj, void *data1,
void *data2, void *data3)
{
struct _prop_stack_extern_elem *eelem;
struct _prop_stack_intern_elem *ielem;
if (stack->used_intern_elems == PROP_STACK_INTERN_ELEMS) {
eelem = _PROP_MALLOC(sizeof(*eelem), M_TEMP);
if (eelem == NULL)
return false;
eelem->object = obj;
eelem->object_data[0] = data1;
eelem->object_data[1] = data2;
eelem->object_data[2] = data3;
SLIST_INSERT_HEAD(&stack->extern_elems, eelem, stack_link);
return true;
}
_PROP_ASSERT(stack->used_intern_elems < PROP_STACK_INTERN_ELEMS);
_PROP_ASSERT(SLIST_EMPTY(&stack->extern_elems));
ielem = &stack->intern_elems[stack->used_intern_elems];
ielem->object = obj;
ielem->object_data[0] = data1;
ielem->object_data[1] = data2;
ielem->object_data[2] = data3;
++stack->used_intern_elems;
return true;
}
bool
_prop_stack_pop(prop_stack_t stack, prop_object_t *obj, void **data1,
void **data2, void **data3)
{
struct _prop_stack_extern_elem *eelem;
struct _prop_stack_intern_elem *ielem;
if (stack->used_intern_elems == 0)
return false;
if ((eelem = SLIST_FIRST(&stack->extern_elems)) != NULL) {
_PROP_ASSERT(stack->used_intern_elems == PROP_STACK_INTERN_ELEMS);
SLIST_REMOVE_HEAD(&stack->extern_elems, stack_link);
if (obj)
*obj = eelem->object;
if (data1)
*data1 = eelem->object_data[0];
if (data2)
*data2 = eelem->object_data[1];
if (data3)
*data3 = eelem->object_data[2];
_PROP_FREE(eelem, M_TEMP);
return true;
}
--stack->used_intern_elems;
ielem = &stack->intern_elems[stack->used_intern_elems];
if (obj)
*obj = ielem->object;
if (data1)
*data1 = ielem->object_data[0];
if (data2)
*data2 = ielem->object_data[1];
if (data3)
*data3 = ielem->object_data[2];
return true;
}

View file

@ -0,0 +1,64 @@
/* $NetBSD: prop_stack.h,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _PROP_STACK_H
#define _PROP_STACK_H
#include <sys/queue.h>
#include <prop/prop_object.h>
struct _prop_stack_intern_elem {
prop_object_t object;
void *object_data[3];
};
struct _prop_stack_extern_elem {
SLIST_ENTRY(_prop_stack_extern_elem) stack_link;
prop_object_t object;
void *object_data[3];
};
#define PROP_STACK_INTERN_ELEMS 16
struct _prop_stack {
struct _prop_stack_intern_elem intern_elems[PROP_STACK_INTERN_ELEMS];
size_t used_intern_elems;
SLIST_HEAD(, _prop_stack_extern_elem) extern_elems;
};
typedef struct _prop_stack *prop_stack_t;
void _prop_stack_init(prop_stack_t);
bool _prop_stack_push(prop_stack_t, prop_object_t, void *, void *, void *);
bool _prop_stack_pop(prop_stack_t, prop_object_t *, void **, void **, void **);
#endif

View file

@ -0,0 +1,193 @@
.\" $NetBSD: prop_string.3,v 1.8 2011/02/26 12:56:36 wiz 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.
.\"
.Dd January 21, 2008
.Dt PROP_STRING 3
.Os
.Sh NAME
.Nm prop_string ,
.Nm prop_string_create ,
.Nm prop_string_create_cstring ,
.Nm prop_string_create_cstring_nocopy ,
.Nm prop_string_copy ,
.Nm prop_string_copy_mutable ,
.Nm prop_string_size ,
.Nm prop_string_mutable ,
.Nm prop_string_cstring ,
.Nm prop_string_cstring_nocopy ,
.Nm prop_string_append ,
.Nm prop_string_append_cstring ,
.Nm prop_string_equals ,
.Nm prop_string_equals_cstring
.Nd string value property object
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.\"
.Ft prop_string_t
.Fn prop_string_create "void"
.Ft prop_string_t
.Fn prop_string_create_cstring "const char *cstring"
.Ft prop_string_t
.Fn prop_string_create_cstring_nocopy "const char *cstring"
.\"
.Ft prop_string_t
.Fn prop_string_copy "prop_string_t string"
.Ft prop_string_t
.Fn prop_string_copy_mutable "prop_string_t string"
.\"
.Ft size_t
.Fn prop_string_size "prop_string_t string"
.Ft bool
.Fn prop_string_mutable "prop_string_t string"
.\"
.Ft char *
.Fn prop_string_cstring "prop_string_t string"
.Ft const char *
.Fn prop_string_cstring_nocopy "prop_string_t string"
.\"
.Ft bool
.Fn prop_string_append "prop_string_t str1" "prop_string_t str2"
.Ft bool
.Fn prop_string_append_cstring "prop_string_t string" "const char *cstring"
.\"
.Ft bool
.Fn prop_string_equals "prop_string_t str1" "prop_string_t str2"
.Ft bool
.Fn prop_string_equals_cstring "prop_string_t string" "const char *cstring"
.Sh DESCRIPTION
The
.Nm prop_string
family of functions operate on a string value property object type.
.Bl -tag -width "xxxxx"
.It Fn prop_string_create "void"
Create an empty mutable string.
Returns
.Dv NULL
on failure.
.It Fn prop_string_create_cstring "const char *cstring"
Create a mutable string that contains a copy of
.Fa cstring .
Returns
.Dv NULL
on failure.
.It Fn prop_string_create_cstring_nocopy "const char *cstring"
Create an immutable string that contains a reference to
.Fa cstring .
Returns
.Dv NULL
on failure.
.It Fn prop_string_copy "prop_string_t string"
Copy a string.
If the string being copied is an immutable external C string reference,
then the copy is also immutable and references the same external C string.
Returns
.Dv NULL
on failure.
.It Fn prop_string_copy_mutable "prop_string_t string"
Copy a string, always creating a mutable copy.
Returns
.Dv NULL
on failure.
.It Fn prop_string_size "prop_string_t string"
Returns the size of the string, not including the terminating NUL.
If the supplied object isn't a string, zero is returned.
.It Fn prop_string_mutable "prop_string_t string"
Returns
.Dv true
if the string is mutable.
If the supplied object isn't a string,
.Dv false
is returned.
.It Fn prop_string_cstring "prop_string_t string"
Returns a copy of the string's contents as a C string.
The caller is responsible for freeing the returned buffer.
.Pp
In user space, the buffer is allocated using
.Xr malloc 3 .
In the kernel, the buffer is allocated using
.Xr malloc 9
using the malloc type
.Dv M_TEMP .
.Pp
Returns
.Dv NULL
on failure.
.It Fn prop_string_cstring_nocopy "prop_string_t string"
Returns an immutable reference to the contents of the string as a
C string.
If the supplied object isn't a string,
.Dv NULL
is returned.
.It Fn prop_string_append "prop_string_t str1" "prop_string_t str2"
Append the contents of
.Fa str2
to
.Fa str1 ,
which must be mutable.
Returns
.Dv true
upon success and
.Dv false
otherwise.
.It Fn prop_string_append_cstring "prop_string_t string" "const char *cstring"
Append the C string
.Fa cstring
to
.Fa string ,
which must be mutable.
Returns
.Dv true
upon success and
.Dv false
otherwise.
.It Fn prop_string_equals "prop_string_t str1" "prop_string_t str2"
Returns
.Dv true
if the two string objects are equivalent.
.It Fn prop_string_equals_cstring "prop_string_t string" "const char *cstring"
Returns
.Dv true
if the string's value is equivalent to
.Fa cstring .
.El
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr proplib 3
.Sh HISTORY
The
.Nm proplib
property container object library first appeared in
.Nx 4.0 .

View 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);
}

View file

@ -0,0 +1,139 @@
.\" $NetBSD: proplib.3,v 1.7 2011/01/19 20:34:23 bouyer Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Jason R. Thorpe.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 17, 2011
.Dt PROPLIB 3
.Os
.Sh NAME
.Nm proplib
.Nd property container object library
.Sh LIBRARY
.Lb libprop
.Sh SYNOPSIS
.In prop/proplib.h
.Sh DESCRIPTION
The
.Nm
library provides an abstract interface for creating and manipulating
property lists.
Property lists have object types for boolean values, opaque data, numbers,
and strings.
Structure is provided by the array and dictionary collection types.
.Pp
Property lists can be passed across protection boundaries by translating
them to an external representation.
This external representation is an XML document whose format is described
by the following DTD:
.Bd -literal -offset indent
http://www.apple.com/DTDs/PropertyList-1.0.dtd
.Ed
.Pp
Property container objects are reference counted.
When an object is created, its reference count is set to 1.
Any code that keeps a reference to an object, including the collection
types
.Pq arrays and dictionaries ,
must
.Dq retain
the object
.Pq increment its reference count .
When that reference is dropped, the object must be
.Dq released
.Pq reference count decremented .
When an object's reference count drops to 0, it is automatically freed.
.Pp
The rules for managing reference counts are very simple:
.Bl -bullet
.It
If you create an object and do not explicitly maintain a reference to it,
you must release it.
.It
If you get a reference to an object from other code and wish to maintain
a reference to it, you must retain the object.
You are responsible for
releasing the object once you drop that reference.
.It
You must never release an object unless you create it or retain it.
.El
.Pp
Object collections may be iterated by creating a special iterator object.
Iterator objects are special; they may not be retained, and they are
released using an iterator-specific release function.
.Sh SEE ALSO
.Xr prop_array 3 ,
.Xr prop_bool 3 ,
.Xr prop_data 3 ,
.Xr prop_dictionary 3 ,
.Xr prop_dictionary_util 3 ,
.Xr prop_number 3 ,
.Xr prop_object 3 ,
.Xr prop_send_ioctl 3 ,
.Xr prop_send_syscall 3 ,
.Xr prop_string 3
.Sh HISTORY
The
.Nm
property container object library first appeared in
.Nx 4.0 .
.Sh CAVEATS
.Nm
does not have a
.Sq date
object type, and thus will not parse
.Sq date
elements from an Apple XML property list.
.Pp
The
.Nm
.Sq number
object type differs from the Apple XML property list format in the following
ways:
.Bl -bullet
.It
The external representation is in base 16, not base 10.
.Nm
is able to parse base 8, base 10, and base 16
.Sq integer
elements.
.It
Internally, integers are always stored as unsigned numbers
.Pq uint64_t .
Therefore, the external representation will never be negative.
.It
Because floating point numbers are not supported,
.Sq real
elements from an Apple XML property list will not be parsed.
.El
.Pp
In order to facilitate use of
.Nm
in kernel, standalone, and user space environments, the
.Nm
parser is not a real XML parser.
It is hard-coded to parse only the property list external representation.

View file

@ -61,6 +61,7 @@
755 root operator /usr/include/arpa
755 root operator /usr/include/compat
755 root operator /usr/include/compat/machine
755 root operator /usr/include/prop
755 root operator /usr/include/ddekit
755 root operator /usr/include/ddekit/minix
755 root operator /usr/include/minix

View file

@ -24,7 +24,7 @@ SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libblockdriver libchardriver \
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
SUBDIR+= libelf libminc libcrypt libterminfo libcurses libvassert libutil \
libpuffs librefuse libbz2 libarchive
libpuffs librefuse libbz2 libarchive libprop
.endif
.if ${COMPILER_TYPE} == "ack"

191
lib/libprop/Makefile Normal file
View file

@ -0,0 +1,191 @@
# $NetBSD: Makefile,v 1.19 2011/09/30 22:08:19 jym Exp $
.include <bsd.own.mk>
WARNS=4
USE_SHLIBDIR= yes
PROPLIBDIR=${NETBSDSRCDIR}/common/lib/libprop
.include "${PROPLIBDIR}/Makefile.inc"
CPPFLAGS+=-D_LIBPROP
CPPFLAGS+= -I${NETBSDSRCDIR}/lib/nbsd_libc/include # -D_REENTRANT
LINTFLAGS+=-w
LIB= prop
MAN= prop_array.3 prop_bool.3 prop_data.3 prop_dictionary.3 \
prop_ingest.3 prop_number.3 prop_object.3 prop_string.3 proplib.3
MAN+= prop_copyin_ioctl.9
MLINKS+= prop_copyin_ioctl.9 prop_array_copyin_ioctl.9
MLINKS+= prop_copyin_ioctl.9 prop_array_copyout_ioctl.9
MLINKS+= prop_copyin_ioctl.9 prop_dictionary_copyin_ioctl.9
MLINKS+= prop_copyin_ioctl.9 prop_dictionary_copyout_ioctl.9
MAN+= prop_send_ioctl.3
MLINKS+= prop_send_ioctl.3 prop_array_send_ioctl.3
MLINKS+= prop_send_ioctl.3 prop_array_recv_ioctl.3
MLINKS+= prop_send_ioctl.3 prop_dictionary_send_ioctl.3
MLINKS+= prop_send_ioctl.3 prop_dictionary_recv_ioctl.3
MLINKS+= prop_send_ioctl.3 prop_dictionary_sendrecv_ioctl.3
MAN+= prop_send_syscall.3
MLINKS+= prop_send_syscall.3 prop_array_send_syscall.3
MLINKS+= prop_send_syscall.3 prop_array_recv_syscall.3
MLINKS+= prop_send_syscall.3 prop_dictionary_send_syscall.3
MLINKS+= prop_send_syscall.3 prop_dictionary_recv_syscall.3
MAN+= prop_dictionary_util.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_bool.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_bool.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_int8.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_uint8.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_int8.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_uint8.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_int16.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_uint16.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_int16.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_uint16.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_int32.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_uint32.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_int32.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_uint32.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_int64.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_uint64.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_int64.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_uint64.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_cstring.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_cstring.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_get_cstring_nocopy.3
MLINKS+= prop_dictionary_util.3 prop_dictionary_set_cstring_nocopy.3
MLINKS+= prop_array.3 prop_array_add.3
MLINKS+= prop_array.3 prop_array_capacity.3
MLINKS+= prop_array.3 prop_array_copy.3
MLINKS+= prop_array.3 prop_array_copy_mutable.3
MLINKS+= prop_array.3 prop_array_count.3
MLINKS+= prop_array.3 prop_array_create.3
MLINKS+= prop_array.3 prop_array_create_with_capacity.3
MLINKS+= prop_array.3 prop_array_ensure_capacity.3
MLINKS+= prop_array.3 prop_array_equals.3
MLINKS+= prop_array.3 prop_array_externalize.3
MLINKS+= prop_array.3 prop_array_externalize_to_file.3
MLINKS+= prop_array.3 prop_array_externalize_to_pref.3
MLINKS+= prop_array.3 prop_array_get.3
MLINKS+= prop_array.3 prop_array_internalize.3
MLINKS+= prop_array.3 prop_array_internalize_from_file.3
MLINKS+= prop_array.3 prop_array_internalize_from_pref.3
MLINKS+= prop_array.3 prop_array_iterator.3
MLINKS+= prop_array.3 prop_array_make_immutable.3
MLINKS+= prop_array.3 prop_array_mutable.3
MLINKS+= prop_array.3 prop_array_remove.3
MLINKS+= prop_array.3 prop_array_set.3
MAN+= prop_array_util.3
MLINKS+= prop_array_util.3 prop_array_get_bool.3
MLINKS+= prop_array_util.3 prop_array_set_bool.3
MLINKS+= prop_array_util.3 prop_array_get_int8.3
MLINKS+= prop_array_util.3 prop_array_get_uint8.3
MLINKS+= prop_array_util.3 prop_array_set_int8.3
MLINKS+= prop_array_util.3 prop_array_set_uint8.3
MLINKS+= prop_array_util.3 prop_array_get_int16.3
MLINKS+= prop_array_util.3 prop_array_get_uint16.3
MLINKS+= prop_array_util.3 prop_array_set_int16.3
MLINKS+= prop_array_util.3 prop_array_set_uint16.3
MLINKS+= prop_array_util.3 prop_array_get_int32.3
MLINKS+= prop_array_util.3 prop_array_get_uint32.3
MLINKS+= prop_array_util.3 prop_array_set_int32.3
MLINKS+= prop_array_util.3 prop_array_set_uint32.3
MLINKS+= prop_array_util.3 prop_array_get_int64.3
MLINKS+= prop_array_util.3 prop_array_get_uint64.3
MLINKS+= prop_array_util.3 prop_array_set_int64.3
MLINKS+= prop_array_util.3 prop_array_set_uint64.3
MLINKS+= prop_array_util.3 prop_array_get_cstring.3
MLINKS+= prop_array_util.3 prop_array_set_cstring.3
MLINKS+= prop_array_util.3 prop_array_get_cstring_nocopy.3
MLINKS+= prop_array_util.3 prop_array_set_cstring_nocopy.3
MLINKS+= prop_bool.3 prop_bool_copy.3
MLINKS+= prop_bool.3 prop_bool_create.3
MLINKS+= prop_bool.3 prop_bool_true.3
MLINKS+= prop_data.3 prop_data_copy.3
MLINKS+= prop_data.3 prop_data_create_data.3
MLINKS+= prop_data.3 prop_data_create_data_nocopy.3
MLINKS+= prop_data.3 prop_data_data.3
MLINKS+= prop_data.3 prop_data_data_nocopy.3
MLINKS+= prop_data.3 prop_data_equals.3
MLINKS+= prop_data.3 prop_data_equals_data.3
MLINKS+= prop_data.3 prop_data_size.3
MLINKS+= prop_dictionary.3 prop_dictionary_all_keys.3
MLINKS+= prop_dictionary.3 prop_dictionary_capacity.3
MLINKS+= prop_dictionary.3 prop_dictionary_copy.3
MLINKS+= prop_dictionary.3 prop_dictionary_copy_mutable.3
MLINKS+= prop_dictionary.3 prop_dictionary_count.3
MLINKS+= prop_dictionary.3 prop_dictionary_create.3
MLINKS+= prop_dictionary.3 prop_dictionary_create_with_capacity.3
MLINKS+= prop_dictionary.3 prop_dictionary_ensure_capacity.3
MLINKS+= prop_dictionary.3 prop_dictionary_equals.3
MLINKS+= prop_dictionary.3 prop_dictionary_externalize.3
MLINKS+= prop_dictionary.3 prop_dictionary_externalize_to_file.3
MLINKS+= prop_dictionary.3 prop_dictionary_externalize_to_pref.3
MLINKS+= prop_dictionary.3 prop_dictionary_get.3
MLINKS+= prop_dictionary.3 prop_dictionary_get_keysym.3
MLINKS+= prop_dictionary.3 prop_dictionary_internalize.3
MLINKS+= prop_dictionary.3 prop_dictionary_internalize_from_file.3
MLINKS+= prop_dictionary.3 prop_dictionary_internalize_from_pref.3
MLINKS+= prop_dictionary.3 prop_dictionary_iterator.3
MLINKS+= prop_dictionary.3 prop_dictionary_keysym_cstring_nocopy.3
MLINKS+= prop_dictionary.3 prop_dictionary_keysym_equals.3
MLINKS+= prop_dictionary.3 prop_dictionary_make_immutable.3
MLINKS+= prop_dictionary.3 prop_dictionary_mutable.3
MLINKS+= prop_dictionary.3 prop_dictionary_remove.3
MLINKS+= prop_dictionary.3 prop_dictionary_remove_keysym.3
MLINKS+= prop_dictionary.3 prop_dictionary_set.3
MLINKS+= prop_dictionary.3 prop_dictionary_set_keysym.3
MLINKS+= prop_ingest.3 prop_ingest_context_alloc.3
MLINKS+= prop_ingest.3 prop_ingest_context_error.3
MLINKS+= prop_ingest.3 prop_ingest_context_free.3
MLINKS+= prop_ingest.3 prop_ingest_context_key.3
MLINKS+= prop_ingest.3 prop_ingest_context_private.3
MLINKS+= prop_ingest.3 prop_ingest_context_type.3
MLINKS+= prop_ingest.3 prop_dictionary_ingest.3
MLINKS+= prop_number.3 prop_number_copy.3
MLINKS+= prop_number.3 prop_number_create_integer.3
MLINKS+= prop_number.3 prop_number_create_unsigned_integer.3
MLINKS+= prop_number.3 prop_number_equals.3
MLINKS+= prop_number.3 prop_number_equals_integer.3
MLINKS+= prop_number.3 prop_number_equals_unsigned_integer.3
MLINKS+= prop_number.3 prop_number_size.3
MLINKS+= prop_number.3 prop_number_unsigned.3
MLINKS+= prop_number.3 prop_number_integer_value.3
MLINKS+= prop_number.3 prop_number_unsigned_integer_value.3
MLINKS+= prop_object.3 prop_object_equals.3
MLINKS+= prop_object.3 prop_object_iterator_next.3
MLINKS+= prop_object.3 prop_object_iterator_release.3
MLINKS+= prop_object.3 prop_object_iterator_reset.3
MLINKS+= prop_object.3 prop_object_release.3
MLINKS+= prop_object.3 prop_object_retain.3
MLINKS+= prop_object.3 prop_object_type.3
MLINKS+= prop_string.3 prop_string_append.3
MLINKS+= prop_string.3 prop_string_append_cstring.3
MLINKS+= prop_string.3 prop_string_copy.3
MLINKS+= prop_string.3 prop_string_copy_mutable.3
MLINKS+= prop_string.3 prop_string_create.3
MLINKS+= prop_string.3 prop_string_create_cstring.3
MLINKS+= prop_string.3 prop_string_create_cstring_nocopy.3
MLINKS+= prop_string.3 prop_string_cstring.3
MLINKS+= prop_string.3 prop_string_cstring_nocopy.3
MLINKS+= prop_string.3 prop_string_equals.3
MLINKS+= prop_string.3 prop_string_equals_cstring.3
MLINKS+= prop_string.3 prop_string_mutable.3
MLINKS+= prop_string.3 prop_string_size.3
.include <bsd.lib.mk>

View file

@ -0,0 +1,4 @@
# $NetBSD: shlib_version,v 1.10 2009/10/10 18:06:54 bad Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
major=1
minor=1

View file

@ -67,7 +67,9 @@ INCSDIR= /usr/include
.else
SUBDIR= rpc
.endif
.if !defined(__MINIX)
.if defined(__MINIX)
SUBDIR+= prop
.else
SUBDIR+= ../common/include/prop
.endif

View file

@ -0,0 +1,9 @@
# $NetBSD: Makefile,v 1.3 2007/08/17 11:05:04 pavel Exp $
INCS= prop_array.h prop_bool.h prop_data.h prop_dictionary.h \
prop_ingest.h prop_number.h prop_object.h prop_string.h \
proplib.h plistref.h
INCSDIR= /usr/include/prop
.include <bsd.prog.mk>

View file

@ -0,0 +1,48 @@
/* $NetBSD: plistref.h,v 1.2 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_PLISTREF_H_
#define _PROPLIB_PLISTREF_H_
/* for size_t */
#include <sys/types.h>
/*
* Property List Reference --
* Used to pass externalized property lists across protection
* boundaries (ioctls, syscalls, etc.).
*/
struct plistref {
void *pref_plist; /* plist data */
size_t pref_len; /* total length of plist data */
};
#endif /* _PROPLIB_PLISTREF_H_ */

View file

@ -0,0 +1,163 @@
/* $NetBSD: prop_array.h,v 1.13 2011/09/30 22:08:18 jym Exp $ */
/*-
* Copyright (c) 2006, 2009 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 <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 *);
prop_array_t prop_array_internalize_from_file(const char *);
#if defined(__NetBSD__)
struct plistref;
#if !defined(_KERNEL) && !defined(_STANDALONE)
bool prop_array_externalize_to_pref(prop_array_t, struct plistref *);
bool prop_array_internalize_from_pref(const struct plistref *,
prop_array_t *);
int prop_array_send_ioctl(prop_array_t, int, unsigned long);
int prop_array_recv_ioctl(int, unsigned long, prop_array_t *);
int prop_array_send_syscall(prop_array_t, struct plistref *);
int prop_array_recv_syscall(const struct plistref *,
prop_array_t *);
#elif defined(_KERNEL)
int prop_array_copyin(const struct plistref *, prop_array_t *);
int prop_array_copyout(struct plistref *, prop_array_t);
int prop_array_copyin_ioctl(const struct plistref *, const u_long,
prop_array_t *);
int prop_array_copyout_ioctl(struct plistref *, const u_long,
prop_array_t);
#endif
#endif /* __NetBSD__ */
/*
* 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 *);
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
__END_DECLS
#endif /* _PROPLIB_PROP_ARRAY_H_ */

View file

@ -0,0 +1,48 @@
/* $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 <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_ */

View file

@ -0,0 +1,54 @@
/* $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 <prop/prop_object.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_ */

View file

@ -0,0 +1,181 @@
/* $NetBSD: prop_dictionary.h,v 1.14 2011/09/30 22:08:18 jym Exp $ */
/*-
* Copyright (c) 2006, 2009 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 <prop/prop_object.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 *);
prop_dictionary_t prop_dictionary_internalize_from_file(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);
#if defined(__NetBSD__)
struct plistref;
#if !defined(_KERNEL) && !defined(_STANDALONE)
bool prop_dictionary_externalize_to_pref(prop_dictionary_t, struct plistref *);
bool prop_dictionary_internalize_from_pref(const struct plistref *,
prop_dictionary_t *);
int prop_dictionary_send_ioctl(prop_dictionary_t, int,
unsigned long);
int prop_dictionary_recv_ioctl(int, unsigned long,
prop_dictionary_t *);
int prop_dictionary_sendrecv_ioctl(prop_dictionary_t,
int, unsigned long,
prop_dictionary_t *);
int prop_dictionary_send_syscall(prop_dictionary_t,
struct plistref *);
int prop_dictionary_recv_syscall(const struct plistref *,
prop_dictionary_t *);
#elif defined(_KERNEL)
int prop_dictionary_copyin(const struct plistref *,
prop_dictionary_t *);
int prop_dictionary_copyout(struct plistref *,
prop_dictionary_t);
int prop_dictionary_copyin_ioctl(const struct plistref *,
const u_long,
prop_dictionary_t *);
int prop_dictionary_copyout_ioctl(struct plistref *,
const u_long,
prop_dictionary_t);
#endif
#endif /* __NetBSD__ */
/*
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*/
bool prop_dictionary_get_dict(prop_dictionary_t, const char *,
prop_dictionary_t *);
bool prop_dictionary_get_bool(prop_dictionary_t, const char *,
bool *);
bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
bool);
bool prop_dictionary_get_int8(prop_dictionary_t, const char *,
int8_t *);
bool prop_dictionary_get_uint8(prop_dictionary_t, const char *,
uint8_t *);
bool prop_dictionary_set_int8(prop_dictionary_t, const char *,
int8_t);
bool prop_dictionary_set_uint8(prop_dictionary_t, const char *,
uint8_t);
bool prop_dictionary_get_int16(prop_dictionary_t, const char *,
int16_t *);
bool prop_dictionary_get_uint16(prop_dictionary_t, const char *,
uint16_t *);
bool prop_dictionary_set_int16(prop_dictionary_t, const char *,
int16_t);
bool prop_dictionary_set_uint16(prop_dictionary_t, const char *,
uint16_t);
bool prop_dictionary_get_int32(prop_dictionary_t, const char *,
int32_t *);
bool prop_dictionary_get_uint32(prop_dictionary_t, const char *,
uint32_t *);
bool prop_dictionary_set_int32(prop_dictionary_t, const char *,
int32_t);
bool prop_dictionary_set_uint32(prop_dictionary_t, const char *,
uint32_t);
bool prop_dictionary_get_int64(prop_dictionary_t, const char *,
int64_t *);
bool prop_dictionary_get_uint64(prop_dictionary_t, const char *,
uint64_t *);
bool prop_dictionary_set_int64(prop_dictionary_t, const char *,
int64_t);
bool prop_dictionary_set_uint64(prop_dictionary_t, const char *,
uint64_t);
bool prop_dictionary_get_cstring(prop_dictionary_t, const char *,
char **);
bool prop_dictionary_set_cstring(prop_dictionary_t, const char *,
const char *);
bool prop_dictionary_get_cstring_nocopy(prop_dictionary_t,
const char *,
const char **);
bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
const char *,
const char *);
bool prop_dictionary_set_and_rel(prop_dictionary_t,
const char *,
prop_object_t);
__END_DECLS
#endif /* _PROPLIB_PROP_DICTIONARY_H_ */

View file

@ -0,0 +1,90 @@
/* $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_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_ */

View file

@ -0,0 +1,59 @@
/* $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_
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <stdint.h>
#endif
#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_ */

View file

@ -0,0 +1,72 @@
/* $NetBSD: prop_object.h,v 1.8 2008/12/05 13:11:41 ad 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 <sys/types.h>
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <stdbool.h>
#endif /* ! _KERNEL && ! _STANDALONE */
typedef void *prop_object_t;
typedef enum {
PROP_TYPE_UNKNOWN = 0x00000000,
#ifndef _PROPLIB_ZFS_CONFLICT
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' */
#endif /* !_PROPLIB_ZFS_CONFLICT */
} 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_ */

View file

@ -0,0 +1,60 @@
/* $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 <prop/prop_object.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_ */

View file

@ -0,0 +1,50 @@
/* $NetBSD: proplib.h,v 1.7 2009/09/13 18:45:10 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PROPLIB_PROPLIB_H_
#define _PROPLIB_PROPLIB_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>
#include <prop/plistref.h>
#ifdef _KERNEL
void prop_kern_init(void);
#endif
#endif /* _PROPLIB_PROPLIB_H_ */

View file

@ -1,3 +1,4 @@
common/lib/libprop src/common/lib/libprop
common/lib/libc src/common/lib/libc
lib/nbsd_libc src/lib/libc
lib/nbsd_libm src/lib/libm