libs/utils/include/celix_utils.h (54 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef CELIX_UTILS_H_
#define CELIX_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h>
#include <stdarg.h>
#include <stdbool.h>
#include "celix_utils_export.h"
#include "celix_compiler.h"
#include "celix_cleanup.h"
#define CELIX_US_IN_SEC (1000000)
#define CELIX_NS_IN_SEC ((CELIX_US_IN_SEC)*1000)
/**
* Creates a copy of a provided string.
* The strdup is limited to the CELIX_UTILS_MAX_STRLEN and uses strndup to achieve this.
* @return a copy of the string (including null terminator).
*/
CELIX_UTILS_EXPORT char* celix_utils_strdup(const char *str);
/**
* Returns the length of the provided string with a max of CELIX_UTILS_MAX_STRLEN.
* @param str The string to get the length from.
* @return The length of the string or 0 if the string is NULL.
*/
CELIX_UTILS_EXPORT size_t celix_utils_strlen(const char *str);
/**
* @brief Creates a hash from a string
* @param string
* @return hash
*/
CELIX_UTILS_EXPORT unsigned int celix_utils_stringHash(const char* string);
/**
* The proposed buffer size to use for celix_utils_writeOrCreateString with a buffer on the stcck.
*/
#define CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE 512
/**`
* @brief Format a string to the provided buffer or a newly allocated buffer if the provided buffer is to small.
* @param[in,out] buffer The buffer to write the formatted string to.
* @param[in] bufferSize The size of the buffer.
* @param[in] format The format string.
* @param[in] ... The arguments for the format string.
* @return The formatted string in the provided buffer or a newly allocated buffer if the provided buffer is to small.
* @retval NULL if a allocation was needed, but failed.
*/
CELIX_UTILS_EXPORT char* celix_utils_writeOrCreateString(char* buffer, size_t bufferSize, const char* format, ...)
__attribute__((format(printf, 3, 4)));
/**
* @brief Format a string to the provided buffer or a newly allocated buffer if the provided buffer is to small.
* @param[in,out] buffer The buffer to write the formatted string to.
* @param[in] bufferSize The size of the buffer.
* @param[in] format The format string.
* @param[in] formatArgs The arguments for the format string.
* @return The formatted string in the provided buffer or a newly allocated buffer if the provided buffer is to small.
* @retval NULL if a allocation was needed, but failed.
*/
CELIX_UTILS_EXPORT char* celix_utils_writeOrCreateVString(char* buffer, size_t bufferSize, const char* format, va_list formatArgs)
__attribute__((format(printf, 3, 0)));
/**
* @brief Free the provided str if the str is not equal to the provided buffer.
* @note This function is useful combined with celix_utils_writeOrCreateString.
* @param buffer The buffer to compare the str to.
* @param str The string to free if it is not equal to the buffer.
*/
CELIX_UTILS_EXPORT void celix_utils_freeStringIfNotEqual(const char* buffer, char* str);
/**
* @brief Guard for a string created with celix_utils_writeOrCreateString, celix_utils_writeOrCreateVString.
*
* Can be used with celix_auto() to automatically and correctly free the string.
* If the string is pointing to the buffer, the string should not be freed, otherwise the string should be freed.
*/
typedef struct celix_utils_string_guard {
const char* buffer;
char* string;
} celix_utils_string_guard_t;
/**
* @brief Initialize a guard for a string created with celix_utils_writeOrCreateString or
* celix_utils_writeOrCreateVString.
*
* De-initialize with celix_utils_stringGuard_deinit().
*
* No allocation is performed.
* This is intended to be used with celix_auto().
*
* * Example:
* ```
* const char* possibleLongString = ...
* char buffer[64];
* char* str = celix_utils_writeOrCreateString(buffer, sizeof(buffer), "Hello %s", possibleLongString);
* celix_auto(celix_utils_string_guard_t) strGuard = celix_utils_stringGuard_init(buffer, str);
* ```
* If the strGuard goes out of scope, the string will be freed correctly.
*
* @param buffer A (local) buffer which was potentially used to create the string.
* @param string The string to guard.
* @return An initialized string guard to be used with celix_auto().
*/
static CELIX_UNUSED inline celix_utils_string_guard_t celix_utils_stringGuard_init(const char* buffer, char* string) {
celix_utils_string_guard_t guard;
guard.buffer = buffer;
guard.string = string;
return guard;
}
/**
* @brief De-initialize a string guard.
*
* This will free the string if it is not equal to the buffer.
* This is intended to be used with celix_auto().
*
* @param guard The guard to de-initialize.
*/
static CELIX_UNUSED inline void celix_utils_stringGuard_deinit(celix_utils_string_guard_t* guard) {
celix_utils_freeStringIfNotEqual(guard->buffer, guard->string);
}
CELIX_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(celix_utils_string_guard_t, celix_utils_stringGuard_deinit)
/**
* @brief Compares two strings and returns true if the strings are equal.
*/
CELIX_UTILS_EXPORT bool celix_utils_stringEquals(const char* a, const char* b);
/**
* Check if the provided string contains a whitespace (spaces, tabs, etc).
* The check is based on `isspace`.
*/
CELIX_UTILS_EXPORT bool celix_utils_containsWhitespace(const char* s);
/**
* @brief Returns a trimmed string.
*
* This function will remove any leading and trailing whitespaces (' ', '\t', etc based on isspace) from the
* input string.
*
* @param[in] string The input string to be trimmed.
* @return A trimmed version of the input string. The caller is responsible for freeing the memory of this string.
*/
CELIX_UTILS_EXPORT char* celix_utils_trim(const char* string);
/**
* @brief Trims the provided string in place.
*
* The trim will remove any leading and trailing whitespaces (' ', '\t', etc based on `isspace`)/
* @param string the string to be trimmed.
* @return string.
*/
CELIX_UTILS_EXPORT char* celix_utils_trimInPlace(char* string);
/**
* @brief Check if a string is NULL or empty "".
*/
CELIX_UTILS_EXPORT bool celix_utils_isStringNullOrEmpty(const char* s);
/** @brief create a C identifier from the provided string by replacing each non-alphanumeric character with a
* underscore.
*
* If the first character is a digit, a prefix underscore will also be added.
* Will return NULL if the input is NULL or an empty string.
*
* @param string the input string to make a C identifier for.
* @return new newly allocated string or NULL if the input was wrong. The caller is owner of the returned string.
*/
CELIX_UTILS_EXPORT char* celix_utils_makeCIdentifier(const char* s);
/**
* @brief Extract a local name and namespace from a fully qualified name using the provided namespace separator.
* so fully qualified name = celix::extra::lb, namespace separator = "::" -> local name = lb, namespace = celix::extra
*
* Note that if no namespace is present the output for namespace will be NULL.
*
* @param fullyQualifiedName The fully qualified name to split
* @param namespaceSeparator The namespace separator
* @param outLocalName A output argument for the local name part. Caller is owner of the data.
* @param outNamespace A output argument for the (optional) namespace part. Caller is owner of the data.
*/
CELIX_UTILS_EXPORT void celix_utils_extractLocalNameAndNamespaceFromFullyQualifiedName(const char *fullyQualifiedName, const char *namespaceSeparator, char **outLocalName, char **outNamespace);
/**
* @brief Returns the diff in seconds between tBegin and tEnd.
* @param tBegin The begin time.
* @param tEnd The end time.
* @return Diff in seconds.
*/
CELIX_UTILS_EXPORT double celix_difftime(const struct timespec *tBegin, const struct timespec *tEnd);
/**
* @brief Returns the current time as struct timespec
* @param clockId The clock to use (see time.h)
*/
CELIX_UTILS_EXPORT struct timespec celix_gettime(clockid_t clockId);
/**
* @brief Returns the absolute time for the provided delay in seconds.
* @param[in] time The time to add the delay to. Can be NULL, in which case the time is 0.
* @param[in] delayInSeconds The delay in seconds.
* @return A new time with the delay added.
*/
CELIX_UTILS_EXPORT struct timespec celix_delayedTimespec(const struct timespec* time, double delayInSeconds);
/**
* @brief Returns the elapsed time - in seconds - relative to the startTime
* using the clock for the provided clockid.
*/
CELIX_UTILS_EXPORT double celix_elapsedtime(clockid_t clockId, struct timespec startTime);
/**
* @brief Compare two time arguments.
* @param[in] a The first timespec.
* @param[in] b The second timespec.
* @return 0 if equal, -1 if a is before b and 1 if a is after b.
*/
CELIX_UTILS_EXPORT int celix_compareTime(const struct timespec* a, const struct timespec* b);
/**
* @brief Creates a hash from a string
*/
CELIX_UTILS_EXPORT unsigned int celix_utils_stringHash(const char* string);
/**
* @brief Compares services using the service id and ranking.
*
* If the service id are the same -> compare return 0.
*
* If the service ranking of A is higher -> return -1; (smaller -> A is sorted before B)
*
* If the service rankings are the same, but the svcId of A is smaller (older service) -> return -1:
* (smaller A is sorted before B)
*
* And vica versa.
*/
CELIX_UTILS_EXPORT int celix_utils_compareServiceIdsAndRanking(long svcIdA, long svcRankA, long svcIdB, long svcRankB);
#ifdef __cplusplus
}
#endif
#endif /* CELIX_UTILS_H_ */