The Fossil IO CString module provides an extensive, allocation-aware string utility layer for C and C++, combining everyday string manipulation, formatting, parsing, and comparison with a large set of novelty transforms and security-focused “safe” variants. The C API offers both conventional and bounds-checked functions that operate on heap-allocated cstring values, making ownership and lifetime explicit while remaining portable and dependency-free. On top of this, the C++ fossil::io::CString class wraps the C API with RAII semantics, STL interoperability, and expressive methods, allowing developers to write idiomatic modern C++ while retaining precise control over memory and safety guarantees.
Code reference for C and C++ APIs for the respective Fossil Logic library.
HEADER REFERENCE #
#ifndef FOSSIL_IO_CSTRING_H
#define FOSSIL_IO_CSTRING_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions */
typedef char* cstring;
typedef const char* ccstring;
/**
* @brief Creates a new cstring with the given initial value.
*
* @param init The initial value for the cstring.
* @return A new cstring initialized with the given value.
*/
cstring fossil_io_cstring_create(ccstring init);
/**
* @brief Frees the memory allocated for the given cstring.
*
* @param str The cstring to be freed.
*/
void fossil_io_cstring_free(cstring str);
// Money String Conversions
/**
* @brief Converts a double amount into a formatted money string.
*
* Example: 1234.56 -> "$1,234.56"
*
* @param amount The numeric amount to convert.
* @param output Buffer to store the formatted string.
* @param size Size of the output buffer.
* @return 0 on success, -1 if the buffer is too small or invalid.
*/
int fossil_io_cstring_money_to_string(double amount, cstring output, size_t size);
/**
* @brief Parses a money string into a numeric double value.
*
* Example: "$1,234.56" -> 1234.56
*
* @param input Input string representing money.
* @param amount Pointer to store the parsed numeric value.
* @return 0 on success, -1 on failure (invalid format).
*/
int fossil_io_cstring_string_to_money(ccstring input, double *amount);
/**
* @brief Converts a double amount into a formatted money string with optional currency symbol.
*
* Example: 1234.56 -> "$1,234.56" (USD default)
*
* @param amount The numeric amount to convert.
* @param output Buffer to store the formatted string.
* @param size Size of the output buffer.
* @param currency Currency symbol to prepend (e.g., "$", "€", "¥"); NULL defaults to "$".
* @return 0 on success, -1 if the buffer is too small or invalid.
*/
int fossil_io_cstring_money_to_string_currency(double amount, char *output, size_t size, const char *currency);
/**
* @brief Parses a money string into a numeric double value.
*
* Detects and ignores a currency symbol at the start.
*
* Example: "$1,234.56" -> 1234.56
*
* @param input Input string representing money.
* @param amount Pointer to store the parsed numeric value.
* @return 0 on success, -1 on failure (invalid format).
*/
int fossil_io_cstring_string_to_money_currency(const char *input, double *amount);
/**
* @brief Tokenizes a string by delimiters (reentrant version).
*
* Similar to strtok_r but with Fossil IO naming.
*
* @param str The string to tokenize (or NULL to continue).
* @param delim Delimiter characters.
* @param saveptr Context pointer across calls.
* @return Pointer to next token, or NULL if none.
*/
cstring fossil_io_cstring_token(cstring str, ccstring delim, cstring *saveptr);
/**
* @brief Case-insensitive substring search.
*
* @param haystack The string to search in.
* @param needle The substring to search for.
* @return Pointer to first occurrence of needle in haystack (case-insensitive),
* or NULL if not found.
*/
ccstring fossil_io_cstring_case_search(ccstring haystack, ccstring needle);
/**
* @brief Case-insensitive string comparison.
*
* @param s1 First string.
* @param s2 Second string.
* @return <0 if s1 < s2, 0 if equal, >0 if s1 > s2 (ignoring case).
*/
int fossil_io_cstring_case_compare(ccstring s1, ccstring s2);
/**
* @brief Case-insensitive string replace.
*
* Replaces all occurrences of `needle` with `replacement` in `input`,
* ignoring case.
*
* @param input Source string.
* @param needle Substring to replace (case-insensitive).
* @param replacement Replacement string.
* @return Newly allocated string with replacements applied, or NULL on failure.
* Caller must free().
*/
cstring fossil_io_cstring_case_replace(ccstring input,
ccstring needle,
ccstring replacement);
/**
* @brief Case-insensitive check if string starts with prefix.
*
* @param str Input string.
* @param prefix Prefix to check.
* @return 1 if str starts with prefix (ignoring case), 0 otherwise.
*/
int fossil_io_cstring_case_starts_with(ccstring str, ccstring prefix);
/**
* @brief Case-insensitive check if string ends with suffix.
*
* @param str Input string.
* @param suffix Suffix to check.
* @return 1 if str ends with suffix (ignoring case), 0 otherwise.
*/
int fossil_io_cstring_case_ends_with(ccstring str, ccstring suffix);
/**
* @brief Converts input into a "silly" string (random case and symbols).
*
* @param input The input string.
* @param output The buffer for the transformed string.
* @param size The size of the output buffer.
* @return 0 on success, non-zero on error (buffer too small).
*/
int fossil_io_cstring_silly(ccstring input, cstring output, size_t size);
/**
* @brief Converts input into Pig Latin.
*
* Rules:
* - Words starting with a vowel → add "yay" at the end.
* - Words starting with consonant(s) → move leading consonant(s) to the end + "ay".
*
* @param input The input string.
* @param output The buffer for the transformed string.
* @param size The size of the output buffer.
* @return 0 on success, non-zero on error.
*/
int fossil_io_cstring_piglatin(ccstring input, cstring output, size_t size);
/**
* @brief Converts input into "leet speak".
*
* Mapping (basic):
* A → 4, E → 3, I → 1, O → 0, S → 5, T → 7
*
* @param input The input string.
* @param output The buffer for the transformed string.
* @param size The size of the output buffer.
* @return 0 on success, non-zero on error.
*/
int fossil_io_cstring_leetspeak(ccstring input, cstring output, size_t size);
// Novelty String Transforms
/**
* @brief Converts a string into "mocking SpongeBob" case.
*
* Example: "hello world" -> "hElLo wOrLd"
*
* @param str Input string.
* @return Newly allocated transformed string, or NULL on failure.
*/
cstring fossil_io_cstring_mocking(ccstring str);
/**
* @brief Applies ROT13 cipher to a string.
*
* Example: "hello" -> "uryyb"
*
* @param str Input string.
* @return Newly allocated transformed string, or NULL on failure.
*/
cstring fossil_io_cstring_rot13(ccstring str);
/**
* @brief Shuffles the characters of a string randomly.
*
* Example: "hello" -> "lohel" (result varies).
*
* @param str Input string.
* @return Newly allocated shuffled string, or NULL on failure.
*/
cstring fossil_io_cstring_shuffle(ccstring str);
/**
* @brief Converts a string to UPPER_SNAKE_CASE.
*
* Example: "Hello World" -> "HELLO_WORLD"
*
* @param str Input string.
* @return Newly allocated transformed string, or NULL on failure.
*/
cstring fossil_io_cstring_upper_snake(ccstring str);
/**
* @brief Generates a "zalgo" glitch text version of a string.
*
* @param str Input string.
* @return Newly allocated transformed string, or NULL on failure.
*/
cstring fossil_io_cstring_zalgo(ccstring str);
/**
* @brief Creates a copy of the given cstring.
*
* @param str The cstring to be copied.
* @return A new cstring that is a copy of the given cstring.
*/
cstring fossil_io_cstring_copy(ccstring str);
/**
* @brief Converts an English number string into an integer.
*
* Example: "twenty-three" -> 23
*
* @param str Input string containing the number in English.
* @param out Pointer to integer where the parsed number will be stored.
* @return 0 on success, non-zero on error (invalid input).
*/
int fossil_io_cstring_number_from_words(const char *str, int *out);
/**
* @brief Converts an integer number into its English representation.
*
* Example: 23 -> "twenty-three"
*
* @param num The integer to convert.
* @param buffer The output buffer to store the English string.
* @param size The size of the output buffer.
* @return 0 on success, non-zero if the buffer is too small.
*/
int fossil_io_cstring_number_to_words(int num, char *buffer, size_t size);
/**
* @brief Duplicates the given cstring.
*
* @param str The cstring to be duplicated.
* @return A new cstring that is a duplicate of the given cstring.
*/
cstring fossil_io_cstring_dup(ccstring str);
/**
* @brief Concatenates two cstrings into a new cstring.
*
* @param s1 The first cstring.
* @param s2 The second cstring.
* @return A new cstring that is the concatenation of s1 and s2.
*/
cstring fossil_io_cstring_concat(ccstring s1, ccstring s2);
/**
* @brief Returns the length of the given cstring.
*
* @param str The cstring whose length is to be determined.
* @return The length of the given cstring.
*/
size_t fossil_io_cstring_length(ccstring str);
/**
* @brief Compares two cstrings.
*
* @param s1 The first cstring.
* @param s2 The second cstring.
* @return An integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2.
*/
int fossil_io_cstring_compare(ccstring s1, ccstring s2);
/**
* @brief Trims whitespace from the beginning and end of the given cstring.
*
* @param str The cstring to be trimmed.
*/
void fossil_io_cstring_trim(cstring str);
/**
* @brief Splits the given cstring by the specified delimiter.
*
* @param str The cstring to be split.
* @param delimiter The character to split the cstring by.
* @param count Pointer to a size_t variable where the number of resulting substrings will be stored.
* @return An array of cstrings resulting from the split operation.
*/
cstring *fossil_io_cstring_split(ccstring str, char delimiter, size_t *count);
/**
* @brief Replaces all occurrences of a substring within a cstring with another substring.
*
* @param str The original cstring.
* @param old The substring to be replaced.
* @param new_str The substring to replace with.
* @return A new cstring with the replacements made.
*/
cstring fossil_io_cstring_replace(ccstring str, ccstring old, ccstring new_str);
/**
* @brief Converts all characters in the given cstring to uppercase.
*
* @param str The cstring to be converted.
* @return The cstring with all characters converted to uppercase.
*/
cstring fossil_io_cstring_to_upper(cstring str);
/**
* @brief Converts all characters in the given cstring to lowercase.
*
* @param str The cstring to be converted.
* @return The cstring with all characters converted to lowercase.
*/
cstring fossil_io_cstring_to_lower(cstring str);
/**
* @brief Checks if the given cstring starts with the specified prefix.
*
* @param str The cstring to be checked.
* @param prefix The prefix to check for.
* @return 1 if the cstring starts with the prefix, 0 otherwise.
*/
int fossil_io_cstring_starts_with(ccstring str, ccstring prefix);
/**
* @brief Checks if the given cstring ends with the specified suffix.
*
* @param str The cstring to be checked.
* @param suffix The suffix to check for.
* @return 1 if the cstring ends with the suffix, 0 otherwise.
*/
int fossil_io_cstring_ends_with(ccstring str, ccstring suffix);
/**
* @brief Extracts a substring from the given cstring.
*
* @param str The original cstring.
* @param start The starting index of the substring.
* @param length The length of the substring.
* @return A new cstring that is the specified substring of the original cstring.
*/
cstring fossil_io_cstring_substring(ccstring str, size_t start, size_t length);
/**
* @brief Reverses the given cstring.
*
* @param str The cstring to be reversed.
* @return A new cstring that is the reverse of the given cstring.
*/
cstring fossil_io_cstring_reverse(cstring str);
/**
* @brief Checks if the given cstring contains the specified substring.
*
* @param str The cstring to be checked.
* @param substr The substring to check for.
* @return 1 if the cstring contains the substring, 0 otherwise.
*/
int fossil_io_cstring_contains(ccstring str, ccstring substr);
/**
* @brief Repeats the given cstring the specified number of times.
*
* @param str The cstring to be repeated.
* @param count The number of times to repeat the cstring.
* @return A new cstring that is the original cstring repeated the specified number of times.
*/
cstring fossil_io_cstring_repeat(ccstring str, size_t count);
/**
* @brief Strips the given character from the beginning and end of the cstring.
*
* @param str The cstring to be stripped.
* @param ch The character to strip.
* @return A new cstring that is the original cstring with the specified character stripped from the beginning and end.
*/
cstring fossil_io_cstring_strip(ccstring str, char ch);
/**
* @brief Counts the number of occurrences of a substring within the given cstring.
*
* @param str The cstring to be searched.
* @param substr The substring to search for.
* @return The number of occurrences of the substring within the cstring.
*/
size_t fossil_io_cstring_count(ccstring str, ccstring substr);
/**
* @brief Pads the given cstring with the specified character on the left side.
*
* @param str The cstring to be padded.
* @param total_length The total length of the resulting cstring.
* @param pad_char The character to pad with.
* @return A new cstring that is the original cstring padded on the left side.
*/
cstring fossil_io_cstring_pad_left(ccstring str, size_t total_length, char pad_char);
/**
* @brief Pads the given cstring with the specified character on the right side.
*
* @param str The cstring to be padded.
* @param total_length The total length of the resulting cstring.
* @param pad_char The character to pad with.
* @return A new cstring that is the original cstring padded on the right side.
*/
cstring fossil_io_cstring_pad_right(ccstring str, size_t total_length, char pad_char);
/**
* @brief Performs a case-insensitive comparison of two C strings.
*
* Compares the characters of `str1` and `str2` one by one, ignoring case.
*
* @param str1 The first null-terminated string to compare.
* @param str2 The second null-terminated string to compare.
* @return 1 if the strings are equal (case-insensitive), 0 otherwise.
*/
int fossil_io_cstring_icmp(ccstring str1, ccstring str2);
/**
* @brief Checks if a substring is contained within a string (case-insensitive).
*
* Iterates through `str` and checks if `substr` occurs at any position, ignoring case.
*
* @param str The null-terminated string to search within.
* @param substr The null-terminated substring to search for.
* @return 1 if `substr` is found within `str` (case-insensitive), 0 otherwise.
*/
int fossil_io_cstring_icontains(ccstring str, ccstring substr);
/**
* @brief Creates a new cstring using a formatted string (like sprintf).
*
* @param format The format string.
* @param ... The arguments for the format string.
* @return A newly allocated cstring.
*/
cstring fossil_io_cstring_format(ccstring format, ...);
/**
* @brief Joins an array of strings with a delimiter.
*
* @param strings The array of cstrings.
* @param count The number of elements in the array.
* @param delimiter The delimiter to insert between strings.
* @return A new cstring consisting of all strings joined by the delimiter.
*/
cstring fossil_io_cstring_join(ccstring *strings, size_t count, char delimiter);
/**
* @brief Finds the first index of a substring within a string.
*
* @param str The cstring to search.
* @param substr The substring to find.
* @return The index of the first occurrence, or -1 if not found.
*/
int fossil_io_cstring_index_of(ccstring str, ccstring substr);
/**
* @brief Checks if two cstrings are exactly equal (case-sensitive).
*
* Compares two null-terminated strings character by character.
*
* @param a The first cstring to compare.
* @param b The second cstring to compare.
* @return 1 if the strings are exactly equal, 0 otherwise.
*/
int fossil_io_cstring_equals(ccstring a, ccstring b);
/**
* @brief Checks if two cstrings are equal, ignoring case.
*
* Compares two null-terminated strings in a case-insensitive manner.
*
* @param a The first cstring to compare.
* @param b The second cstring to compare.
* @return 1 if the strings are equal ignoring case, 0 otherwise.
*/
int fossil_io_cstring_iequals(ccstring a, ccstring b);
/**
* @brief Escapes a cstring for safe use in JSON strings.
*
* Replaces special characters like quotes, backslashes, and control characters
* with their escaped equivalents (e.g., `"` becomes `\"`, `\n` becomes `\\n`, etc.).
*
* @param str The original cstring to escape.
* @return A newly allocated cstring containing the JSON-escaped result.
*/
cstring fossil_io_cstring_escape_json(ccstring str);
/**
* @brief Unescapes a JSON-escaped cstring.
*
* Converts escaped sequences such as `\\n`, `\\t`, `\\uXXXX`, and `\\\"` into
* their actual character representations.
*
* @param str The JSON-escaped cstring to unescape.
* @return A newly allocated cstring with escape sequences resolved.
*/
cstring fossil_io_cstring_unescape_json(ccstring str);
/**
* @brief Normalizes whitespace in a cstring by collapsing multiple spaces.
*
* Replaces sequences of two or more whitespace characters with a single space.
* Leading and trailing whitespace is trimmed.
*
* @param str The cstring to normalize.
* @return A newly allocated cstring with normalized whitespace.
*/
cstring fossil_io_cstring_normalize_spaces(cstring str);
/**
* @brief Removes surrounding single or double quotes from a cstring.
*
* If the string begins and ends with the same quote character (`"` or `'`),
* both are removed. Does not modify the contents inside the quotes.
*
* @param str The cstring to process.
* @return A newly allocated cstring without surrounding quotes.
*/
cstring fossil_io_cstring_strip_quotes(ccstring str);
/**
* @brief Appends src to dest in-place, resizing as necessary.
*
* @param dest A pointer to the destination cstring.
* @param src The string to append.
* @return 0 on success, non-zero on allocation failure.
*/
cstring fossil_io_cstring_append(cstring *dest, ccstring src);
// Secure String
/**
* @brief Creates a new cstring with the given initial value safely.
*
* Allocates a new buffer for the string, ensuring null-termination.
*
* @param init The initial value for the cstring.
* @return A new cstring initialized with the given value, or NULL on failure.
*/
cstring fossil_io_cstring_create_safe(const char *init, size_t max_len);
/**
* @brief Frees a cstring safely.
*
* Sets the pointer to NULL after freeing to prevent dangling references.
*
* @param str Pointer to the cstring to free.
*/
void fossil_io_cstring_free_safe(cstring *str);
/**
* @brief Creates a safe copy of the given cstring.
*
* @param str The cstring to copy.
* @param max_len Maximum number of characters to copy.
* @return A newly allocated cstring copy, or NULL on failure.
*/
cstring fossil_io_cstring_copy_safe(ccstring str, size_t max_len);
/**
* @brief Duplicates the given cstring safely.
*
* @param str The cstring to duplicate.
* @param max_len Maximum number of characters to duplicate.
* @return A newly allocated duplicate cstring, or NULL on failure.
*/
cstring fossil_io_cstring_dup_safe(ccstring str, size_t max_len);
/**
* @brief Concatenates two cstrings safely.
*
* Ensures that the resulting string is null-terminated and does not overflow.
*
* @param s1 First cstring.
* @param s2 Second cstring.
* @param max_len Maximum allowed length of the resulting string.
* @return A new concatenated cstring, or NULL on failure.
*/
cstring fossil_io_cstring_concat_safe(ccstring s1, ccstring s2, size_t max_len);
/**
* @brief Returns the length of the given cstring safely.
*
* Ensures that the string is properly null-terminated within max_len.
*
* @param str The cstring whose length is determined.
* @param max_len Maximum characters to scan.
* @return The length of the cstring up to max_len.
*/
size_t fossil_io_cstring_length_safe(ccstring str, size_t max_len);
/**
* @brief Compares two cstrings safely.
*
* Ensures no buffer overrun; comparison stops at max_len or null terminator.
*
* @param s1 First cstring.
* @param s2 Second cstring.
* @param max_len Maximum characters to compare.
* @return <0 if s1<s2, 0 if equal, >0 if s1>s2
*/
int fossil_io_cstring_compare_safe(ccstring s1, ccstring s2, size_t max_len);
/**
* @brief Safely concatenates src to dest in-place with bounds checking.
*
* Resizes the buffer as needed. Ensures null-termination.
*
* @param dest Pointer to destination cstring.
* @param src Source cstring to append.
* @param max_len Maximum allowed length for dest after append.
* @return 0 on success, non-zero on failure.
*/
int fossil_io_cstring_append_safe(cstring *dest, ccstring src, size_t max_len);
/**
* @brief Trims whitespace safely from a cstring.
*
* Ensures null-termination and modifies in-place or allocates a new string.
*
* @param str The cstring to trim.
* @param max_len Maximum length of the string to process.
*/
cstring fossil_io_cstring_trim_safe(ccstring str, size_t max_len);
/**
* @brief Splits a cstring safely by a delimiter.
*
* Allocates an array of strings, each safely null-terminated.
*
* @param str The string to split.
* @param delimiter Character to split by.
* @param count Pointer to store number of substrings.
* @param max_len Maximum length of each substring.
* @return Array of safe cstrings, or NULL on failure.
*/
cstring *fossil_io_cstring_split_safe(ccstring str, char delimiter, size_t *count, size_t max_len);
/**
* @brief Replaces all occurrences of a substring safely.
*
* Allocates a new string and ensures null-termination.
*
* @param str Original string.
* @param old Substring to replace.
* @param new_str Replacement substring.
* @param max_len Maximum length of resulting string.
* @return A new cstring with replacements, or NULL on failure.
*/
cstring fossil_io_cstring_replace_safe(ccstring str, ccstring old, ccstring new_str, size_t max_len);
/**
* @brief Converts a cstring to uppercase safely.
*
* Allocates a new string, ensures null-termination.
*
* @param str The cstring to convert.
* @param max_len Maximum allowed length.
* @return Uppercase cstring, or NULL on failure.
*/
cstring fossil_io_cstring_to_upper_safe(ccstring str, size_t max_len);
/**
* @brief Converts a cstring to lowercase safely.
*
* @param str The cstring to convert.
* @param max_len Maximum allowed length.
* @return Lowercase cstring, or NULL on failure.
*/
cstring fossil_io_cstring_to_lower_safe(ccstring str, size_t max_len);
/**
* @brief Safely creates a formatted cstring.
*
* Allocates enough memory for the resulting string; guarantees null-termination.
*
* @param max_len Maximum length for formatted string.
* @param format Format string.
* @param ... Format arguments.
* @return Newly allocated formatted cstring, or NULL on failure.
*/
cstring fossil_io_cstring_format_safe(size_t max_len, ccstring format, ...);
/**
* @brief Safely joins multiple strings with a delimiter.
*
* @param strings Array of cstrings.
* @param count Number of elements.
* @param delimiter Character to insert.
* @param max_len Maximum allowed length of resulting string.
* @return New cstring or NULL on failure.
*/
cstring fossil_io_cstring_join_safe(ccstring *strings, size_t count, char delimiter, size_t max_len);
/**
* @brief Safely escapes a cstring for JSON output.
*
* Ensures resulting string is null-terminated and memory-safe.
*
* @param str Input cstring.
* @param max_len Maximum length of resulting escaped string.
* @return Escaped cstring, or NULL on failure.
*/
cstring fossil_io_cstring_escape_json_safe(ccstring str, size_t max_len);
/**
* @brief Safely unescapes a JSON-escaped cstring.
*
* @param str JSON-escaped string.
* @param max_len Maximum length of resulting string.
* @return Unescaped cstring, or NULL on failure.
*/
cstring fossil_io_cstring_unescape_json_safe(ccstring str, size_t max_len);
/**
* @brief Extracts a substring from a given cstring safely.
*
* Ensures bounds checking and respects maximum length.
*
* @param str The original cstring.
* @param start The starting index for the substring.
* @param length The number of characters to include.
* @param max_len Maximum allowed length to prevent buffer overrun.
* @return A newly allocated cstring containing the substring, or NULL on failure.
*/
cstring fossil_io_cstring_substring_safe(ccstring str, size_t start, size_t length, size_t max_len);
/**
* @brief Reverses a cstring safely.
*
* Creates a new string that is the reverse of the input while ensuring memory safety.
*
* @param str The cstring to reverse.
* @param max_len Maximum length to process to prevent overflow.
* @return A newly allocated reversed cstring, or NULL on failure.
*/
cstring fossil_io_cstring_reverse_safe(ccstring str, size_t max_len);
/**
* @brief Checks if a cstring contains a substring safely.
*
* Ensures that no buffer overruns occur.
*
* @param str The cstring to search.
* @param substr The substring to look for.
* @param max_len Maximum number of characters to scan.
* @return 1 if substring exists, 0 otherwise.
*/
int fossil_io_cstring_contains_safe(ccstring str, ccstring substr, size_t max_len);
/**
* @brief Repeats a cstring multiple times safely.
*
* Ensures the resulting string does not exceed max_len.
*
* @param str The string to repeat.
* @param count Number of repetitions.
* @param max_len Maximum length of resulting string.
* @return A newly allocated repeated cstring, or NULL on failure.
*/
cstring fossil_io_cstring_repeat_safe(ccstring str, size_t count, size_t max_len);
/**
* @brief Strips a specified character from both ends of a cstring safely.
*
* @param str The cstring to process.
* @param ch The character to strip.
* @param max_len Maximum length to process.
* @return A new cstring with the specified character removed from start and end.
*/
cstring fossil_io_cstring_strip_safe(ccstring str, char ch, size_t max_len);
/**
* @brief Counts the occurrences of a substring within a cstring safely.
*
* Ensures safe bounds checking.
*
* @param str The cstring to search.
* @param substr The substring to count.
* @param max_len Maximum length to scan.
* @return The number of occurrences of the substring.
*/
size_t fossil_io_cstring_count_safe(ccstring str, ccstring substr, size_t max_len);
/**
* @brief Pads a cstring on the left with a specific character safely.
*
* Ensures total length does not exceed max_len.
*
* @param str The cstring to pad.
* @param total_length The desired total length after padding.
* @param pad_char Character to pad with.
* @param max_len Maximum allowed length of the resulting string.
* @return A newly allocated padded cstring.
*/
cstring fossil_io_cstring_pad_left_safe(ccstring str, size_t total_length, char pad_char, size_t max_len);
/**
* @brief Pads a cstring on the right with a specific character safely.
*
* Ensures total length does not exceed max_len.
*
* @param str The cstring to pad.
* @param total_length The desired total length after padding.
* @param pad_char Character to pad with.
* @param max_len Maximum allowed length of the resulting string.
* @return A newly allocated padded cstring.
*/
cstring fossil_io_cstring_pad_right_safe(ccstring str, size_t total_length, char pad_char, size_t max_len);
/**
* @brief Checks if a cstring starts with a specified prefix safely.
*
* @param str The cstring to check.
* @param prefix The prefix to test.
* @param max_len Maximum characters to consider.
* @return 1 if the cstring starts with the prefix, 0 otherwise.
*/
int fossil_io_cstring_starts_with_safe(ccstring str, ccstring prefix, size_t max_len);
/**
* @brief Checks if a cstring ends with a specified suffix safely.
*
* @param str The cstring to check.
* @param suffix The suffix to test.
* @param max_len Maximum characters to consider.
* @return 1 if the cstring ends with the suffix, 0 otherwise.
*/
int fossil_io_cstring_ends_with_safe(ccstring str, ccstring suffix, size_t max_len);
/**
* @brief Compares two cstrings for exact equality safely.
*
* @param a First cstring.
* @param b Second cstring.
* @param max_len Maximum characters to compare.
* @return 1 if equal, 0 otherwise.
*/
int fossil_io_cstring_equals_safe(ccstring a, ccstring b, size_t max_len);
/**
* @brief Compares two cstrings for equality ignoring case safely.
*
* @param a First cstring.
* @param b Second cstring.
* @param max_len Maximum characters to compare.
* @return 1 if equal ignoring case, 0 otherwise.
*/
int fossil_io_cstring_iequals_safe(ccstring a, ccstring b, size_t max_len);
/**
* @brief Checks if a substring exists in a cstring ignoring case safely.
*
* @param str The cstring to search.
* @param substr The substring to look for.
* @param max_len Maximum characters to scan.
* @return 1 if found, 0 otherwise.
*/
int fossil_io_cstring_icontains_safe(ccstring str, ccstring substr, size_t max_len);
/**
* @brief Removes surrounding quotes from a cstring safely.
*
* @param str The cstring to process.
* @param max_len Maximum characters to process.
* @return A new cstring without surrounding quotes.
*/
cstring fossil_io_cstring_strip_quotes_safe(ccstring str, size_t max_len);
/**
* @brief Normalizes whitespace in a cstring safely.
*
* Collapses multiple spaces into one and trims leading/trailing whitespace.
*
* @param str The cstring to normalize.
* @param max_len Maximum characters to process.
* @return A newly allocated normalized cstring.
*/
cstring fossil_io_cstring_normalize_spaces_safe(ccstring str, size_t max_len);
/**
* @brief Returns the index of a substring in a cstring safely.
*
* @param str The cstring to search.
* @param substr The substring to find.
* @param max_len Maximum characters to consider.
* @return Index of first occurrence, or -1 if not found.
*/
int fossil_io_cstring_index_of_safe(ccstring str, ccstring substr, size_t max_len);
#ifdef __cplusplus
}
#include <string>
#include <vector>
/**
* namespace for Fossil Logic.
*/
namespace fossil {
/**
* Namespace for I/O operations.
*/
namespace io {
class CString {
private:
cstring _str;
public:
/**
* Constructor to create a new cstring with the given initial value.
*
* @param init The initial value for the cstring.
*/
CString(const std::string &init) {
_str = fossil_io_cstring_create(init.c_str());
}
/**
* Constructor to create a CString from an existing cstring.
*
* @param str The cstring to wrap.
*/
CString(ccstring str) {
_str = fossil_io_cstring_copy(str);
}
/**
* Default constructor to create an empty CString.
*/
CString() {
_str = fossil_io_cstring_create("");
}
/**
* Destructor to free the memory allocated for the cstring.
*/
~CString() {
fossil_io_cstring_free(_str);
}
/**
* Converts an English number string into an integer.
*
* Example: "twenty-three" -> 23
*
* @param str Input string containing the number in English.
* @return The parsed integer value, or throws std::invalid_argument on error.
*/
static int number_from_words(const std::string &str) {
int value = 0;
int result = fossil_io_cstring_number_from_words(str.c_str(), &value);
if (result != 0) throw std::invalid_argument("Invalid English number string");
return value;
}
/**
* Converts an integer number into its English representation.
*
* Example: 23 -> "twenty-three"
*
* @param num The integer to convert.
* @return The English representation as a std::string.
*/
static std::string number_to_words(int num) {
char buffer[128];
int result = fossil_io_cstring_number_to_words(num, buffer, sizeof(buffer));
if (result != 0) throw std::runtime_error("Buffer too small for English number string");
return std::string(buffer);
}
/**
* Convert numeric amount to string.
* Uses default currency "$".
*/
static std::string money_to_string(double amount) {
char buffer[128];
if (fossil_io_cstring_money_to_string(amount, buffer, sizeof(buffer)) != 0) {
throw std::runtime_error("Failed to convert amount to string");
}
return std::string(buffer);
}
/**
* Convert numeric amount to string with currency symbol.
*/
static std::string currency_to_string(double amount, const std::string ¤cy) {
char buffer[128];
if (fossil_io_cstring_money_to_string_currency(amount, buffer, sizeof(buffer), currency.c_str()) != 0) {
throw std::runtime_error("Failed to convert amount to string with currency");
}
return std::string(buffer);
}
/**
* Convert string to numeric amount.
*/
static double from_money(const std::string &str) {
double value = 0.0;
if (fossil_io_cstring_string_to_money(str.c_str(), &value) != 0) {
throw std::runtime_error("Failed to parse money string");
}
return value;
}
/**
* Convert string to numeric amount with currency detection.
*/
static double from_currency(const std::string &str) {
double value = 0.0;
if (fossil_io_cstring_string_to_money_currency(str.c_str(), &value) != 0) {
throw std::runtime_error("Failed to parse money string with currency");
}
return value;
}
/**
* Creates a copy of the given cstring.
*
* @param str The cstring to be copied.
* @return A new CString that is a copy of the given cstring.
*/
static CString copy(const std::string &str) {
return CString(fossil_io_cstring_copy(str.c_str()));
}
/**
* Converts input into a "silly" string (random case and symbols).
*
* @param output_size The size of the output buffer.
* @return A std::string with the silly transformation.
*/
std::string silly(size_t output_size = 256) const {
char *output = new char[output_size];
int res = fossil_io_cstring_silly(_str, output, output_size);
std::string result = (res == 0) ? std::string(output) : "";
delete[] output;
return result;
}
/**
* Converts input into Pig Latin.
*
* @param output_size The size of the output buffer.
* @return A std::string with the Pig Latin transformation.
*/
std::string piglatin(size_t output_size = 256) const {
char *output = new char[output_size];
int res = fossil_io_cstring_piglatin(_str, output, output_size);
std::string result = (res == 0) ? std::string(output) : "";
delete[] output;
return result;
}
/**
* Converts input into "leet speak".
*
* @param output_size The size of the output buffer.
* @return A std::string with the leet speak transformation.
*/
std::string leetspeak(size_t output_size = 256) const {
char *output = new char[output_size];
int res = fossil_io_cstring_leetspeak(_str, output, output_size);
std::string result = (res == 0) ? std::string(output) : "";
delete[] output;
return result;
}
/**
* Converts a string into "mocking SpongeBob" case.
*
* @return A CString with the mocking transformation.
*/
CString mocking() const {
return CString(fossil_io_cstring_mocking(_str));
}
/**
* Applies ROT13 cipher to a string.
*
* @return A CString with the ROT13 transformation.
*/
CString rot13() const {
return CString(fossil_io_cstring_rot13(_str));
}
/**
* Shuffles the characters of a string randomly.
*
* @return A CString with the shuffled string.
*/
CString shuffle() const {
return CString(fossil_io_cstring_shuffle(_str));
}
/**
* Converts a string to UPPER_SNAKE_CASE.
*
* @return A CString with the UPPER_SNAKE_CASE transformation.
*/
CString upper_snake() const {
return CString(fossil_io_cstring_upper_snake(_str));
}
/**
* Duplicates the given cstring.
*
* @param str The cstring to be duplicated.
* @return A new CString that is a duplicate of the given cstring.
*/
static CString dup(const std::string &str) {
return CString(fossil_io_cstring_dup(str.c_str()));
}
/**
* Concatenates two cstrings into a new CString.
*
* @param s1 The first cstring.
* @param s2 The second cstring.
* @return A new CString that is the concatenation of s1 and s2.
*/
static CString concat(const std::string &s1, const std::string &s2) {
return CString(fossil_io_cstring_concat(s1.c_str(), s2.c_str()));
}
/**
* Returns the length of the cstring.
*
* @return The length of the cstring.
*/
size_t length() const {
return fossil_io_cstring_length(_str);
}
/**
* Compares this cstring with another cstring.
*
* @param other The other cstring to compare with.
* @return An integer less than, equal to, or greater than zero if this cstring is found, respectively, to be less than, to match, or be greater than the other cstring.
*/
int compare(const std::string &other) const {
return fossil_io_cstring_compare(_str, other.c_str());
}
/**
* Trims whitespace from the beginning and end of the cstring.
*/
void trim() {
fossil_io_cstring_trim(_str);
}
/**
* Splits the cstring by the specified delimiter.
*
* @param delimiter The character to split the cstring by.
* @param count Pointer to a size_t variable where the number of resulting substrings will be stored.
* @return An array of cstrings resulting from the split operation.
*/
std::vector<std::string> split(char delimiter, size_t *count) const {
cstring *result = fossil_io_cstring_split(_str, delimiter, count);
std::vector<std::string> vec;
for (size_t i = 0; i < *count; i++) {
vec.push_back(result[i]);
}
return vec;
}
/**
* Replaces all occurrences of a substring within the cstring with another substring.
*
* @param old The substring to be replaced.
* @param new_str The substring to replace with.
* @return A new CString with the replacements made.
*/
CString replace(const std::string &old, const std::string &new_str) const {
return CString(fossil_io_cstring_replace(_str, old.c_str(), new_str.c_str()));
}
/**
* Converts all characters in the cstring to uppercase.
*
* @return The cstring with all characters converted to uppercase.
*/
CString to_upper() const {
return CString(fossil_io_cstring_to_upper(_str));
}
/**
* Converts all characters in the cstring to lowercase.
*
* @return The cstring with all characters converted to lowercase.
*/
CString to_lower() const {
return CString(fossil_io_cstring_to_lower(_str));
}
/**
* Checks if the cstring starts with the specified prefix.
*
* @param prefix The prefix to check for.
* @return True if the cstring starts with the prefix, false otherwise.
*/
bool starts_with(const std::string &prefix) const {
return fossil_io_cstring_starts_with(_str, prefix.c_str());
}
/**
* Checks if the cstring ends with the specified suffix.
*
* @param suffix The suffix to check for.
* @return True if the cstring ends with the suffix, false otherwise.
*/
bool ends_with(const std::string &suffix) const {
return fossil_io_cstring_ends_with(_str, suffix.c_str());
}
/**
* Extracts a substring from the cstring.
*
* @param start The starting index of the substring.
* @param length The length of the substring.
* @return A new CString that is the specified substring of the original cstring.
*/
CString substring(size_t start, size_t length) const {
return CString(fossil_io_cstring_substring(_str, start, length));
}
/**
* Reverses the cstring.
*
* @return A new CString that is the reverse of the cstring.
*/
CString reverse() const {
return CString(fossil_io_cstring_reverse(_str));
}
/**
* Checks if the cstring contains the specified substring.
*
* @param substr The substring to check for.
* @return True if the cstring contains the substring, false otherwise.
*/
bool contains(const std::string &substr) const {
return fossil_io_cstring_contains(_str, substr.c_str());
}
/**
* Repeats the cstring the specified number of times.
*
* @param count The number of times to repeat the cstring.
* @return A new CString that is the original cstring repeated the specified number of times.
*/
CString repeat(size_t count) const {
return CString(fossil_io_cstring_repeat(_str, count));
}
/**
* Strips the given character from the beginning and end of the cstring.
*
* @param ch The character to strip.
* @return A new CString that is the original cstring with the specified character stripped from the beginning and end.
*/
CString strip(char ch) const {
return CString(fossil_io_cstring_strip(_str, ch));
}
/**
* Counts the number of occurrences of a substring within the cstring.
*
* @param substr The substring to search for.
* @return The number of occurrences of the substring within the cstring.
*/
size_t count(const std::string &substr) const {
return fossil_io_cstring_count(_str, substr.c_str());
}
/**
* Pads the cstring with the specified character on the left side.
*
* @param total_length The total length of the resulting cstring.
* @param pad_char The character to pad with.
* @return A new CString that is the original cstring padded on the left side.
*/
CString pad_left(size_t total_length, char pad_char) const {
return CString(fossil_io_cstring_pad_left(_str, total_length, pad_char));
}
/**
* Pads the cstring with the specified character on the right side.
*
* @param total_length The total length of the resulting cstring.
* @param pad_char The character to pad with.
* @return A new CString that is the original cstring padded on the right side.
*/
CString pad_right(size_t total_length, char pad_char) const {
return CString(fossil_io_cstring_pad_right(_str, total_length, pad_char));
}
/**
* Performs a case-insensitive comparison of two C strings.
*
* @param other The other string to compare with.
* @return True if the strings are equal (case-insensitive), false otherwise.
*/
bool icmp(const std::string &other) const {
return fossil_io_cstring_icmp(_str, other.c_str()) == 1;
}
/**
* Checks if a substring is contained within the string (case-insensitive).
*
* @param substr The substring to search for.
* @return True if the substring is found (case-insensitive), false otherwise.
*/
bool icontains(const std::string &substr) const {
return fossil_io_cstring_icontains(_str, substr.c_str()) == 1;
}
/**
* Creates a new CString using a formatted string (like sprintf).
*
* @param format The format string.
* @param ... The arguments for the format string.
* @return A newly allocated CString.
*/
static CString format(const char *format, ...) {
va_list args;
va_start(args, format);
cstring result = fossil_io_cstring_format(format, args);
va_end(args);
return CString(result);
}
/**
* Joins an array of strings with a delimiter.
*
* @param strings The array of strings.
* @param delimiter The delimiter to insert between strings.
* @return A new CString consisting of all strings joined by the delimiter.
*/
static CString join(const std::vector<std::string> &strings, char delimiter) {
std::vector<ccstring> cstrs;
for (const auto &s : strings) {
cstrs.push_back(s.c_str());
}
cstring result = fossil_io_cstring_join(const_cast<ccstring*>(cstrs.data()), cstrs.size(), delimiter);
return CString(result);
}
/**
* Finds the first index of a substring within the string.
*
* @param substr The substring to find.
* @return The index of the first occurrence, or -1 if not found.
*/
int index_of(const std::string &substr) const {
return fossil_io_cstring_index_of(_str, substr.c_str());
}
/**
* Checks if two strings are exactly equal (case-sensitive).
*
* @param other The other string to compare.
* @return True if the strings are exactly equal, false otherwise.
*/
bool equals(const std::string &other) const {
return fossil_io_cstring_equals(_str, other.c_str()) == 1;
}
/**
* Checks if two strings are equal, ignoring case.
*
* @param other The other string to compare.
* @return True if the strings are equal ignoring case, false otherwise.
*/
bool iequals(const std::string &other) const {
return fossil_io_cstring_iequals(_str, other.c_str()) == 1;
}
/**
* Escapes the string for safe use in JSON strings.
*
* @return A newly allocated CString containing the JSON-escaped result.
*/
CString escape_json() const {
return CString(fossil_io_cstring_escape_json(_str));
}
/**
* Unescapes a JSON-escaped string.
*
* @return A newly allocated CString with escape sequences resolved.
*/
CString unescape_json() const {
return CString(fossil_io_cstring_unescape_json(_str));
}
/**
* Normalizes whitespace in the string by collapsing multiple spaces.
*
* @return A newly allocated CString with normalized whitespace.
*/
CString normalize_spaces() const {
return CString(fossil_io_cstring_normalize_spaces(_str));
}
/**
* Removes surrounding single or double quotes from the string.
*
* @return A newly allocated CString without surrounding quotes.
*/
CString strip_quotes() const {
return CString(fossil_io_cstring_strip_quotes(_str));
}
/**
* Appends src to this string in-place, resizing as necessary.
*
* @param src The string to append.
* @return 0 on success, non-zero on allocation failure.
*/
int append(const std::string &src) {
return fossil_io_cstring_append(&_str, src.c_str()) == nullptr ? 1 : 0;
}
/* ---------------- Safe Copy / Dup / Concat ---------------- */
/**
* @brief Creates a safe copy of the given string.
*
* Allocates a new CString with a copy of the input string, using the
* secure underlying C function to prevent buffer overflows.
*
* @param str The string to copy.
* @return A new CString containing a safe copy of the input string.
*/
static CString copy_safe(const std::string &str) {
return CString(fossil_io_cstring_copy_safe(str.c_str(), str.size()));
}
/**
* @brief Duplicates a string safely.
*
* Creates a new CString with the same content as the input string,
* using a secure duplication function that respects the specified length.
*
* @param str The string to duplicate.
* @return A new CString duplicate of the input string.
*/
static CString dup_safe(const std::string &str) {
return CString(fossil_io_cstring_dup_safe(str.c_str(), str.size()));
}
/**
* @brief Concatenates two strings safely.
*
* Produces a new CString containing s1 followed by s2, using the secure
* concatenation function and respecting the maximum allowed length.
*
* @param s1 The first string.
* @param s2 The second string.
* @param max_len Maximum length of the resulting string to prevent overflow.
* @return A new CString with the concatenated content.
*/
static CString concat_safe(const std::string &s1, const std::string &s2, size_t max_len) {
return CString(fossil_io_cstring_concat_safe(s1.c_str(), s2.c_str(), max_len));
}
/* ---------------- Safe Substring / Reverse / Contains ---------------- */
/**
* @brief Extracts a safe substring from the CString.
*
* Uses secure substring logic to prevent reading beyond the maximum length.
*
* @param start Starting index of the substring.
* @param length Length of the substring.
* @param max_len Maximum number of characters to read from the original string.
* @return A new CString containing the substring.
*/
CString substring_safe(size_t start, size_t length, size_t max_len) const {
return CString(fossil_io_cstring_substring_safe(_str, start, length, max_len));
}
/**
* @brief Reverses the CString safely.
*
* Returns a new CString containing the reverse of the original string
* while respecting the maximum length.
*
* @param max_len Maximum length to process for safety.
* @return A new reversed CString.
*/
CString reverse_safe(size_t max_len) const {
return CString(fossil_io_cstring_reverse_safe(_str, max_len));
}
/**
* @brief Checks if the CString contains a substring safely.
*
* Performs a bounds-checked search within the string.
*
* @param substr The substring to search for.
* @param max_len Maximum number of characters to check.
* @return True if substring is found, false otherwise.
*/
bool contains_safe(const std::string &substr, size_t max_len) const {
return fossil_io_cstring_contains_safe(_str, substr.c_str(), max_len) != 0;
}
/* ---------------- Safe Repeat / Strip / Count ---------------- */
/**
* @brief Repeats the CString a specified number of times safely.
*
* Generates a new CString that repeats the content up to max_len characters.
*
* @param count Number of repetitions.
* @param max_len Maximum total length of the resulting string.
* @return A new repeated CString.
*/
CString repeat_safe(size_t count, size_t max_len) const {
return CString(fossil_io_cstring_repeat_safe(_str, count, max_len));
}
/**
* @brief Strips a character from both ends of the CString safely.
*
* Produces a new CString with leading and trailing characters removed,
* respecting max_len for safety.
*
* @param ch The character to strip.
* @param max_len Maximum number of characters to consider.
* @return A new CString with the character stripped.
*/
CString strip_safe(char ch, size_t max_len) const {
return CString(fossil_io_cstring_strip_safe(_str, ch, max_len));
}
/**
* @brief Counts the number of occurrences of a substring safely.
*
* Uses a secure method that respects maximum string length.
*
* @param substr The substring to count.
* @param max_len Maximum number of characters to process.
* @return Number of occurrences of substr in the CString.
*/
size_t count_safe(const std::string &substr, size_t max_len) const {
return fossil_io_cstring_count_safe(_str, substr.c_str(), max_len);
}
/* ---------------- Safe Padding ---------------- */
/**
* @brief Pads the CString on the left safely.
*
* Ensures the resulting string does not exceed max_len characters.
*
* @param total_length The total desired length after padding.
* @param pad_char Character to pad with.
* @param max_len Maximum allowed length to prevent overflow.
* @return A new left-padded CString.
*/
CString pad_left_safe(size_t total_length, char pad_char, size_t max_len) const {
return CString(fossil_io_cstring_pad_left_safe(_str, total_length, pad_char, max_len));
}
/**
* @brief Pads the CString on the right safely.
*
* Ensures the resulting string does not exceed max_len characters.
*
* @param total_length The total desired length after padding.
* @param pad_char Character to pad with.
* @param max_len Maximum allowed length to prevent overflow.
* @return A new right-padded CString.
*/
CString pad_right_safe(size_t total_length, char pad_char, size_t max_len) const {
return CString(fossil_io_cstring_pad_right_safe(_str, total_length, pad_char, max_len));
}
/* ---------------- Safe Prefix / Suffix ---------------- */
/**
* @brief Checks if the CString starts with a prefix safely.
*
* Considers max_len for safe comparison.
*
* @param prefix The prefix to check.
* @param max_len Maximum number of characters to read.
* @return True if CString starts with prefix, false otherwise.
*/
bool starts_with_safe(const std::string &prefix, size_t max_len) const {
return fossil_io_cstring_starts_with_safe(_str, prefix.c_str(), max_len) != 0;
}
/**
* @brief Checks if the CString ends with a suffix safely.
*
* Considers max_len for safe comparison.
*
* @param suffix The suffix to check.
* @param max_len Maximum number of characters to read.
* @return True if CString ends with suffix, false otherwise.
*/
bool ends_with_safe(const std::string &suffix, size_t max_len) const {
return fossil_io_cstring_ends_with_safe(_str, suffix.c_str(), max_len) != 0;
}
/* ---------------- Safe Equality Checks ---------------- */
/**
* @brief Checks equality safely (case-sensitive).
*
* Compares CString to another string with max_len bounds.
*
* @param other The string to compare.
* @param max_len Maximum characters to compare.
* @return True if equal, false otherwise.
*/
bool equals_safe(const std::string &other, size_t max_len) const {
return fossil_io_cstring_equals_safe(_str, other.c_str(), max_len) != 0;
}
/**
* @brief Checks equality safely (case-insensitive).
*
* Compares CString to another string with max_len bounds, ignoring case.
*
* @param other The string to compare.
* @param max_len Maximum characters to compare.
* @return True if equal ignoring case, false otherwise.
*/
bool iequals_safe(const std::string &other, size_t max_len) const {
return fossil_io_cstring_iequals_safe(_str, other.c_str(), max_len) != 0;
}
/**
* @brief Checks if CString contains a substring safely (case-insensitive).
*
* @param substr Substring to check.
* @param max_len Maximum characters to examine.
* @return True if found, false otherwise.
*/
bool icontains_safe(const std::string &substr, size_t max_len) const {
return fossil_io_cstring_icontains_safe(_str, substr.c_str(), max_len) != 0;
}
/* ---------------- Safe Quotes / Whitespace / Index ---------------- */
/**
* @brief Removes surrounding quotes safely.
*
* Considers max_len and removes only leading/trailing single or double quotes.
*
* @param max_len Maximum characters to process.
* @return A new CString with quotes removed.
*/
CString strip_quotes_safe(size_t max_len) const {
return CString(fossil_io_cstring_strip_quotes_safe(_str, max_len));
}
/**
* @brief Normalizes spaces safely.
*
* Collapses multiple consecutive spaces into one, respecting max_len.
*
* @param max_len Maximum characters to process.
* @return A new CString with normalized spaces.
*/
CString normalize_spaces_safe(size_t max_len) const {
return CString(fossil_io_cstring_normalize_spaces_safe(_str, max_len));
}
/**
* @brief Finds the index of a substring safely.
*
* @param substr Substring to find.
* @param max_len Maximum characters to search.
* @return Index of substring or -1 if not found.
*/
int index_of_safe(const std::string &substr, size_t max_len) const {
return fossil_io_cstring_index_of_safe(_str, substr.c_str(), max_len);
}
/**
* Returns the underlying cstring.
*
* @return The underlying cstring.
*/
cstring str() const {
return _str;
}
};
}
}
#endif
#endif /* FOSSIL_IO_FRAMEWORK_H */SAMPLE CODE C #
#include "fossil/io/cstring.h"
#include <stdio.h>
#include <stdlib.h>
int main(void) {
/* Create and trim a string */
cstring s = fossil_io_cstring_create(" Hello, World! ");
fossil_io_cstring_trim(s);
printf("Trimmed: '%s'\n", s);
/* Case-insensitive search */
if (fossil_io_cstring_icontains(s, "world")) {
printf("Contains 'world' (case-insensitive)\n");
}
/* Replace a substring */
cstring replaced =
fossil_io_cstring_replace(s, "World", "Fossil");
printf("Replaced: %s\n", replaced);
/* Money formatting */
char money[64];
if (fossil_io_cstring_money_to_string_currency(
1234.56, money, sizeof(money), "€") == 0) {
printf("Money: %s\n", money);
}
/* Cleanup */
fossil_io_cstring_free(s);
fossil_io_cstring_free(replaced);
return 0;
}
SAMPLE CODE C++ #
#include "fossil/io/cstring.h"
#include <iostream>
using fossil::io::CString;
int main() {
CString text(" twenty-three dollars ");
/* Normalize and transform */
text.trim();
std::cout << "Text: " << text.silly() << '\n';
/* English number parsing */
int value = CString::number_from_words("twenty-three");
std::cout << "Parsed number: " << value << '\n';
/* Number → words */
std::string words = CString::number_to_words(42);
std::cout << "42 in words: " << words << '\n';
/* Chained transformations */
CString transformed =
text.strip(' ')
.to_upper()
.reverse();
std::cout << "Transformed: "
<< transformed.contains("YTNEW") << '\n';
/* JSON escaping */
CString json("\"hello\nworld\"");
CString escaped = json.escape_json();
std::cout << "Escaped JSON: " << escaped.contains("\\n") << '\n';
/* Money helpers */
std::string money = CString::currency_to_string(9876.54, "$");
double amount = CString::from_currency(money);
std::cout << "Money: " << money
<< " → " << amount << '\n';
return 0; // all memory released via RAII
}