The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libprop/prop_string.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 43b3845b65a86d3bb7ea24adddb04595


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.