Enlightenment CVS committal Author : moom16 Project : e17 Module : proto
Dir : e17/proto/etk/src/lib Modified Files: etk_string.c etk_string.h Log Message: * Add a string object that make easier string manipulations =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_string.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_string.c 1 Oct 2005 16:29:45 -0000 1.1 +++ etk_string.c 5 Feb 2006 10:28:10 -0000 1.2 @@ -1 +1,541 @@ #include "etk_string.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "etk_utils.h" + +#define ETK_STRING_BLOCK_SIZE 128 +#define ETK_STRING_SIZE_TO_ALLOC(length) (((length) + (ETK_STRING_BLOCK_SIZE - 1)) / ETK_STRING_BLOCK_SIZE) * ETK_STRING_BLOCK_SIZE + +enum _Etk_String_Property_Id +{ + ETK_STRING_STRING_PROPERTY +}; + +static void _etk_string_constructor(Etk_String *string); +static void _etk_string_destructor(Etk_String *string); +static char *_etk_string_vprintf(const char *format, va_list args); + +/** + * @brief Gets the type of an Etk_String + * @return Returns the type on an Etk_String + */ +Etk_Type *etk_string_type_get() +{ + static Etk_Type *string_type = NULL; + + if (!string_type) + { + string_type = etk_type_new("Etk_String", ETK_OBJECT_TYPE, sizeof(Etk_String), ETK_CONSTRUCTOR(_etk_string_constructor), ETK_DESTRUCTOR(_etk_string_destructor)); + etk_type_property_add(string_type, "string", ETK_STRING_STRING_PROPERTY, ETK_PROPERTY_STRING, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_string(NULL)); + } + + return string_type; +} + +/** + * @brief Creates a new string + * @param value the default value of the string. Can be NULL + * @return Returns the new string + */ +Etk_String *etk_string_new(const char *value) +{ + return etk_string_set(ETK_STRING(etk_object_new(ETK_STRING_TYPE, NULL)), value); +} + +/** + * @brief Creates a new string, with a specific size. + * @param value the default value of the string. Can be NULL + * @param size If @a size is lower than the length of @a value, the string will be truncated. @n + * Otherwise, extra memory will be allocated (useful if you planned to insert text often and want to avoid too many reallocations) + * @return Returns the new string + */ +Etk_String *etk_string_new_sized(const char *value, int size) +{ + return etk_string_set_sized(ETK_STRING(etk_object_new(ETK_STRING_TYPE, NULL)), value, size); +} + +/** + * @brief Creates a new string, and sets its default value from the format and the arguments + * @param format the format to set to the string. It uses the same arguments than printf() + * @param ... the arguments corresponding to the format + * @return Returns the new string + */ +Etk_String *etk_string_new_printf(const char *format, ...) +{ + Etk_String *new_string; + va_list args; + + va_start(args, format); + new_string = etk_string_set_vprintf(ETK_STRING(etk_object_new(ETK_STRING_TYPE, NULL)), format, args); + va_end(args); + + return new_string; +} + +/** + * @brief Creates a new string, and sets its default value from the format and the arguments + * @param format the format to set to the string. It uses the same arguments than printf() + * @param args the arguments corresponding to the format + * @return Returns the new string + */ +Etk_String *etk_string_new_vprintf(const char *format, va_list args) +{ + return etk_string_set_vprintf(ETK_STRING(etk_object_new(ETK_STRING_TYPE, NULL)), format, args); +} + +/** + * @brief Creates a new string and copies the text from @a string + * @param string the string to copy + * @return Returns the new copied string + */ +Etk_String *etk_string_copy(const Etk_String *string) +{ + if (!string) + return etk_string_new(NULL); + else + return etk_string_new_sized(string->string, string->allocated_length); +} + +/** + * @param Gets the string as an array of char + * @param string a string + * @param Returns the string as an array of char (a pointer on the first character) + */ +const char *etk_string_get(Etk_String *string) +{ + if (!string) + return NULL; + return string->string; +} + +/** + * @brief Gets the length of the string + * @param string a string + * @return Returns the length of the string + */ +int etk_string_length_get(Etk_String *string) +{ + if (!string) + return 0; + return string->length; +} + +/** + * @brief Truncates the string + * @param string a string + * @param length the new length of the string. If @a length is greater than the current length of the string, the function does nothing + * @return Returns the truncated string + */ +Etk_String *etk_string_truncate(Etk_String *string, int length) +{ + if (!string) + return NULL; + + if (length < string->length) + { + string->string[length] = 0; + string->length = length; + etk_object_notify(ETK_OBJECT(string), "string"); + } + return string; +} + +/** + * @brief Sets the value of a string + * @param string a string + * @param value the value to assign to the string + * @return Returns the string + */ +Etk_String *etk_string_set(Etk_String *string, const char *value) +{ + if (!string) + return NULL; + + if (!value) + etk_string_set_sized(string, NULL, 0); + else + etk_string_set_sized(string, value, strlen(value)); + + return string; +} + +/** + * @brief Sets the value of a string, with a specific size. + * @param string a string + * @param value the value to assign to the string + * @param size If @a size is lower than the length of @a value, the string will be truncated. @n + * Otherwise, extra memory will be allocated (useful if you planned to insert text often and want to avoid too many reallocations) + * @return Returns the string + */ +Etk_String *etk_string_set_sized(Etk_String *string, const char *value, int size) +{ + if (!string) + return NULL; + + if (!value || *value == 0 || size <= 0) + { + *string->string = 0; + string->length = 0; + } + else + { + int length; + + if (size > string->allocated_length) + { + free(string->string); + string->string = malloc(ETK_STRING_SIZE_TO_ALLOC(size) + 1); + string->allocated_length = ETK_STRING_SIZE_TO_ALLOC(size); + } + + length = strlen(value); + string->length = ETK_MIN(length, size); + strncpy(string->string, value, string->length); + string->string[string->length] = 0; + } + + etk_object_notify(ETK_OBJECT(string), "string"); + return string; +} + +/** + * @brief Sets the value of the string from the format and the arguments + * @param string a string + * @param format the format to set to the string. It uses the same arguments than printf() + * @param ... the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_set_printf(Etk_String *string, const char *format, ...) +{ + va_list args; + + if (!string) + return NULL; + + va_start(args, format); + etk_string_set_vprintf(string, format, args); + va_end(args); + + return string; +} + +/** + * @brief Sets the value of the string from the format and the arguments + * @param string a string + * @param format the format to set to the string. It uses the same arguments than printf() + * @param args the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_set_vprintf(Etk_String *string, const char *format, va_list args) +{ + va_list args2; + char *text; + + if (!string) + return NULL; + + va_copy(args2, args); + text = _etk_string_vprintf(format, args); + etk_string_set(string, text); + free(text); + va_end(args2); + + return string; +} + +/** + * @brief Prepends a text to a string + * @param string a string + * @param text the text to prepend to the string + * @return Returns the string + */ +Etk_String *etk_string_prepend(Etk_String *string, const char *text) +{ + return etk_string_insert(string, 0, text); +} + +/** + * @brief Prepends a character to a string + * @param string a string + * @param c the character to prepend to the string + * @return Returns the string + */ +Etk_String *etk_string_prepend_char(Etk_String *string, char c) +{ + return etk_string_insert_char(string, 0, c); +} + +/** + * @brief Prepends a text to a string from the format and the arguments + * @param string a string + * @param format the format to prepend to the string. It uses the same arguments than printf() + * @param ... the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_prepend_printf(Etk_String *string, const char *format, ...) +{ + va_list args; + + if (!string) + return NULL; + + va_start(args, format); + etk_string_prepend_vprintf(string, format, args); + va_end(args); + + return string; +} + +/** + * @brief Prepends a text to a string from the format and the arguments + * @param string a string + * @param format the format to prepend to the string. It uses the same arguments than printf() + * @param args the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_prepend_vprintf(Etk_String *string, const char *format, va_list args) +{ + va_list args2; + + if (!string) + return NULL; + + va_copy(args2, args); + etk_string_insert_vprintf(string, 0, format, args2); + va_end(args2); + + return string; +} + +/** + * @brief Appends a text to a string + * @param string a string + * @param text the text to append to the string + * @return Returns the string + */ +Etk_String *etk_string_append(Etk_String *string, const char *text) +{ + return etk_string_insert(string, string->length, text); +} + +/** + * @brief Appends a character to a string + * @param string a string + * @param c the character to append to the string + * @return Returns the string + */ +Etk_String *etk_string_append_char(Etk_String *string, char c) +{ + return etk_string_insert_char(string, string->length, c); +} + +/** + * @brief Appends a text to a string from the format and the arguments + * @param string a string + * @param format the format to append to the string. It uses the same arguments than printf() + * @param ... the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_append_printf(Etk_String *string, const char *format, ...) +{ + va_list args; + + if (!string) + return NULL; + + va_start(args, format); + etk_string_append_vprintf(string, format, args); + va_end(args); + + return string; +} + +/** + * @brief Appends a text to a string from the format and the arguments + * @param string a string + * @param format the format to append to the string. It uses the same arguments than printf() + * @param args the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_append_vprintf(Etk_String *string, const char *format, va_list args) +{ + va_list args2; + + if (!string) + return NULL; + + va_copy(args2, args); + etk_string_insert_vprintf(string, string->length, format, args2); + va_end(args2); + + return string; +} + +/** + * @brief Inserts a text into a string + * @param string a string + * @param pos the position where to insert the text + * @param text the text to insert into the string + * @return Returns the string + */ +Etk_String *etk_string_insert(Etk_String *string, int pos, const char *text) +{ + int length; + int i; + + if (!string) + return NULL; + if (!text || *text == 0) + return string; + + pos = ETK_CLAMP(pos, 0, string->length); + length = strlen(text); + if (string->length + length > string->allocated_length) + { + string->string = realloc(string->string, ETK_STRING_SIZE_TO_ALLOC(string->length + length) + 1); + string->allocated_length = ETK_STRING_SIZE_TO_ALLOC(string->length + length); + } + for (i = string->length - 1; i >= pos; i--) + string->string[i + length] = string->string[i]; + + strncpy(&string->string[pos], text, length); + string->length += length; + string->string[string->length] = 0; + + etk_object_notify(ETK_OBJECT(string), "string"); + + return string; +} + +/** + * @brief Inserys a character into a string + * @param string a string + * @param pos the positon where to insert the char + * @param c the character to insert into the string + * @return Returns the string + */ +Etk_String *etk_string_insert_char(Etk_String *string, int pos, char c) +{ + int i; + + if (!string) + return NULL; + if (c == 0) + return etk_string_truncate(string, pos); + + pos = ETK_CLAMP(pos, 0, string->length); + if (string->length + 1 > string->allocated_length) + { + string->string = realloc(string->string, ETK_STRING_SIZE_TO_ALLOC(string->length + 1) + 1); + string->allocated_length = ETK_STRING_SIZE_TO_ALLOC(string->length + 1); + } + for (i = string->length - 1; i >= pos; i--) + string->string[i + 1] = string->string[i]; + + string->string[pos] = c; + string->length++; + string->string[string->length] = 0; + + etk_object_notify(ETK_OBJECT(string), "string"); + + return string; +} + +/** + * @brief Inserts a text into a string from the format and the arguments + * @param string a string + * @param pos the positon where to insert the char + * @param format the format to insert into the string. It uses the same arguments than printf() + * @param ... the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_insert_printf(Etk_String *string, int pos, const char *format, ...) +{ + va_list args; + + if (!string) + return NULL; + + va_start(args, format); + etk_string_insert_vprintf(string, pos, format, args); + va_end(args); + + return string; +} + +/** + * @brief Inserts a text into a string from the format and the arguments + * @param string a string + * @param pos the positon where to insert the char + * @param format the format to insert into the string. It uses the same arguments than printf() + * @param args the arguments corresponding to the format + * @return Returns the string + */ +Etk_String *etk_string_insert_vprintf(Etk_String *string, int pos, const char *format, va_list args) +{ + va_list args2; + char *text_to_append; + + if (!string) + return NULL; + + va_copy(args2, args); + text_to_append = _etk_string_vprintf(format, args2); + etk_string_insert(string, pos, text_to_append); + free(text_to_append); + va_end(args2); + + return string; +} + +/************************** + * + * Etk specific functions + * + **************************/ + +/* Initializes the default values of the string */ +static void _etk_string_constructor(Etk_String *string) +{ + if (!string) + return; + + string->string = strdup(""); + string->length = 0; + string->allocated_length = 0; +} + +/* Frees the string */ +static void _etk_string_destructor(Etk_String *string) +{ + if (!string) + return; + free(string->string); +} + +/************************** + * + * Private functions + * + **************************/ + +/* Creates a new string (char *) from the format and the args, and returns it. The returned string will have to be freed */ +static char *_etk_string_vprintf(const char *format, va_list args) +{ + char c; + char *text; + va_list args2; + int length; + + if (!format) + return NULL; + + va_copy(args2, args); + length = vsnprintf(&c, 1, format, args2); + text = malloc(length + 1); + vsprintf(text, format, args2); + va_end(args2); + + return text; +} =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_string.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_string.h 1 Oct 2005 16:29:45 -0000 1.1 +++ etk_string.h 5 Feb 2006 10:28:10 -0000 1.2 @@ -1,11 +1,23 @@ +/** @file etk_string.h */ #ifndef _ETK_STRING_H_ #define _ETK_STRING_H_ +#include "etk_object.h" +#include <stdarg.h> +#include "etk_types.h" + /** * @defgroup Etk_String Etk_String * @{ */ +/** @brief Gets the type of a string */ +#define ETK_STRING_TYPE (etk_string_type_get()) +/** @brief Casts the object to an Etk_String */ +#define ETK_STRING(obj) (ETK_OBJECT_CAST((obj), ETK_STRING_TYPE, Etk_String)) +/** @brief Checks if the object is an Etk_Text_Buffer */ +#define ETK_IS_STRING(obj) (ETK_OBJECT_CHECK_TYPE((obj), ETK_STRING_TYPE)) + /** * @struct Etk_String * @brief An Etk_String is an easy way to manipulate a string @@ -13,9 +25,44 @@ struct _Etk_String { /* private: */ + /* Inherit from Etk_Object */ + Etk_Object object; + char *string; + int length; + int allocated_length; }; +Etk_String *etk_string_new(const char *value); +Etk_String *etk_string_new_sized(const char *value, int size); +Etk_String *etk_string_new_printf(const char *format, ...); +Etk_String *etk_string_new_vprintf(const char *format, va_list args); +Etk_String *etk_string_copy(const Etk_String *string); + +const char *etk_string_get(Etk_String *string); +int etk_string_length_get(Etk_String *string); +Etk_String *etk_string_truncate(Etk_String *string, int length); + +Etk_String *etk_string_set(Etk_String *string, const char *value); +Etk_String *etk_string_set_sized(Etk_String *string, const char *value, int size); +Etk_String *etk_string_set_printf(Etk_String *string, const char *format, ...); +Etk_String *etk_string_set_vprintf(Etk_String *string, const char *format, va_list args); + +Etk_String *etk_string_prepend(Etk_String *string, const char *text); +Etk_String *etk_string_prepend_char(Etk_String *string, char c); +Etk_String *etk_string_prepend_printf(Etk_String *string, const char *format, ...); +Etk_String *etk_string_prepend_vprintf(Etk_String *string, const char *format, va_list args); + +Etk_String *etk_string_append(Etk_String *string, const char *text); +Etk_String *etk_string_append_char(Etk_String *string, char c); +Etk_String *etk_string_append_printf(Etk_String *string, const char *format, ...); +Etk_String *etk_string_append_vprintf(Etk_String *string, const char *format, va_list args); + +Etk_String *etk_string_insert(Etk_String *string, int pos, const char *text); +Etk_String *etk_string_insert_char(Etk_String *string, int pos, char c); +Etk_String *etk_string_insert_printf(Etk_String *string, int pos, const char *format, ...); +Etk_String *etk_string_insert_vprintf(Etk_String *string, int pos, const char *format, va_list args); + /** @} */ #endif ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs