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