EAPI Eina_Stringshare *
eina_stringshare_add_length(const char *str, unsigned int slen)
{
   if (!str)
     return NULL;
   else if (slen == 0)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return "";
     }
   else if (slen == 1)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1);
     }
   else if (slen < 4)
     {
        const char *s;

        eina_share_common_population_add(stringshare_share, slen);
        eina_spinlock_take(&_mutex_small);
        s = _eina_stringshare_small_add(str, slen);
        eina_spinlock_release(&_mutex_small);

        return s;
     }

   return eina_share_common_add_length(stringshare_share, str, slen *
                                       sizeof(char), sizeof(char));
}
Exemple #2
0
/**
 * Increment references of the given shared string.
 *
 * @param str The shared string.
 * @return    A pointer to an instance of the string on success.
 *            @c NULL on failure.
 *
 * This is similar to eina_share_common_add(), but it's faster since it will
 * avoid lookups if possible, but on the down side it requires the parameter
 * to be shared before, in other words, it must be the return of a previous
 * eina_share_common_add().
 *
 * There is no unref since this is the work of eina_share_common_del().
 */
EAPI const char *
eina_stringshare_ref(const char *str)
{
   int slen;
   DBG("str=%p (%s)", str, str ? str : "");

   if (!str)
      return eina_share_common_ref(stringshare_share, str);

   /* special cases */
   if      (str[0] == '\0')
      slen = 0;
   else if (str[1] == '\0')
      slen = 1;
   else if (str[2] == '\0')
      slen = 2;
   else if (str[3] == '\0')
      slen = 3;
   else
      slen = 3 + (int)strlen(str + 3);

   if (slen < 2)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return str;
     }
   else if (slen < 4)
     {
        const char *s;
        eina_share_common_population_add(stringshare_share, slen);

        STRINGSHARE_LOCK_SMALL();
        s = _eina_stringshare_small_add(str, slen);
        STRINGSHARE_UNLOCK_SMALL();

        return s;
     }

   return eina_share_common_ref(stringshare_share, str);
}
EAPI Eina_Stringshare *
eina_stringshare_ref(Eina_Stringshare *str)
{
   int slen;

   if (!str)
     return NULL;

   /* special cases */
   if      (str[0] == '\0')
     slen = 0;
   else if (str[1] == '\0')
     slen = 1;
   else if (str[2] == '\0')
     slen = 2;
   else if (str[3] == '\0')
     slen = 3;
   else
     slen = 3 + (int)strlen(str + 3);

   if (slen < 2)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return str;
     }
   else if (slen < 4)
     {
        const char *s;

        eina_share_common_population_add(stringshare_share, slen);
        eina_spinlock_take(&_mutex_small);
        s = _eina_stringshare_small_add(str, slen);
        eina_spinlock_release(&_mutex_small);

        return s;
     }

   return eina_share_common_ref(stringshare_share, str);
}
Exemple #4
0
/**
 * @brief Retrieve an instance of a string for use in a program.
 *
 * @param   str The string to retrieve an instance of.
 * @param   slen The string size (<= strlen(str)).
 * @return  A pointer to an instance of the string on success.
 *          @c NULL on failure.
 *
 * This function retrieves an instance of @p str. If @p str is
 * @c NULL, then @c NULL is returned. If @p str is already stored, it
 * is just returned and its reference counter is increased. Otherwise
 * it is added to the strings to be searched and a duplicated string
 * of @p str is returned.
 *
 * This function does not check string size, but uses the
 * exact given size. This can be used to share_common part of a larger
 * buffer or substring.
 *
 * @see eina_share_common_add()
 */
EAPI const char *
eina_stringshare_add_length(const char *str, unsigned int slen)
{
   DBG("str=%p (%.*s), slen=%u", str, slen, str ? str : "", slen);

   if ((!str) || (slen <= 0))
      return "";
   else if (slen == 1)
      return (const char *)_eina_stringshare_single + ((*str) << 1);
   else if (slen < 4)
     {
        const char *s;

        STRINGSHARE_LOCK_SMALL();
        s = _eina_stringshare_small_add(str, slen);
        STRINGSHARE_UNLOCK_SMALL();
        return s;
     }

   return eina_share_common_add_length(stringshare_share, str, slen *
                                       sizeof(char), sizeof(char));
}