LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/base - string.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 56 75 74.7 %
Date: 2024-06-13 04:01:37 Functions: 9 11 81.8 %

          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     3009515 : string_dealloc(void *ptr)
      41             : {
      42     3009515 :     heim_string_t s = ptr;
      43             :     heim_string_free_f_t *deallocp;
      44             :     heim_string_free_f_t dealloc;
      45             : 
      46     3009515 :     if (*(const char *)ptr != '\0')
      47     2626733 :         return;
      48             : 
      49             :     /* Possible string ref */
      50      382782 :     deallocp = _heim_get_isaextra(s, 0);
      51      382782 :     dealloc = *deallocp;
      52      382782 :     if (dealloc != NULL) {
      53      382782 :         char **strp = _heim_get_isaextra(s, 1);
      54      382782 :         dealloc(*strp);
      55             :     }
      56             : }
      57             : 
      58             : static int
      59     1921200 : string_cmp(void *a, void *b)
      60             : {
      61     1921200 :     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     1921200 :     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     1921200 :     return strcmp(a, b);
      74             : }
      75             : 
      76             : static uintptr_t
      77     3801509 : string_hash(void *ptr)
      78             : {
      79     3801509 :     const char *s = ptr;
      80             :     uintptr_t n;
      81             : 
      82    33352522 :     for (n = 0; *s; ++s)
      83    29551013 :         n += *s;
      84     3801509 :     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     2675208 : heim_string_create(const char *string)
     108             : {
     109     2675208 :     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      382782 : heim_string_ref_create(const char *string, heim_string_free_f_t dealloc)
     123             : {
     124             :     heim_string_t s;
     125             :     heim_string_free_f_t *deallocp;
     126             : 
     127      382782 :     s = _heim_alloc_object(&_heim_string_object, 1);
     128      382782 :     if (s) {
     129             :         const char **strp;
     130             : 
     131      382782 :         ((char *)s)[0] = '\0';
     132      382782 :         deallocp = _heim_get_isaextra(s, 0);
     133      382782 :         *deallocp = dealloc;
     134      382782 :         strp = _heim_get_isaextra(s, 1);
     135      382782 :         *strp = string;
     136             :     }
     137      382782 :     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     2675208 : heim_string_create_with_bytes(const void *data, size_t len)
     151             : {
     152             :     heim_string_t s;
     153             : 
     154     2675208 :     s = _heim_alloc_object(&_heim_string_object, len + 1);
     155     2675208 :     if (s) {
     156     2675208 :         memcpy(s, data, len);
     157     2675208 :         ((char *)s)[len] = '\0';
     158             :     }
     159     2675208 :     return s;
     160             : }
     161             : 
     162             : /**
     163             :  * Create a string object using a format string
     164             :  *
     165             :  * @param fmt format string
     166             :  * @param ...
     167             :  *
     168             :  * @return string object
     169             :  */
     170             : 
     171             : heim_string_t
     172           0 : heim_string_create_with_format(const char *fmt, ...)
     173             : {
     174             :     heim_string_t s;
     175           0 :     char *str = NULL;
     176             :     va_list ap;
     177             :     int ret;
     178             : 
     179           0 :     va_start(ap, fmt);
     180           0 :     ret = vasprintf(&str, fmt, ap);
     181           0 :     va_end(ap);
     182           0 :     if (ret < 0 || str == NULL)
     183           0 :         return NULL;
     184             : 
     185           0 :     s = heim_string_ref_create(str, free);
     186           0 :     if (s == NULL)
     187           0 :         free(str);
     188           0 :     return s;
     189             : }
     190             : 
     191             : /**
     192             :  * Return the type ID of string objects
     193             :  *
     194             :  * @return type id of string objects
     195             :  */
     196             : 
     197             : heim_tid_t
     198           0 : heim_string_get_type_id(void)
     199             : {
     200           0 :     return HEIM_TID_STRING;
     201             : }
     202             : 
     203             : /**
     204             :  * Get the string value of the content.
     205             :  *
     206             :  * @param string the string object to get the value from
     207             :  *
     208             :  * @return a utf8 string
     209             :  */
     210             : 
     211             : const char *
     212     1786521 : heim_string_get_utf8(heim_string_t string)
     213             : {
     214     1786521 :     if (*(const char *)string == '\0') {
     215             :         const char **strp;
     216             : 
     217             :         /* String ref */
     218      784285 :         strp = _heim_get_isaextra(string, 1);
     219      784285 :         if (*strp != NULL)
     220      784285 :             return *strp;
     221             :     }
     222     1002236 :     return (const char *)string;
     223             : }
     224             : 
     225             : /*
     226             :  *
     227             :  */
     228             : 
     229             : static void
     230       16111 : init_string(void *ptr)
     231             : {
     232       16111 :     heim_dict_t *dict = ptr;
     233       16111 :     *dict = heim_dict_create(101);
     234       16111 :     heim_assert(*dict != NULL, "__heim_string_constant");
     235       16111 : }
     236             : 
     237             : heim_string_t
     238       16253 : __heim_string_constant(const char *_str)
     239             : {
     240             :     static HEIMDAL_MUTEX mutex = HEIMDAL_MUTEX_INITIALIZER;
     241             :     static heim_base_once_t once;
     242             :     static heim_dict_t dict = NULL;
     243             :     heim_string_t s, s2;
     244             : 
     245       16253 :     heim_base_once_f(&once, &dict, init_string);
     246       16253 :     s = heim_string_create(_str);
     247             : 
     248             :     HEIMDAL_MUTEX_lock(&mutex);
     249       16253 :     s2 = heim_dict_get_value(dict, s);
     250       16253 :     if (s2) {
     251         142 :         heim_release(s);
     252         142 :         s = s2;
     253             :     } else {
     254       16111 :         _heim_make_permanent(s);
     255       16111 :         heim_dict_set_value(dict, s, s);
     256             :     }
     257             :     HEIMDAL_MUTEX_unlock(&mutex);
     258             : 
     259       16253 :     return s;
     260             : }

Generated by: LCOV version 1.13