LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/base - string.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 80 93 86.0 %
Date: 2024-04-21 15:09:00 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2010 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  *
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  *
      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             :  * 3. Neither the name of the Institute nor the names of its contributors
      20             :  *    may be used to endorse or promote products derived from this software
      21             :  *    without specific prior written permission.
      22             :  *
      23             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      24             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      25             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      26             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      27             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      28             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      29             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      30             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      31             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      32             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      33             :  * SUCH DAMAGE.
      34             :  */
      35             : 
      36             : #include "baselocl.h"
      37             : #include <string.h>
      38             : 
      39             : static void HEIM_CALLCONV
      40     4805343 : string_dealloc(void *ptr)
      41             : {
      42     4805343 :     heim_string_t s = ptr;
      43      154727 :     heim_string_free_f_t *deallocp;
      44      154727 :     heim_string_free_f_t dealloc;
      45             : 
      46     4805343 :     if (*(const char *)ptr != '\0')
      47     4098991 :         return;
      48             : 
      49             :     /* Possible string ref */
      50      572103 :     deallocp = _heim_get_isaextra(s, 0);
      51      572103 :     dealloc = *deallocp;
      52      572103 :     if (dealloc != NULL) {
      53      572103 :         char **strp = _heim_get_isaextra(s, 1);
      54      572103 :         dealloc(*strp);
      55             :     }
      56             : }
      57             : 
      58             : static int
      59     3258957 : string_cmp(void *a, void *b)
      60             : {
      61     3258957 :     if (*(char *)a == '\0') {
      62           0 :         char **strp = _heim_get_isaextra(a, 1);
      63             : 
      64           0 :         if (*strp != NULL)
      65           0 :             a = *strp; /* a is a string ref */
      66             :     }
      67     3258957 :     if (*(char *)b == '\0') {
      68           0 :         char **strp = _heim_get_isaextra(b, 1);
      69             : 
      70           0 :         if (*strp != NULL)
      71           0 :             b = *strp; /* b is a string ref */
      72             :     }
      73     3258957 :     return strcmp(a, b);
      74             : }
      75             : 
      76             : static uintptr_t
      77     6136414 : string_hash(void *ptr)
      78             : {
      79     6136414 :     const char *s = ptr;
      80      203417 :     uintptr_t n;
      81             : 
      82    57071090 :     for (n = 0; *s; ++s)
      83    50934676 :         n += *s;
      84     6136414 :     return n;
      85             : }
      86             : 
      87             : struct heim_type_data _heim_string_object = {
      88             :     HEIM_TID_STRING,
      89             :     "string-object",
      90             :     NULL,
      91             :     string_dealloc,
      92             :     NULL,
      93             :     string_cmp,
      94             :     string_hash,
      95             :     NULL
      96             : };
      97             : 
      98             : /**
      99             :  * Create a string object
     100             :  *
     101             :  * @param string the string to create, must be an utf8 string
     102             :  *
     103             :  * @return string object
     104             :  */
     105             : 
     106             : heim_string_t
     107     4332110 : heim_string_create(const char *string)
     108             : {
     109     4332110 :     return heim_string_create_with_bytes(string, strlen(string));
     110             : }
     111             : 
     112             : /**
     113             :  * Create a string object without copying the source.
     114             :  *
     115             :  * @param string the string to referenced, must be UTF-8
     116             :  * @param dealloc the function to use to release the referece to the string
     117             :  *
     118             :  * @return string object
     119             :  */
     120             : 
     121             : heim_string_t
     122      572103 : heim_string_ref_create(const char *string, heim_string_free_f_t dealloc)
     123             : {
     124       20478 :     heim_string_t s;
     125       20478 :     heim_string_free_f_t *deallocp;
     126             : 
     127      572103 :     s = _heim_alloc_object(&_heim_string_object, 1);
     128      572103 :     if (s) {
     129       20478 :         const char **strp;
     130             : 
     131      572103 :         ((char *)s)[0] = '\0';
     132      572103 :         deallocp = _heim_get_isaextra(s, 0);
     133      572103 :         *deallocp = dealloc;
     134      572103 :         strp = _heim_get_isaextra(s, 1);
     135      572103 :         *strp = string;
     136             :     }
     137      572103 :     return s;
     138             : }
     139             : 
     140             : /**
     141             :  * Create a string object
     142             :  *
     143             :  * @param string the string to create, must be an utf8 string
     144             :  * @param len the length of the string
     145             :  *
     146             :  * @return string object
     147             :  */
     148             : 
     149             : heim_string_t
     150     4332110 : heim_string_create_with_bytes(const void *data, size_t len)
     151             : {
     152      138063 :     heim_string_t s;
     153             : 
     154     4332110 :     s = _heim_alloc_object(&_heim_string_object, len + 1);
     155     4332110 :     if (s) {
     156     4332110 :         if (len)
     157     4332110 :             memcpy(s, data, len);
     158     4332110 :         ((char *)s)[len] = '\0';
     159             :     }
     160     4332110 :     return s;
     161             : }
     162             : 
     163             : /**
     164             :  * Create a string object using a format string
     165             :  *
     166             :  * @param fmt format string
     167             :  * @param ...
     168             :  *
     169             :  * @return string object
     170             :  */
     171             : 
     172             : heim_string_t
     173           6 : heim_string_create_with_format(const char *fmt, ...)
     174             : {
     175           0 :     heim_string_t s;
     176           6 :     char *str = NULL;
     177           0 :     va_list ap;
     178           0 :     int ret;
     179             : 
     180           6 :     va_start(ap, fmt);
     181           6 :     ret = vasprintf(&str, fmt, ap);
     182           6 :     va_end(ap);
     183           6 :     if (ret < 0 || str == NULL)
     184           0 :         return NULL;
     185             : 
     186           6 :     s = heim_string_ref_create(str, free);
     187           6 :     if (s == NULL)
     188           0 :         free(str);
     189           6 :     return s;
     190             : }
     191             : 
     192             : /**
     193             :  * Return the type ID of string objects
     194             :  *
     195             :  * @return type id of string objects
     196             :  */
     197             : 
     198             : heim_tid_t
     199           0 : heim_string_get_type_id(void)
     200             : {
     201           0 :     return HEIM_TID_STRING;
     202             : }
     203             : 
     204             : /**
     205             :  * Get the string value of the content.
     206             :  *
     207             :  * @param string the string object to get the value from
     208             :  *
     209             :  * @return a utf8 string
     210             :  */
     211             : 
     212             : const char *
     213     2722389 : heim_string_get_utf8(heim_string_t string)
     214             : {
     215     2722389 :     if (*(const char *)string == '\0') {
     216       42126 :         const char **strp;
     217             : 
     218             :         /* String ref */
     219     1174984 :         strp = _heim_get_isaextra(string, 1);
     220     1174984 :         if (*strp != NULL)
     221     1174984 :             return *strp;
     222             :     }
     223     1492212 :     return (const char *)string;
     224             : }
     225             : 
     226             : /*
     227             :  *
     228             :  */
     229             : 
     230             : static void
     231       32887 : init_string(void *ptr)
     232             : {
     233       32887 :     heim_dict_t *dict = ptr;
     234       32887 :     *dict = heim_dict_create(101);
     235       32887 :     heim_assert(*dict != NULL, "__heim_string_constant");
     236       32887 : }
     237             : 
     238             : heim_string_t
     239       33089 : __heim_string_constant(const char *_str)
     240             : {
     241        1282 :     static HEIMDAL_MUTEX mutex = HEIMDAL_MUTEX_INITIALIZER;
     242        1282 :     static heim_base_once_t once = HEIM_BASE_ONCE_INIT;
     243        1282 :     static heim_dict_t dict = NULL;
     244        1282 :     heim_string_t s, s2;
     245             : 
     246       33089 :     heim_base_once_f(&once, &dict, init_string);
     247       33089 :     s = heim_string_create(_str);
     248             : 
     249        1282 :     HEIMDAL_MUTEX_lock(&mutex);
     250       33089 :     s2 = heim_dict_get_value(dict, s);
     251       33089 :     if (s2) {
     252         186 :         heim_release(s);
     253         186 :         s = s2;
     254             :     } else {
     255       32903 :         _heim_make_permanent(s);
     256       32903 :         heim_dict_set_value(dict, s, s);
     257             :     }
     258        1282 :     HEIMDAL_MUTEX_unlock(&mutex);
     259             : 
     260       33089 :     return s;
     261             : }

Generated by: LCOV version 1.14