/*	$NetBSD: prop_object_impl.h,v 1.12 2007/03/12 18:18:39 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the NetBSD
 *      Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 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_system_impl.h"

_PROP_MALLOC_DECLARE(M_PROP_ARRAY)
_PROP_MALLOC_DECLARE(M_PROP_DATA)
_PROP_MALLOC_DECLARE(M_PROP_DICT)
_PROP_MALLOC_DECLARE(M_PROP_STRING)

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 */
};

boolean_t	_prop_object_externalize_append_cstring(
				struct _prop_object_externalize_context *,
				const char *);
boolean_t	_prop_object_externalize_append_char(
				struct _prop_object_externalize_context *,
				unsigned char);

struct _prop_object_externalize_context *
		_prop_object_externalize_context_alloc(void);
void		_prop_object_externalize_context_free(
				struct _prop_object_externalize_context *);

#if !defined(_KERNEL) && !defined(_STANDALONE)
boolean_t	_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 */

struct _prop_object_type {
	uint32_t	pot_type;		/* type indicator */
	void		(*pot_free)(void *);	/* func to free object */
	boolean_t	(*pot_equals)		/* func to test quality */
			    (void *, 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;
};

#ifdef _STANDALONE
#define	_PROP_BUF_EXPAND 	32
#else
#define	_PROP_BUF_EXPAND 	256
#endif

#define	_PROP_PDK_MAXKEY	128

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 */

struct _prop_dictionary {
	struct _prop_object	pd_obj;
	_PROP_RWLOCK_DECL(pd_rwlock)
	struct _prop_dict_entry	*pd_array;
	unsigned int		pd_capacity;
	unsigned int		pd_count;
	int			pd_flags;

	uint32_t		pd_version;
};

#define	PD_F_IMMUTABLE		0x01	/* dictionary is immutable */

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

struct _prop_number_value {
	union {
		int64_t  pnu_signed;
		uint64_t pnu_unsigned;
	} pnv_un;
#define	pnv_signed	pnv_un.pnu_signed
#define	pnv_unsigned	pnv_un.pnu_unsigned
	unsigned int	pnv_is_unsigned	:1,
					:31;
};

struct _prop_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

struct _prop_data 	*_prop_data_alloc(void);
struct _prop_number 	*_prop_number_alloc(const struct _prop_number_value *);
struct _prop_string 	*_prop_string_alloc(void);

#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */
