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)); }
/** * 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); }
/** * @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)); }