import netbsd libprop
This commit is contained in:
parent
59ff5cbd87
commit
6b6d114a21
9
common/lib/libprop/Makefile.inc
Normal file
9
common/lib/libprop/Makefile.inc
Normal 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
|
308
common/lib/libprop/prop_array.3
Normal file
308
common/lib/libprop/prop_array.3
Normal 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 .
|
911
common/lib/libprop/prop_array.c
Normal file
911
common/lib/libprop/prop_array.c
Normal 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 */
|
228
common/lib/libprop/prop_array_util.3
Normal file
228
common/lib/libprop/prop_array_util.3
Normal 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 .
|
251
common/lib/libprop/prop_array_util.c
Normal file
251
common/lib/libprop/prop_array_util.c
Normal 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;
|
||||
}
|
82
common/lib/libprop/prop_bool.3
Normal file
82
common/lib/libprop/prop_bool.3
Normal 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 .
|
222
common/lib/libprop/prop_bool.c
Normal file
222
common/lib/libprop/prop_bool.c
Normal 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);
|
||||
}
|
194
common/lib/libprop/prop_copyin_ioctl.9
Normal file
194
common/lib/libprop/prop_copyin_ioctl.9
Normal 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 .
|
148
common/lib/libprop/prop_data.3
Normal file
148
common/lib/libprop/prop_data.3
Normal 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 .
|
627
common/lib/libprop/prop_data.c
Normal file
627
common/lib/libprop/prop_data.c
Normal 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);
|
||||
}
|
353
common/lib/libprop/prop_dictionary.3
Normal file
353
common/lib/libprop/prop_dictionary.3
Normal 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 .
|
1420
common/lib/libprop/prop_dictionary.c
Normal file
1420
common/lib/libprop/prop_dictionary.c
Normal file
File diff suppressed because it is too large
Load diff
200
common/lib/libprop/prop_dictionary_util.3
Normal file
200
common/lib/libprop/prop_dictionary_util.3
Normal 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 .
|
232
common/lib/libprop/prop_dictionary_util.c
Normal file
232
common/lib/libprop/prop_dictionary_util.c
Normal 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;
|
||||
}
|
181
common/lib/libprop/prop_ingest.3
Normal file
181
common/lib/libprop/prop_ingest.3
Normal 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 .
|
159
common/lib/libprop/prop_ingest.c
Normal file
159
common/lib/libprop/prop_ingest.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* $NetBSD: prop_ingest.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <prop/proplib.h>
|
||||
#include "prop_object_impl.h"
|
||||
|
||||
struct _prop_ingest_context {
|
||||
prop_ingest_error_t pic_error;
|
||||
prop_type_t pic_type;
|
||||
const char * pic_key;
|
||||
void * pic_private;
|
||||
};
|
||||
|
||||
/*
|
||||
* prop_ingest_context_alloc --
|
||||
* Allocate and initialize an ingest context.
|
||||
*/
|
||||
prop_ingest_context_t
|
||||
prop_ingest_context_alloc(void *private)
|
||||
{
|
||||
prop_ingest_context_t ctx;
|
||||
|
||||
ctx = _PROP_MALLOC(sizeof(*ctx), M_TEMP);
|
||||
if (ctx != NULL) {
|
||||
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
|
||||
ctx->pic_type = PROP_TYPE_UNKNOWN;
|
||||
ctx->pic_key = NULL;
|
||||
ctx->pic_private = private;
|
||||
}
|
||||
return (ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_ingest_context_free --
|
||||
* Free an ingest context.
|
||||
*/
|
||||
void
|
||||
prop_ingest_context_free(prop_ingest_context_t ctx)
|
||||
{
|
||||
|
||||
_PROP_FREE(ctx, M_TEMP);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_ingest_context_error --
|
||||
* Get the error code from an ingest context.
|
||||
*/
|
||||
prop_ingest_error_t
|
||||
prop_ingest_context_error(prop_ingest_context_t ctx)
|
||||
{
|
||||
|
||||
return (ctx->pic_error);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_ingest_context_type --
|
||||
* Return the type of last object visisted by an ingest context.
|
||||
*/
|
||||
prop_type_t
|
||||
prop_ingest_context_type(prop_ingest_context_t ctx)
|
||||
{
|
||||
|
||||
return (ctx->pic_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_ingest_context_key --
|
||||
* Return the last key looked up by an ingest context.
|
||||
*/
|
||||
const char *
|
||||
prop_ingest_context_key(prop_ingest_context_t ctx)
|
||||
{
|
||||
|
||||
return (ctx->pic_key);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_ingest_context_private --
|
||||
* Return the caller-private data associated with an ingest context.
|
||||
*/
|
||||
void *
|
||||
prop_ingest_context_private(prop_ingest_context_t ctx)
|
||||
{
|
||||
|
||||
return (ctx->pic_private);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_dictionary_ingest --
|
||||
* Ingest a dictionary using handlers for each object to translate
|
||||
* into an arbitrary binary format.
|
||||
*/
|
||||
bool
|
||||
prop_dictionary_ingest(prop_dictionary_t dict,
|
||||
const prop_ingest_table_entry rules[],
|
||||
prop_ingest_context_t ctx)
|
||||
{
|
||||
const prop_ingest_table_entry *pite;
|
||||
prop_object_t obj;
|
||||
|
||||
ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR;
|
||||
|
||||
for (pite = rules; pite->pite_key != NULL; pite++) {
|
||||
ctx->pic_key = pite->pite_key;
|
||||
obj = prop_dictionary_get(dict, pite->pite_key);
|
||||
ctx->pic_type = prop_object_type(obj);
|
||||
if (obj == NULL) {
|
||||
if (pite->pite_flags & PROP_INGEST_FLAG_OPTIONAL) {
|
||||
if ((*pite->pite_handler)(ctx, NULL) == false) {
|
||||
ctx->pic_error =
|
||||
PROP_INGEST_ERROR_HANDLER_FAILED;
|
||||
return (false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ctx->pic_error = PROP_INGEST_ERROR_NO_KEY;
|
||||
return (false);
|
||||
}
|
||||
if (ctx->pic_type != pite->pite_type &&
|
||||
pite->pite_type != PROP_TYPE_UNKNOWN) {
|
||||
ctx->pic_error = PROP_INGEST_ERROR_WRONG_TYPE;
|
||||
return (false);
|
||||
}
|
||||
if ((*pite->pite_handler)(ctx, obj) == false) {
|
||||
ctx->pic_error = PROP_INGEST_ERROR_HANDLER_FAILED;
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
612
common/lib/libprop/prop_kern.c
Normal file
612
common/lib/libprop/prop_kern.c
Normal 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__ */
|
210
common/lib/libprop/prop_number.3
Normal file
210
common/lib/libprop/prop_number.3
Normal 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 .
|
592
common/lib/libprop/prop_number.c
Normal file
592
common/lib/libprop/prop_number.c
Normal 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);
|
||||
}
|
141
common/lib/libprop/prop_object.3
Normal file
141
common/lib/libprop/prop_object.3
Normal 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 .
|
1230
common/lib/libprop/prop_object.c
Normal file
1230
common/lib/libprop/prop_object.c
Normal file
File diff suppressed because it is too large
Load diff
436
common/lib/libprop/prop_object_impl.h
Normal file
436
common/lib/libprop/prop_object_impl.h
Normal 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
1057
common/lib/libprop/prop_rb.c
Normal file
File diff suppressed because it is too large
Load diff
154
common/lib/libprop/prop_rb_impl.h
Normal file
154
common/lib/libprop/prop_rb_impl.h
Normal 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_*/
|
151
common/lib/libprop/prop_send_ioctl.3
Normal file
151
common/lib/libprop/prop_send_ioctl.3
Normal 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 .
|
128
common/lib/libprop/prop_send_syscall.3
Normal file
128
common/lib/libprop/prop_send_syscall.3
Normal 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 .
|
118
common/lib/libprop/prop_stack.c
Normal file
118
common/lib/libprop/prop_stack.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* $NetBSD: prop_stack.c,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "prop_stack.h"
|
||||
#include "prop_object_impl.h"
|
||||
|
||||
void
|
||||
_prop_stack_init(prop_stack_t stack)
|
||||
{
|
||||
stack->used_intern_elems = 0;
|
||||
SLIST_INIT(&stack->extern_elems);
|
||||
}
|
||||
|
||||
bool
|
||||
_prop_stack_push(prop_stack_t stack, prop_object_t obj, void *data1,
|
||||
void *data2, void *data3)
|
||||
{
|
||||
struct _prop_stack_extern_elem *eelem;
|
||||
struct _prop_stack_intern_elem *ielem;
|
||||
|
||||
if (stack->used_intern_elems == PROP_STACK_INTERN_ELEMS) {
|
||||
eelem = _PROP_MALLOC(sizeof(*eelem), M_TEMP);
|
||||
|
||||
if (eelem == NULL)
|
||||
return false;
|
||||
|
||||
eelem->object = obj;
|
||||
eelem->object_data[0] = data1;
|
||||
eelem->object_data[1] = data2;
|
||||
eelem->object_data[2] = data3;
|
||||
|
||||
SLIST_INSERT_HEAD(&stack->extern_elems, eelem, stack_link);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_PROP_ASSERT(stack->used_intern_elems < PROP_STACK_INTERN_ELEMS);
|
||||
_PROP_ASSERT(SLIST_EMPTY(&stack->extern_elems));
|
||||
|
||||
ielem = &stack->intern_elems[stack->used_intern_elems];
|
||||
ielem->object = obj;
|
||||
ielem->object_data[0] = data1;
|
||||
ielem->object_data[1] = data2;
|
||||
ielem->object_data[2] = data3;
|
||||
|
||||
++stack->used_intern_elems;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
_prop_stack_pop(prop_stack_t stack, prop_object_t *obj, void **data1,
|
||||
void **data2, void **data3)
|
||||
{
|
||||
struct _prop_stack_extern_elem *eelem;
|
||||
struct _prop_stack_intern_elem *ielem;
|
||||
|
||||
if (stack->used_intern_elems == 0)
|
||||
return false;
|
||||
|
||||
if ((eelem = SLIST_FIRST(&stack->extern_elems)) != NULL) {
|
||||
_PROP_ASSERT(stack->used_intern_elems == PROP_STACK_INTERN_ELEMS);
|
||||
|
||||
SLIST_REMOVE_HEAD(&stack->extern_elems, stack_link);
|
||||
if (obj)
|
||||
*obj = eelem->object;
|
||||
if (data1)
|
||||
*data1 = eelem->object_data[0];
|
||||
if (data2)
|
||||
*data2 = eelem->object_data[1];
|
||||
if (data3)
|
||||
*data3 = eelem->object_data[2];
|
||||
_PROP_FREE(eelem, M_TEMP);
|
||||
return true;
|
||||
}
|
||||
|
||||
--stack->used_intern_elems;
|
||||
ielem = &stack->intern_elems[stack->used_intern_elems];
|
||||
|
||||
if (obj)
|
||||
*obj = ielem->object;
|
||||
if (data1)
|
||||
*data1 = ielem->object_data[0];
|
||||
if (data2)
|
||||
*data2 = ielem->object_data[1];
|
||||
if (data3)
|
||||
*data3 = ielem->object_data[2];
|
||||
|
||||
return true;
|
||||
}
|
64
common/lib/libprop/prop_stack.h
Normal file
64
common/lib/libprop/prop_stack.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: prop_stack.h,v 1.2 2007/08/30 12:23:54 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _PROP_STACK_H
|
||||
#define _PROP_STACK_H
|
||||
|
||||
#include <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
|
193
common/lib/libprop/prop_string.3
Normal file
193
common/lib/libprop/prop_string.3
Normal 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 .
|
471
common/lib/libprop/prop_string.c
Normal file
471
common/lib/libprop/prop_string.c
Normal file
|
@ -0,0 +1,471 @@
|
|||
/* $NetBSD: prop_string.c,v 1.11 2008/08/03 04:00:12 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <prop/prop_string.h>
|
||||
#include "prop_object_impl.h"
|
||||
|
||||
struct _prop_string {
|
||||
struct _prop_object ps_obj;
|
||||
union {
|
||||
char * psu_mutable;
|
||||
const char * psu_immutable;
|
||||
} ps_un;
|
||||
#define ps_mutable ps_un.psu_mutable
|
||||
#define ps_immutable ps_un.psu_immutable
|
||||
size_t ps_size; /* not including \0 */
|
||||
int ps_flags;
|
||||
};
|
||||
|
||||
#define PS_F_NOCOPY 0x01
|
||||
|
||||
_PROP_POOL_INIT(_prop_string_pool, sizeof(struct _prop_string), "propstng")
|
||||
|
||||
_PROP_MALLOC_DEFINE(M_PROP_STRING, "prop string",
|
||||
"property string container object")
|
||||
|
||||
static _prop_object_free_rv_t
|
||||
_prop_string_free(prop_stack_t, prop_object_t *);
|
||||
static bool _prop_string_externalize(
|
||||
struct _prop_object_externalize_context *,
|
||||
void *);
|
||||
static _prop_object_equals_rv_t
|
||||
_prop_string_equals(prop_object_t, prop_object_t,
|
||||
void **, void **,
|
||||
prop_object_t *, prop_object_t *);
|
||||
|
||||
static const struct _prop_object_type _prop_object_type_string = {
|
||||
.pot_type = PROP_TYPE_STRING,
|
||||
.pot_free = _prop_string_free,
|
||||
.pot_extern = _prop_string_externalize,
|
||||
.pot_equals = _prop_string_equals,
|
||||
};
|
||||
|
||||
#define prop_object_is_string(x) \
|
||||
((x) != NULL && (x)->ps_obj.po_type == &_prop_object_type_string)
|
||||
#define prop_string_contents(x) ((x)->ps_immutable ? (x)->ps_immutable : "")
|
||||
|
||||
/* ARGSUSED */
|
||||
static _prop_object_free_rv_t
|
||||
_prop_string_free(prop_stack_t stack, prop_object_t *obj)
|
||||
{
|
||||
prop_string_t ps = *obj;
|
||||
|
||||
if ((ps->ps_flags & PS_F_NOCOPY) == 0 && ps->ps_mutable != NULL)
|
||||
_PROP_FREE(ps->ps_mutable, M_PROP_STRING);
|
||||
_PROP_POOL_PUT(_prop_string_pool, ps);
|
||||
|
||||
return (_PROP_OBJECT_FREE_DONE);
|
||||
}
|
||||
|
||||
static bool
|
||||
_prop_string_externalize(struct _prop_object_externalize_context *ctx,
|
||||
void *v)
|
||||
{
|
||||
prop_string_t ps = v;
|
||||
|
||||
if (ps->ps_size == 0)
|
||||
return (_prop_object_externalize_empty_tag(ctx, "string"));
|
||||
|
||||
if (_prop_object_externalize_start_tag(ctx, "string") == false ||
|
||||
_prop_object_externalize_append_encoded_cstring(ctx,
|
||||
ps->ps_immutable) == false ||
|
||||
_prop_object_externalize_end_tag(ctx, "string") == false)
|
||||
return (false);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static _prop_object_equals_rv_t
|
||||
_prop_string_equals(prop_object_t v1, prop_object_t v2,
|
||||
void **stored_pointer1, void **stored_pointer2,
|
||||
prop_object_t *next_obj1, prop_object_t *next_obj2)
|
||||
{
|
||||
prop_string_t str1 = v1;
|
||||
prop_string_t str2 = v2;
|
||||
|
||||
if (str1 == str2)
|
||||
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||
if (str1->ps_size != str2->ps_size)
|
||||
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||
if (strcmp(prop_string_contents(str1), prop_string_contents(str2)))
|
||||
return (_PROP_OBJECT_EQUALS_FALSE);
|
||||
else
|
||||
return (_PROP_OBJECT_EQUALS_TRUE);
|
||||
}
|
||||
|
||||
static prop_string_t
|
||||
_prop_string_alloc(void)
|
||||
{
|
||||
prop_string_t ps;
|
||||
|
||||
ps = _PROP_POOL_GET(_prop_string_pool);
|
||||
if (ps != NULL) {
|
||||
_prop_object_init(&ps->ps_obj, &_prop_object_type_string);
|
||||
|
||||
ps->ps_mutable = NULL;
|
||||
ps->ps_size = 0;
|
||||
ps->ps_flags = 0;
|
||||
}
|
||||
|
||||
return (ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_create --
|
||||
* Create an empty mutable string.
|
||||
*/
|
||||
prop_string_t
|
||||
prop_string_create(void)
|
||||
{
|
||||
|
||||
return (_prop_string_alloc());
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_create_cstring --
|
||||
* Create a string that contains a copy of the provided C string.
|
||||
*/
|
||||
prop_string_t
|
||||
prop_string_create_cstring(const char *str)
|
||||
{
|
||||
prop_string_t ps;
|
||||
char *cp;
|
||||
size_t len;
|
||||
|
||||
ps = _prop_string_alloc();
|
||||
if (ps != NULL) {
|
||||
len = strlen(str);
|
||||
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||
if (cp == NULL) {
|
||||
prop_object_release(ps);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(cp, str);
|
||||
ps->ps_mutable = cp;
|
||||
ps->ps_size = len;
|
||||
}
|
||||
return (ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_create_cstring_nocopy --
|
||||
* Create an immutable string that contains a refrence to the
|
||||
* provided C string.
|
||||
*/
|
||||
prop_string_t
|
||||
prop_string_create_cstring_nocopy(const char *str)
|
||||
{
|
||||
prop_string_t ps;
|
||||
|
||||
ps = _prop_string_alloc();
|
||||
if (ps != NULL) {
|
||||
ps->ps_immutable = str;
|
||||
ps->ps_size = strlen(str);
|
||||
ps->ps_flags |= PS_F_NOCOPY;
|
||||
}
|
||||
return (ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_copy --
|
||||
* Copy a string. If the original string is immutable, then the
|
||||
* copy is also immutable and references the same external data.
|
||||
*/
|
||||
prop_string_t
|
||||
prop_string_copy(prop_string_t ops)
|
||||
{
|
||||
prop_string_t ps;
|
||||
|
||||
if (! prop_object_is_string(ops))
|
||||
return (NULL);
|
||||
|
||||
ps = _prop_string_alloc();
|
||||
if (ps != NULL) {
|
||||
ps->ps_size = ops->ps_size;
|
||||
ps->ps_flags = ops->ps_flags;
|
||||
if (ops->ps_flags & PS_F_NOCOPY)
|
||||
ps->ps_immutable = ops->ps_immutable;
|
||||
else {
|
||||
char *cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
|
||||
if (cp == NULL) {
|
||||
prop_object_release(ps);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(cp, prop_string_contents(ops));
|
||||
ps->ps_mutable = cp;
|
||||
}
|
||||
}
|
||||
return (ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_copy_mutable --
|
||||
* Copy a string, always returning a mutable copy.
|
||||
*/
|
||||
prop_string_t
|
||||
prop_string_copy_mutable(prop_string_t ops)
|
||||
{
|
||||
prop_string_t ps;
|
||||
char *cp;
|
||||
|
||||
if (! prop_object_is_string(ops))
|
||||
return (NULL);
|
||||
|
||||
ps = _prop_string_alloc();
|
||||
if (ps != NULL) {
|
||||
ps->ps_size = ops->ps_size;
|
||||
cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
|
||||
if (cp == NULL) {
|
||||
prop_object_release(ps);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(cp, prop_string_contents(ops));
|
||||
ps->ps_mutable = cp;
|
||||
}
|
||||
return (ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_size --
|
||||
* Return the size of the string, not including the terminating NUL.
|
||||
*/
|
||||
size_t
|
||||
prop_string_size(prop_string_t ps)
|
||||
{
|
||||
|
||||
if (! prop_object_is_string(ps))
|
||||
return (0);
|
||||
|
||||
return (ps->ps_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_mutable --
|
||||
* Return true if the string is a mutable string.
|
||||
*/
|
||||
bool
|
||||
prop_string_mutable(prop_string_t ps)
|
||||
{
|
||||
|
||||
if (! prop_object_is_string(ps))
|
||||
return (false);
|
||||
|
||||
return ((ps->ps_flags & PS_F_NOCOPY) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_cstring --
|
||||
* Return a copy of the contents of the string as a C string.
|
||||
* The string is allocated with the M_TEMP malloc type.
|
||||
*/
|
||||
char *
|
||||
prop_string_cstring(prop_string_t ps)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (! prop_object_is_string(ps))
|
||||
return (NULL);
|
||||
|
||||
cp = _PROP_MALLOC(ps->ps_size + 1, M_TEMP);
|
||||
if (cp != NULL)
|
||||
strcpy(cp, prop_string_contents(ps));
|
||||
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_cstring_nocopy --
|
||||
* Return an immutable reference to the contents of the string
|
||||
* as a C string.
|
||||
*/
|
||||
const char *
|
||||
prop_string_cstring_nocopy(prop_string_t ps)
|
||||
{
|
||||
|
||||
if (! prop_object_is_string(ps))
|
||||
return (NULL);
|
||||
|
||||
return (prop_string_contents(ps));
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_append --
|
||||
* Append the contents of one string to another. Returns true
|
||||
* upon success. The destination string must be mutable.
|
||||
*/
|
||||
bool
|
||||
prop_string_append(prop_string_t dst, prop_string_t src)
|
||||
{
|
||||
char *ocp, *cp;
|
||||
size_t len;
|
||||
|
||||
if (! (prop_object_is_string(dst) &&
|
||||
prop_object_is_string(src)))
|
||||
return (false);
|
||||
|
||||
if (dst->ps_flags & PS_F_NOCOPY)
|
||||
return (false);
|
||||
|
||||
len = dst->ps_size + src->ps_size;
|
||||
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||
if (cp == NULL)
|
||||
return (false);
|
||||
sprintf(cp, "%s%s", prop_string_contents(dst),
|
||||
prop_string_contents(src));
|
||||
ocp = dst->ps_mutable;
|
||||
dst->ps_mutable = cp;
|
||||
dst->ps_size = len;
|
||||
if (ocp != NULL)
|
||||
_PROP_FREE(ocp, M_PROP_STRING);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_append_cstring --
|
||||
* Append a C string to a string. Returns true upon success.
|
||||
* The destination string must be mutable.
|
||||
*/
|
||||
bool
|
||||
prop_string_append_cstring(prop_string_t dst, const char *src)
|
||||
{
|
||||
char *ocp, *cp;
|
||||
size_t len;
|
||||
|
||||
if (! prop_object_is_string(dst))
|
||||
return (false);
|
||||
|
||||
_PROP_ASSERT(src != NULL);
|
||||
|
||||
if (dst->ps_flags & PS_F_NOCOPY)
|
||||
return (false);
|
||||
|
||||
len = dst->ps_size + strlen(src);
|
||||
cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||
if (cp == NULL)
|
||||
return (false);
|
||||
sprintf(cp, "%s%s", prop_string_contents(dst), src);
|
||||
ocp = dst->ps_mutable;
|
||||
dst->ps_mutable = cp;
|
||||
dst->ps_size = len;
|
||||
if (ocp != NULL)
|
||||
_PROP_FREE(ocp, M_PROP_STRING);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_equals --
|
||||
* Return true if two strings are equivalent.
|
||||
*/
|
||||
bool
|
||||
prop_string_equals(prop_string_t str1, prop_string_t str2)
|
||||
{
|
||||
if (!prop_object_is_string(str1) || !prop_object_is_string(str2))
|
||||
return (false);
|
||||
|
||||
return prop_object_equals(str1, str2);
|
||||
}
|
||||
|
||||
/*
|
||||
* prop_string_equals_cstring --
|
||||
* Return true if the string is equivalent to the specified
|
||||
* C string.
|
||||
*/
|
||||
bool
|
||||
prop_string_equals_cstring(prop_string_t ps, const char *cp)
|
||||
{
|
||||
|
||||
if (! prop_object_is_string(ps))
|
||||
return (false);
|
||||
|
||||
return (strcmp(prop_string_contents(ps), cp) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* _prop_string_internalize --
|
||||
* Parse a <string>...</string> and return the object created from the
|
||||
* external representation.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
bool
|
||||
_prop_string_internalize(prop_stack_t stack, prop_object_t *obj,
|
||||
struct _prop_object_internalize_context *ctx)
|
||||
{
|
||||
prop_string_t string;
|
||||
char *str;
|
||||
size_t len, alen;
|
||||
|
||||
if (ctx->poic_is_empty_element) {
|
||||
*obj = prop_string_create();
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* No attributes recognized here. */
|
||||
if (ctx->poic_tagattr != NULL)
|
||||
return (true);
|
||||
|
||||
/* Compute the length of the result. */
|
||||
if (_prop_object_internalize_decode_string(ctx, NULL, 0, &len,
|
||||
NULL) == false)
|
||||
return (true);
|
||||
|
||||
str = _PROP_MALLOC(len + 1, M_PROP_STRING);
|
||||
if (str == NULL)
|
||||
return (true);
|
||||
|
||||
if (_prop_object_internalize_decode_string(ctx, str, len, &alen,
|
||||
&ctx->poic_cp) == false ||
|
||||
alen != len) {
|
||||
_PROP_FREE(str, M_PROP_STRING);
|
||||
return (true);
|
||||
}
|
||||
str[len] = '\0';
|
||||
|
||||
if (_prop_object_internalize_find_tag(ctx, "string",
|
||||
_PROP_TAG_TYPE_END) == false) {
|
||||
_PROP_FREE(str, M_PROP_STRING);
|
||||
return (true);
|
||||
}
|
||||
|
||||
string = _prop_string_alloc();
|
||||
if (string == NULL) {
|
||||
_PROP_FREE(str, M_PROP_STRING);
|
||||
return (true);
|
||||
}
|
||||
|
||||
string->ps_mutable = str;
|
||||
string->ps_size = len;
|
||||
*obj = string;
|
||||
|
||||
return (true);
|
||||
}
|
139
common/lib/libprop/proplib.3
Normal file
139
common/lib/libprop/proplib.3
Normal 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.
|
|
@ -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
|
||||
|
|
|
@ -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
191
lib/libprop/Makefile
Normal 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>
|
4
lib/libprop/shlib_version
Normal file
4
lib/libprop/shlib_version
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
9
nbsd_include/prop/Makefile
Normal file
9
nbsd_include/prop/Makefile
Normal 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>
|
48
nbsd_include/prop/plistref.h
Normal file
48
nbsd_include/prop/plistref.h
Normal 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_ */
|
163
nbsd_include/prop/prop_array.h
Normal file
163
nbsd_include/prop/prop_array.h
Normal 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_ */
|
48
nbsd_include/prop/prop_bool.h
Normal file
48
nbsd_include/prop/prop_bool.h
Normal 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_ */
|
54
nbsd_include/prop/prop_data.h
Normal file
54
nbsd_include/prop/prop_data.h
Normal 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_ */
|
181
nbsd_include/prop/prop_dictionary.h
Normal file
181
nbsd_include/prop/prop_dictionary.h
Normal 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_ */
|
90
nbsd_include/prop/prop_ingest.h
Normal file
90
nbsd_include/prop/prop_ingest.h
Normal 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_ */
|
59
nbsd_include/prop/prop_number.h
Normal file
59
nbsd_include/prop/prop_number.h
Normal 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_ */
|
72
nbsd_include/prop/prop_object.h
Normal file
72
nbsd_include/prop/prop_object.h
Normal 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_ */
|
60
nbsd_include/prop/prop_string.h
Normal file
60
nbsd_include/prop/prop_string.h
Normal 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_ */
|
50
nbsd_include/prop/proplib.h
Normal file
50
nbsd_include/prop/proplib.h
Normal 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_ */
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue