Home | History | Annotate | Line # | Download | only in libprop
prop_string.c revision 1.6.12.1
      1  1.6.12.1  wrstuden /*	$NetBSD: prop_string.c,v 1.6.12.1 2007/09/30 03:38:50 wrstuden Exp $	*/
      2       1.1   thorpej 
      3       1.1   thorpej /*-
      4       1.1   thorpej  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5       1.1   thorpej  * All rights reserved.
      6       1.1   thorpej  *
      7       1.1   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1   thorpej  * by Jason R. Thorpe.
      9       1.1   thorpej  *
     10       1.1   thorpej  * Redistribution and use in source and binary forms, with or without
     11       1.1   thorpej  * modification, are permitted provided that the following conditions
     12       1.1   thorpej  * are met:
     13       1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     14       1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     15       1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     17       1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     18       1.1   thorpej  * 3. All advertising materials mentioning features or use of this software
     19       1.1   thorpej  *    must display the following acknowledgement:
     20       1.1   thorpej  *      This product includes software developed by the NetBSD
     21       1.1   thorpej  *      Foundation, Inc. and its contributors.
     22       1.1   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23       1.1   thorpej  *    contributors may be used to endorse or promote products derived
     24       1.1   thorpej  *    from this software without specific prior written permission.
     25       1.1   thorpej  *
     26       1.1   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27       1.1   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28       1.1   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29       1.1   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30       1.1   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31       1.1   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32       1.1   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33       1.1   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34       1.1   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35       1.1   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36       1.1   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     37       1.1   thorpej  */
     38       1.1   thorpej 
     39       1.1   thorpej #include <prop/prop_string.h>
     40       1.1   thorpej #include "prop_object_impl.h"
     41       1.1   thorpej 
     42       1.1   thorpej struct _prop_string {
     43       1.1   thorpej 	struct _prop_object	ps_obj;
     44       1.1   thorpej 	union {
     45       1.1   thorpej 		char *		psu_mutable;
     46       1.1   thorpej 		const char *	psu_immutable;
     47       1.1   thorpej 	} ps_un;
     48       1.1   thorpej #define	ps_mutable		ps_un.psu_mutable
     49       1.1   thorpej #define	ps_immutable		ps_un.psu_immutable
     50       1.1   thorpej 	size_t			ps_size;	/* not including \0 */
     51       1.1   thorpej 	int			ps_flags;
     52       1.1   thorpej };
     53       1.1   thorpej 
     54       1.1   thorpej #define	PS_F_NOCOPY		0x01
     55       1.1   thorpej 
     56       1.1   thorpej _PROP_POOL_INIT(_prop_string_pool, sizeof(struct _prop_string), "propstng")
     57       1.1   thorpej 
     58       1.1   thorpej _PROP_MALLOC_DEFINE(M_PROP_STRING, "prop string",
     59       1.1   thorpej 		    "property string container object")
     60       1.1   thorpej 
     61  1.6.12.1  wrstuden static int		_prop_string_free(prop_stack_t, prop_object_t *);
     62  1.6.12.1  wrstuden static bool	_prop_string_externalize(
     63       1.2   thorpej 				struct _prop_object_externalize_context *,
     64       1.2   thorpej 				void *);
     65  1.6.12.1  wrstuden static bool	_prop_string_equals(prop_object_t, prop_object_t,
     66  1.6.12.1  wrstuden 				void **, void **,
     67  1.6.12.1  wrstuden 				prop_object_t *, prop_object_t *);
     68       1.2   thorpej 
     69       1.2   thorpej static const struct _prop_object_type _prop_object_type_string = {
     70       1.2   thorpej 	.pot_type	=	PROP_TYPE_STRING,
     71       1.2   thorpej 	.pot_free	=	_prop_string_free,
     72       1.2   thorpej 	.pot_extern	=	_prop_string_externalize,
     73       1.2   thorpej 	.pot_equals	=	_prop_string_equals,
     74       1.2   thorpej };
     75       1.2   thorpej 
     76       1.2   thorpej #define	prop_object_is_string(x)	\
     77       1.4   thorpej 	((x) != NULL && (x)->ps_obj.po_type == &_prop_object_type_string)
     78       1.1   thorpej #define	prop_string_contents(x)  ((x)->ps_immutable ? (x)->ps_immutable : "")
     79       1.1   thorpej 
     80  1.6.12.1  wrstuden /* ARGSUSED */
     81  1.6.12.1  wrstuden static int
     82  1.6.12.1  wrstuden _prop_string_free(prop_stack_t stack, prop_object_t *obj)
     83       1.1   thorpej {
     84  1.6.12.1  wrstuden 	prop_string_t ps = *obj;
     85       1.1   thorpej 
     86       1.1   thorpej 	if ((ps->ps_flags & PS_F_NOCOPY) == 0 && ps->ps_mutable != NULL)
     87       1.1   thorpej 	    	_PROP_FREE(ps->ps_mutable, M_PROP_STRING);
     88  1.6.12.1  wrstuden 	_PROP_POOL_PUT(_prop_string_pool, ps);
     89  1.6.12.1  wrstuden 
     90  1.6.12.1  wrstuden 	return (_PROP_OBJECT_FREE_DONE);
     91       1.1   thorpej }
     92       1.1   thorpej 
     93  1.6.12.1  wrstuden static bool
     94       1.1   thorpej _prop_string_externalize(struct _prop_object_externalize_context *ctx,
     95       1.1   thorpej 			 void *v)
     96       1.1   thorpej {
     97       1.1   thorpej 	prop_string_t ps = v;
     98       1.1   thorpej 
     99       1.1   thorpej 	if (ps->ps_size == 0)
    100       1.1   thorpej 		return (_prop_object_externalize_empty_tag(ctx, "string"));
    101       1.1   thorpej 
    102  1.6.12.1  wrstuden 	if (_prop_object_externalize_start_tag(ctx, "string") == false ||
    103       1.1   thorpej 	    _prop_object_externalize_append_encoded_cstring(ctx,
    104  1.6.12.1  wrstuden 	    					ps->ps_immutable) == false ||
    105  1.6.12.1  wrstuden 	    _prop_object_externalize_end_tag(ctx, "string") == false)
    106  1.6.12.1  wrstuden 		return (false);
    107       1.1   thorpej 
    108  1.6.12.1  wrstuden 	return (true);
    109       1.1   thorpej }
    110       1.1   thorpej 
    111  1.6.12.1  wrstuden /* ARGSUSED */
    112  1.6.12.1  wrstuden static bool
    113  1.6.12.1  wrstuden _prop_string_equals(prop_object_t v1, prop_object_t v2,
    114  1.6.12.1  wrstuden     void **stored_pointer1, void **stored_pointer2,
    115  1.6.12.1  wrstuden     prop_object_t *next_obj1, prop_object_t *next_obj2)
    116       1.2   thorpej {
    117       1.2   thorpej 	prop_string_t str1 = v1;
    118       1.2   thorpej 	prop_string_t str2 = v2;
    119       1.2   thorpej 
    120       1.2   thorpej 	if (str1 == str2)
    121  1.6.12.1  wrstuden 		return (_PROP_OBJECT_EQUALS_TRUE);
    122       1.2   thorpej 	if (str1->ps_size != str2->ps_size)
    123  1.6.12.1  wrstuden 		return (_PROP_OBJECT_EQUALS_FALSE);
    124  1.6.12.1  wrstuden 	if (strcmp(prop_string_contents(str1), prop_string_contents(str2)))
    125  1.6.12.1  wrstuden 		return (_PROP_OBJECT_EQUALS_FALSE);
    126  1.6.12.1  wrstuden 	else
    127  1.6.12.1  wrstuden 		return (_PROP_OBJECT_EQUALS_TRUE);
    128       1.2   thorpej }
    129       1.2   thorpej 
    130       1.1   thorpej static prop_string_t
    131       1.1   thorpej _prop_string_alloc(void)
    132       1.1   thorpej {
    133       1.1   thorpej 	prop_string_t ps;
    134       1.1   thorpej 
    135       1.1   thorpej 	ps = _PROP_POOL_GET(_prop_string_pool);
    136       1.1   thorpej 	if (ps != NULL) {
    137       1.2   thorpej 		_prop_object_init(&ps->ps_obj, &_prop_object_type_string);
    138       1.1   thorpej 
    139       1.1   thorpej 		ps->ps_mutable = NULL;
    140       1.1   thorpej 		ps->ps_size = 0;
    141       1.1   thorpej 		ps->ps_flags = 0;
    142       1.1   thorpej 	}
    143       1.1   thorpej 
    144       1.1   thorpej 	return (ps);
    145       1.1   thorpej }
    146       1.1   thorpej 
    147       1.1   thorpej /*
    148       1.1   thorpej  * prop_string_create --
    149       1.1   thorpej  *	Create an empty mutable string.
    150       1.1   thorpej  */
    151       1.1   thorpej prop_string_t
    152       1.1   thorpej prop_string_create(void)
    153       1.1   thorpej {
    154       1.1   thorpej 
    155       1.1   thorpej 	return (_prop_string_alloc());
    156       1.1   thorpej }
    157       1.1   thorpej 
    158       1.1   thorpej /*
    159       1.1   thorpej  * prop_string_create_cstring --
    160       1.1   thorpej  *	Create a string that contains a copy of the provided C string.
    161       1.1   thorpej  */
    162       1.1   thorpej prop_string_t
    163       1.1   thorpej prop_string_create_cstring(const char *str)
    164       1.1   thorpej {
    165       1.1   thorpej 	prop_string_t ps;
    166       1.1   thorpej 	char *cp;
    167       1.1   thorpej 	size_t len;
    168       1.1   thorpej 
    169       1.1   thorpej 	ps = _prop_string_alloc();
    170       1.1   thorpej 	if (ps != NULL) {
    171       1.1   thorpej 		len = strlen(str);
    172       1.1   thorpej 		cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
    173       1.1   thorpej 		if (cp == NULL) {
    174  1.6.12.1  wrstuden 			prop_object_release(ps);
    175       1.1   thorpej 			return (NULL);
    176       1.1   thorpej 		}
    177       1.1   thorpej 		strcpy(cp, str);
    178       1.1   thorpej 		ps->ps_mutable = cp;
    179       1.1   thorpej 		ps->ps_size = len;
    180       1.1   thorpej 	}
    181       1.1   thorpej 	return (ps);
    182       1.1   thorpej }
    183       1.1   thorpej 
    184       1.1   thorpej /*
    185       1.1   thorpej  * prop_string_create_cstring_nocopy --
    186       1.1   thorpej  *	Create an immutable string that contains a refrence to the
    187       1.1   thorpej  *	provided C string.
    188       1.1   thorpej  */
    189       1.1   thorpej prop_string_t
    190       1.1   thorpej prop_string_create_cstring_nocopy(const char *str)
    191       1.1   thorpej {
    192       1.1   thorpej 	prop_string_t ps;
    193       1.1   thorpej 
    194       1.1   thorpej 	ps = _prop_string_alloc();
    195       1.1   thorpej 	if (ps != NULL) {
    196       1.1   thorpej 		ps->ps_immutable = str;
    197       1.1   thorpej 		ps->ps_size = strlen(str);
    198       1.1   thorpej 		ps->ps_flags |= PS_F_NOCOPY;
    199       1.1   thorpej 	}
    200       1.1   thorpej 	return (ps);
    201       1.1   thorpej }
    202       1.1   thorpej 
    203       1.1   thorpej /*
    204       1.1   thorpej  * prop_string_copy --
    205       1.1   thorpej  *	Copy a string.  If the original string is immutable, then the
    206       1.1   thorpej  *	copy is also immutable and references the same external data.
    207       1.1   thorpej  */
    208       1.1   thorpej prop_string_t
    209       1.1   thorpej prop_string_copy(prop_string_t ops)
    210       1.1   thorpej {
    211       1.1   thorpej 	prop_string_t ps;
    212       1.1   thorpej 
    213       1.3   thorpej 	if (! prop_object_is_string(ops))
    214       1.3   thorpej 		return (NULL);
    215       1.1   thorpej 
    216       1.1   thorpej 	ps = _prop_string_alloc();
    217       1.1   thorpej 	if (ps != NULL) {
    218       1.1   thorpej 		ps->ps_size = ops->ps_size;
    219       1.1   thorpej 		ps->ps_flags = ops->ps_flags;
    220       1.1   thorpej 		if (ops->ps_flags & PS_F_NOCOPY)
    221       1.1   thorpej 			ps->ps_immutable = ops->ps_immutable;
    222       1.1   thorpej 		else {
    223       1.1   thorpej 			char *cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
    224       1.1   thorpej 			if (cp == NULL) {
    225  1.6.12.1  wrstuden 				prop_object_release(ps);
    226       1.1   thorpej 				return (NULL);
    227       1.1   thorpej 			}
    228       1.1   thorpej 			strcpy(cp, prop_string_contents(ops));
    229       1.1   thorpej 			ps->ps_mutable = cp;
    230       1.1   thorpej 		}
    231       1.1   thorpej 	}
    232       1.1   thorpej 	return (ps);
    233       1.1   thorpej }
    234       1.1   thorpej 
    235       1.1   thorpej /*
    236       1.1   thorpej  * prop_string_copy_mutable --
    237       1.1   thorpej  *	Copy a string, always returning a mutable copy.
    238       1.1   thorpej  */
    239       1.1   thorpej prop_string_t
    240       1.1   thorpej prop_string_copy_mutable(prop_string_t ops)
    241       1.1   thorpej {
    242       1.1   thorpej 	prop_string_t ps;
    243       1.1   thorpej 	char *cp;
    244       1.1   thorpej 
    245       1.3   thorpej 	if (! prop_object_is_string(ops))
    246       1.3   thorpej 		return (NULL);
    247       1.1   thorpej 
    248       1.1   thorpej 	ps = _prop_string_alloc();
    249       1.1   thorpej 	if (ps != NULL) {
    250       1.1   thorpej 		ps->ps_size = ops->ps_size;
    251       1.1   thorpej 		cp = _PROP_MALLOC(ps->ps_size + 1, M_PROP_STRING);
    252       1.1   thorpej 		if (cp == NULL) {
    253  1.6.12.1  wrstuden 			prop_object_release(ps);
    254       1.1   thorpej 			return (NULL);
    255       1.1   thorpej 		}
    256       1.1   thorpej 		strcpy(cp, prop_string_contents(ops));
    257       1.1   thorpej 		ps->ps_mutable = cp;
    258       1.1   thorpej 	}
    259       1.1   thorpej 	return (ps);
    260       1.1   thorpej }
    261       1.1   thorpej 
    262       1.1   thorpej /*
    263       1.1   thorpej  * prop_string_size --
    264       1.3   thorpej  *	Return the size of the string, not including the terminating NUL.
    265       1.1   thorpej  */
    266       1.1   thorpej size_t
    267       1.1   thorpej prop_string_size(prop_string_t ps)
    268       1.1   thorpej {
    269       1.1   thorpej 
    270       1.3   thorpej 	if (! prop_object_is_string(ps))
    271       1.3   thorpej 		return (0);
    272       1.3   thorpej 
    273       1.1   thorpej 	return (ps->ps_size);
    274       1.1   thorpej }
    275       1.1   thorpej 
    276       1.1   thorpej /*
    277       1.1   thorpej  * prop_string_mutable --
    278  1.6.12.1  wrstuden  *	Return true if the string is a mutable string.
    279       1.1   thorpej  */
    280  1.6.12.1  wrstuden bool
    281       1.1   thorpej prop_string_mutable(prop_string_t ps)
    282       1.1   thorpej {
    283       1.1   thorpej 
    284       1.3   thorpej 	if (! prop_object_is_string(ps))
    285  1.6.12.1  wrstuden 		return (false);
    286       1.3   thorpej 
    287       1.1   thorpej 	return ((ps->ps_flags & PS_F_NOCOPY) == 0);
    288       1.1   thorpej }
    289       1.1   thorpej 
    290       1.1   thorpej /*
    291       1.1   thorpej  * prop_string_cstring --
    292       1.1   thorpej  *	Return a copy of the contents of the string as a C string.
    293       1.1   thorpej  *	The string is allocated with the M_TEMP malloc type.
    294       1.1   thorpej  */
    295       1.1   thorpej char *
    296       1.1   thorpej prop_string_cstring(prop_string_t ps)
    297       1.1   thorpej {
    298       1.1   thorpej 	char *cp;
    299       1.1   thorpej 
    300       1.3   thorpej 	if (! prop_object_is_string(ps))
    301       1.3   thorpej 		return (NULL);
    302       1.3   thorpej 
    303       1.1   thorpej 	cp = _PROP_MALLOC(ps->ps_size + 1, M_TEMP);
    304       1.1   thorpej 	if (cp != NULL)
    305       1.1   thorpej 		strcpy(cp, prop_string_contents(ps));
    306       1.1   thorpej 
    307       1.1   thorpej 	return (cp);
    308       1.1   thorpej }
    309       1.1   thorpej 
    310       1.1   thorpej /*
    311       1.1   thorpej  * prop_string_cstring_nocopy --
    312       1.1   thorpej  *	Return an immutable reference to the contents of the string
    313       1.1   thorpej  *	as a C string.
    314       1.1   thorpej  */
    315       1.1   thorpej const char *
    316       1.1   thorpej prop_string_cstring_nocopy(prop_string_t ps)
    317       1.1   thorpej {
    318       1.1   thorpej 
    319       1.3   thorpej 	if (! prop_object_is_string(ps))
    320       1.3   thorpej 		return (NULL);
    321       1.3   thorpej 
    322       1.1   thorpej 	return (prop_string_contents(ps));
    323       1.1   thorpej }
    324       1.1   thorpej 
    325       1.1   thorpej /*
    326       1.1   thorpej  * prop_string_append --
    327  1.6.12.1  wrstuden  *	Append the contents of one string to another.  Returns true
    328       1.1   thorpej  *	upon success.  The destination string must be mutable.
    329       1.1   thorpej  */
    330  1.6.12.1  wrstuden bool
    331       1.1   thorpej prop_string_append(prop_string_t dst, prop_string_t src)
    332       1.1   thorpej {
    333       1.1   thorpej 	char *ocp, *cp;
    334       1.1   thorpej 	size_t len;
    335       1.1   thorpej 
    336       1.3   thorpej 	if (! (prop_object_is_string(dst) &&
    337       1.3   thorpej 	       prop_object_is_string(src)))
    338  1.6.12.1  wrstuden 		return (false);
    339       1.1   thorpej 
    340       1.1   thorpej 	if (dst->ps_flags & PS_F_NOCOPY)
    341  1.6.12.1  wrstuden 		return (false);
    342       1.1   thorpej 
    343       1.1   thorpej 	len = dst->ps_size + src->ps_size;
    344       1.1   thorpej 	cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
    345       1.1   thorpej 	if (cp == NULL)
    346  1.6.12.1  wrstuden 		return (false);
    347       1.1   thorpej 	sprintf(cp, "%s%s", prop_string_contents(dst),
    348       1.1   thorpej 		prop_string_contents(src));
    349       1.1   thorpej 	ocp = dst->ps_mutable;
    350       1.1   thorpej 	dst->ps_mutable = cp;
    351       1.1   thorpej 	dst->ps_size = len;
    352       1.1   thorpej 	if (ocp != NULL)
    353       1.1   thorpej 		_PROP_FREE(ocp, M_PROP_STRING);
    354       1.1   thorpej 
    355  1.6.12.1  wrstuden 	return (true);
    356       1.1   thorpej }
    357       1.1   thorpej 
    358       1.1   thorpej /*
    359       1.1   thorpej  * prop_string_append_cstring --
    360  1.6.12.1  wrstuden  *	Append a C string to a string.  Returns true upon success.
    361       1.1   thorpej  *	The destination string must be mutable.
    362       1.1   thorpej  */
    363  1.6.12.1  wrstuden bool
    364       1.1   thorpej prop_string_append_cstring(prop_string_t dst, const char *src)
    365       1.1   thorpej {
    366       1.1   thorpej 	char *ocp, *cp;
    367       1.1   thorpej 	size_t len;
    368       1.1   thorpej 
    369       1.3   thorpej 	if (! prop_object_is_string(dst))
    370  1.6.12.1  wrstuden 		return (false);
    371       1.3   thorpej 
    372       1.1   thorpej 	_PROP_ASSERT(src != NULL);
    373       1.1   thorpej 
    374       1.1   thorpej 	if (dst->ps_flags & PS_F_NOCOPY)
    375  1.6.12.1  wrstuden 		return (false);
    376       1.1   thorpej 
    377       1.1   thorpej 	len = dst->ps_size + strlen(src);
    378       1.1   thorpej 	cp = _PROP_MALLOC(len + 1, M_PROP_STRING);
    379       1.1   thorpej 	if (cp == NULL)
    380  1.6.12.1  wrstuden 		return (false);
    381       1.1   thorpej 	sprintf(cp, "%s%s", prop_string_contents(dst), src);
    382       1.1   thorpej 	ocp = dst->ps_mutable;
    383       1.1   thorpej 	dst->ps_mutable = cp;
    384       1.1   thorpej 	dst->ps_size = len;
    385       1.1   thorpej 	if (ocp != NULL)
    386       1.1   thorpej 		_PROP_FREE(ocp, M_PROP_STRING);
    387       1.1   thorpej 
    388  1.6.12.1  wrstuden 	return (true);
    389       1.1   thorpej }
    390       1.1   thorpej 
    391       1.1   thorpej /*
    392       1.1   thorpej  * prop_string_equals --
    393  1.6.12.1  wrstuden  *	Return true if two strings are equivalent.
    394       1.1   thorpej  */
    395  1.6.12.1  wrstuden bool
    396       1.1   thorpej prop_string_equals(prop_string_t str1, prop_string_t str2)
    397       1.1   thorpej {
    398  1.6.12.1  wrstuden 	if (!prop_object_is_string(str1) || !prop_object_is_string(str2))
    399  1.6.12.1  wrstuden 		return (false);
    400       1.1   thorpej 
    401  1.6.12.1  wrstuden 	return prop_object_equals(str1, str2);
    402       1.1   thorpej }
    403       1.1   thorpej 
    404       1.1   thorpej /*
    405       1.1   thorpej  * prop_string_equals_cstring --
    406  1.6.12.1  wrstuden  *	Return true if the string is equivalent to the specified
    407       1.1   thorpej  *	C string.
    408       1.1   thorpej  */
    409  1.6.12.1  wrstuden bool
    410       1.1   thorpej prop_string_equals_cstring(prop_string_t ps, const char *cp)
    411       1.1   thorpej {
    412       1.1   thorpej 
    413       1.3   thorpej 	if (! prop_object_is_string(ps))
    414  1.6.12.1  wrstuden 		return (false);
    415       1.3   thorpej 
    416       1.1   thorpej 	return (strcmp(prop_string_contents(ps), cp) == 0);
    417       1.1   thorpej }
    418       1.1   thorpej 
    419       1.1   thorpej /*
    420       1.1   thorpej  * _prop_string_internalize --
    421       1.1   thorpej  *	Parse a <string>...</string> and return the object created from the
    422       1.1   thorpej  *	external representation.
    423       1.1   thorpej  */
    424  1.6.12.1  wrstuden /* ARGSUSED */
    425  1.6.12.1  wrstuden bool
    426  1.6.12.1  wrstuden _prop_string_internalize(prop_stack_t stack, prop_object_t *obj,
    427  1.6.12.1  wrstuden     struct _prop_object_internalize_context *ctx)
    428       1.1   thorpej {
    429       1.1   thorpej 	prop_string_t string;
    430       1.1   thorpej 	char *str;
    431       1.1   thorpej 	size_t len, alen;
    432       1.1   thorpej 
    433  1.6.12.1  wrstuden 	if (ctx->poic_is_empty_element) {
    434  1.6.12.1  wrstuden 		*obj = prop_string_create();
    435  1.6.12.1  wrstuden 		return (true);
    436  1.6.12.1  wrstuden 	}
    437       1.1   thorpej 
    438       1.1   thorpej 	/* No attributes recognized here. */
    439       1.1   thorpej 	if (ctx->poic_tagattr != NULL)
    440  1.6.12.1  wrstuden 		return (true);
    441       1.1   thorpej 
    442       1.1   thorpej 	/* Compute the length of the result. */
    443       1.6    martin 	if (_prop_object_internalize_decode_string(ctx, NULL, 0, &len,
    444  1.6.12.1  wrstuden 						   NULL) == false)
    445  1.6.12.1  wrstuden 		return (true);
    446       1.1   thorpej 
    447       1.1   thorpej 	str = _PROP_MALLOC(len + 1, M_PROP_STRING);
    448       1.1   thorpej 	if (str == NULL)
    449  1.6.12.1  wrstuden 		return (true);
    450       1.1   thorpej 
    451       1.1   thorpej 	if (_prop_object_internalize_decode_string(ctx, str, len, &alen,
    452  1.6.12.1  wrstuden 						   &ctx->poic_cp) == false ||
    453       1.1   thorpej 	    alen != len) {
    454       1.1   thorpej 		_PROP_FREE(str, M_PROP_STRING);
    455  1.6.12.1  wrstuden 		return (true);
    456       1.1   thorpej 	}
    457       1.1   thorpej 	str[len] = '\0';
    458       1.1   thorpej 
    459       1.1   thorpej 	if (_prop_object_internalize_find_tag(ctx, "string",
    460  1.6.12.1  wrstuden 					      _PROP_TAG_TYPE_END) == false) {
    461       1.1   thorpej 		_PROP_FREE(str, M_PROP_STRING);
    462  1.6.12.1  wrstuden 		return (true);
    463       1.1   thorpej 	}
    464       1.1   thorpej 
    465       1.1   thorpej 	string = _prop_string_alloc();
    466       1.1   thorpej 	if (string == NULL) {
    467       1.1   thorpej 		_PROP_FREE(str, M_PROP_STRING);
    468  1.6.12.1  wrstuden 		return (true);
    469       1.1   thorpej 	}
    470       1.1   thorpej 
    471       1.1   thorpej 	string->ps_mutable = str;
    472       1.1   thorpej 	string->ps_size = len;
    473  1.6.12.1  wrstuden 	*obj = string;
    474       1.1   thorpej 
    475  1.6.12.1  wrstuden 	return (true);
    476       1.1   thorpej }
    477