update documentation(doxygen).

This commit is contained in:
bossiel 2010-02-25 19:03:32 +00:00
parent 70d57ea547
commit 6f8afbbd7a
33 changed files with 552 additions and 530 deletions

View File

@ -1,4 +1,4 @@
# Doxyfile 1.6.1
# Doxyfile 1.6.3
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
@ -397,6 +397,12 @@ HIDE_SCOPE_NAMES = YES
SHOW_INCLUDE_FILES = YES
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
# rather than with sharp brackets.
FORCE_LOCAL_INCLUDES = NO
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
@ -838,6 +844,12 @@ HTML_FOOTER = footer.html
HTML_STYLESHEET =
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
@ -939,7 +951,7 @@ QCH_FILE =
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace
QHP_NAMESPACE =
QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
@ -971,6 +983,23 @@ QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
# will be generated, which together with the HTML files, form an Eclipse help
# plugin. To install this plugin and make it available under the help contents
# menu in Eclipse, the contents of the directory containing the HTML and XML
# files needs to be copied into the plugins directory of eclipse. The name of
# the directory within the plugins directory should be the same as
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
# this name.
ECLIPSE_DOC_ID = org.doxygen.Project
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
@ -1011,15 +1040,26 @@ TREEVIEW_WIDTH = 250
FORMULA_FONTSIZE = 10
# When the SEARCHENGINE tag is enable doxygen will generate a search box
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
# there is already a search function so this one should typically
# be disabled.
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
# (GENERATE_DOCSET) there is already a search function so this one should
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvances is that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
@ -1036,7 +1076,10 @@ GENERATE_LATEX = NO
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.
LATEX_CMD_NAME = latex

View File

@ -2,6 +2,6 @@
<head></head>
<body>
<hr>
<b>TinySAK 1.0</b> - Copyright (C) 2009 Mamadou Diop. All rights reserved. Licensed under the terms of the GNU General Public License v3.
<b>doubango project - TinySAK 1.0</b> - Copyright (C) 2009-2010 Mamadou DIOP. All rights reserved. Licensed under the terms of the GNU General Public License v3.
</body>
</html>

View File

@ -28,16 +28,18 @@
*
* This file is an overview of TinySAK API.
*
* TinySAK (aka Tiny Swiss Army Knife) is a tiny but fully featured utility API.
* This API is designed to efficiently work on embedded systems whith limited memory
* and low computing power.
* TinySAK (a.k.a <b>T</b>iny <b>S</b>wiss <b>A</b>rmy <b>K</b>nife) is a tiny but fully featured utility API.
* This API is designed to efficiently work on embedded systems whith limited memory and low computing power.<br>
* This library provide a base object class to ease Object Oriented Programming in C. There are many other
* features like multi-threading, time management, encoding, encryption or content management.
*
* @par Getting Started
*
* - @ref tsk_list_page
* - @ref tsk_heap_page
* - @ref tsk_memory_page
* - @ref tsk_string_page
* - @ref tsk_object_group
* - @ref tsk_base64_group
* - @ref tsk_binaryutils_group
* - @ref tsk_buffer_group
* - @ref tsk_condwait_group
*
* @par Supported Systems
*

View File

@ -37,7 +37,6 @@ TSK_BEGIN_DECLS
#include "tsk_list.h"
#include "tsk_string.h"
#include "tsk_heap.h"
#include "tsk_buffer.h"
#include "tsk_memory.h"
#include "tsk_url.h"
@ -54,7 +53,6 @@ TSK_BEGIN_DECLS
#include "tsk_safeobj.h"
#include "tsk_object.h"
#include "tsk_macros.h"
#include "tsk_debug.h"
#include "tsk_ppfcs16.h"

View File

@ -31,11 +31,16 @@
#include "tsk_memory.h"
/**@defgroup tsk_base64_group Base64 encoder/decoder as per RFC 4648.
* @brief Provides base64 encoder and decoder functions.
*/
/** Pad char.*/
#define TSK_BASE64_PAD '='
#define TSK_IS_BASE64(c) ( isalnum((c)) || ((c) == '+') || ((c) == '/') )
/** Encoding block size. */
#define TSK_BASE64_ENCODE_BLOCK_SIZE 3 /* 24-bit input group */
/** Decoding block size. */
#define TSK_BASE64_DECODE_BLOCK_SIZE 4
/*==================================================================
@ -61,16 +66,16 @@
RFC 4548 - Table 1: The Base 64 Alphabet
*/
/**
/**@ingroup tsk_base64_group
* Encodes arbitrary data into base64 format.
* @param input The input data to encode in base64 format.
* @param input_size The size of the @ref input data.
* @param input_size The size of the @a input data.
* @param output A pointer where to copy the encoded data.
* If you don't know what will be the size of the output result then set the pointer value to NULL to let the function allocate it of you.
* If @ref output is NULL then it will be up to you to free the allocated buffer.
* In all case it is up to you to free the @a ouput.
* You can also use @ref TSK_BASE64_ENCODE_LEN to allocate the buffer before calling this method.
*
* @retval The size of the encoded data (sizeof(@ref output))
* @retval The size of the encoded data (sizeof(@a output))
*/
size_t tsk_base64_encode(const uint8_t* input, size_t input_size, char **output)
{
@ -140,16 +145,16 @@ quantum:
return output_size;
}
/**
/**@ingroup tsk_base64_group
* Decodes arbitrary base64 data.
* @param input The input base64 data to decode.
* @param input_size The size of the @ref input data.
* @param input_size The size of the @a input data.
* @param output A pointer where to copy the decoded data.
* If you don't know what will be the size of the output result then set the pointer value to NULL to let the function allocate it of you.
* If @ref output is NULL then it will be up to you to free the allocated buffer.
* In all case it is up to you to free the @a ouput.
* You can also use @ref TSK_BASE64_DECODE_LEN to allocate the buffer before calling this method.
*
* @retval The size of the decoded data (sizeof(@ref output))
* @retval The size of the decoded data (sizeof(@a output))
*/
size_t tsk_base64_decode(const uint8_t* input, size_t input_size, char **output)
{

View File

@ -34,7 +34,15 @@
TSK_BEGIN_DECLS
/**@ingroup tsk_base64_group
* Guess the output(encoded) size.
* @param IN_LEN The input size.
*/
#define TSK_BASE64_ENCODE_LEN(IN_LEN) ((2 + (IN_LEN) - (((IN_LEN) + 2) % 3)) * 4 / 3)
/**@ingroup tsk_base64_group
* Guess the output(decoded) size.
* @param IN_LEN The input size.
*/
#define TSK_BASE64_DECODE_LEN(IN_LEN) (((IN_LEN * 3)/4) + 2)
TINYSAK_API size_t tsk_base64_encode(const uint8_t* input, size_t input_size, char **output);

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_binaryutils.c
* @brief Binary utils
* @brief Utility functions for binary manipulation.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -29,3 +29,5 @@
*/
#include "tsk_binaryutils.h"
/**@defgroup tsk_binaryutils_group Binary utility functions.
*/

View File

@ -36,17 +36,39 @@
TSK_BEGIN_DECLS
/**@ingroup tsk_binaryutils_group
* Reverse (bit per bit) a 2-byte value.
* @param value The 2-byte value to reverse.
*/
#define TSK_BINARY_REVERSE_2BYTE(value) ((Tsk_BitReverseTable256[value & 0xff] << 8) | (Tsk_BitReverseTable256[(value >> 8)]))
/**@ingroup tsk_binaryutils_group
* Converts to uint8_t pointer.
*/
#define TSK_TO_U8(buffer) ((uint8_t*)buffer)
/**@ingroup tsk_binaryutils_group
* Gets the value of the fist byte.
*/
#define TSK_BINARY_GET_1BYTE(buffer) *TSK_TO_U8(buffer)// 1-byte
/**@ingroup tsk_binaryutils_group
* Converts from Little to Big endian.
*/
static uint16_t TSK_LSB_2_MSB( void const * buffer )
{
const uint8_t* dummy = (const uint8_t*)buffer;
return ( ((uint16_t)dummy[0] << 8) | dummy[1] );
}
/**@ingroup tsk_binaryutils_group
* @def TSK_BINARY_GET_2BYTES
* Gets the first 2-bytes value.
*/
/**@ingroup tsk_binaryutils_group
* @def TSK_BINARY_SET_2BYTES
* Sets the first 2-bytes value.
*/
#if 0 /*BIG_ENDIAN*/// Do not change this (it's for my own tests)
# define TSK_BINARY_GET_2BYTES(buffer) *((uint16_t*)buffer)
# define TSK_BINARY_SET_2BYTES(buffer, value) *((uint16_t*)buffer)=value
@ -106,6 +128,9 @@ static const int8_t operand_multitype_indexes [256] =
};
// Used LSB<->MSB bits reverse/swap
/**@ingroup tsk_binaryutils_group
* Lookup table for bit reversing.
*/
static const unsigned char Tsk_BitReverseTable256[] =
{
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_buffer.c
* @brief Data buffer.
* @brief Buffer manager.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -33,10 +33,28 @@
#include <stdio.h>
#include <string.h>
/**@defgroup tsk_buffer_group Buffer management.
*/
#if defined(_MSC_VER) || TSK_UNDER_WINDOWS
# define vsnprintf _vsnprintf
#endif
/**@ingroup tsk_buffer_group
* Appends new data to the buffer.
* @param self The buffer to append to. The buffer should be created using @ref TSK_BUFFER_CREATE or @ref TSK_BUFFER_CREATE_NULL.
* @param format A string with embedded tag to be substituted.
* @param ... List of parameters.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_buffer_append.
*
* @code
* tsk_buffer_t* buffer = TSK_BUFFER_CREATE_NULL();
* tsk_buffer_appendEx(buffer, "str1=%s, c1=%c and val1=%x", "str1", 'c', 0x2554);
* printf(TSK_BUFFER_TO_STRING(buffer));
* TSK_OBJECT_SAFE_FREE(buffer);
* @endcode
*/
int tsk_buffer_appendEx(tsk_buffer_t* self, const char* format, ...)
{
/*
@ -47,8 +65,7 @@ int tsk_buffer_appendEx(tsk_buffer_t* self, const char* format, ...)
char *buffer;
size_t oldsize;
if(!self)
{
if(!self){
return -1;
}
@ -98,7 +115,21 @@ int tsk_buffer_appendEx(tsk_buffer_t* self, const char* format, ...)
return 0;
}
/**@ingroup tsk_buffer_group
* Appends data to the buffer.
* @param self The buffer to append to. The buffer should be created using @ref TSK_BUFFER_CREATE or @ref TSK_BUFFER_CREATE_NULL.
* @param data The data to append to the buffer.
* @param size The size of the @a data to append.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_buffer_appendEx.
*
* @code
* tsk_buffer_t* buffer = TSK_BUFFER_CREATE_NULL();
* tsk_buffer_append(buffer, "doubango", strlen("doubango"));
* printf(TSK_BUFFER_TO_STRING(buffer));
* TSK_OBJECT_SAFE_FREE(buffer);
* @endcode
*/
int tsk_buffer_append(tsk_buffer_t* self, const void* data, size_t size)
{
if(self && size)
@ -117,6 +148,12 @@ int tsk_buffer_append(tsk_buffer_t* self, const void* data, size_t size)
return -1;
}
/**@ingroup tsk_buffer_group
* Reallocates the buffer.
* @param self The buffer to realloc.
* @param size The new size.
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tsk_buffer_realloc(tsk_buffer_t* self, size_t size)
{
if(self)
@ -138,6 +175,13 @@ int tsk_buffer_realloc(tsk_buffer_t* self, size_t size)
return -1;
}
/**@ingroup tsk_buffer_group
* Removes a chunck of data from the buffer.
* @param self The buffer from which to remove the chunck.
* @param position The chunck start position.
* @param size The size of the chunck.
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tsk_buffer_remove(tsk_buffer_t* self, size_t position, size_t size)
{
if(self)
@ -156,7 +200,15 @@ int tsk_buffer_remove(tsk_buffer_t* self, size_t position, size_t size)
return -1;
}
int tsk_buffer_insert(tsk_buffer_t* self, size_t position, const void*data, size_t size)
/**@ingroup tsk_buffer_group
* Inserts a chunck of data into the buffer.
* @param self The buffer to insert to.
* @param position The starting position to insert to.
* @param data A pointer to the chunck to insert.
* @param size The size of the chunck.
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tsk_buffer_insert(tsk_buffer_t* self, size_t position, const void* data, size_t size)
{
if(self && size)
{
@ -184,10 +236,14 @@ int tsk_buffer_insert(tsk_buffer_t* self, size_t position, const void*data, size
return -1;
}
/**@ingroup tsk_buffer_group
* Cleanups the internal data and reset the size..
* @param self The buffer holding the internal data to free.
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tsk_buffer_cleanup(tsk_buffer_t* self)
{
if(self && self->data)
{
if(self && self->data){
tsk_free(&(self->data));
self->size = 0;
}

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_buffer.h
* @brief Data buffer.
* @brief Buffer manager.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -33,28 +33,71 @@
#include "tinySAK_config.h"
#include "tsk_list.h"
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_CREATE
* Creates new buffer.
* @param data A pointer to the data to copy into the newly created buffer.
* @param size The size of the data to copy.
* @retval A new buffer object.
* @sa TSK_BUFFER_CREATE_NULL.
*/
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_CREATE_NULL
* Creates a new empty buffer.
* @retval A new empty buffer object.
* @sa TSK_BUFFER_CREATE.
*/
TSK_BEGIN_DECLS
#define TSK_BUFFER_CREATE(data, size) tsk_object_new(tsk_buffer_def_t, (const void*)data, (size_t)size)
#define TSK_BUFFER_CREATE_NULL() TSK_BUFFER_CREATE(0,0)
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER
* Converts to @ref tsk_buffer_t object.
* @param self @ref tsk_buffer_t object.
*/
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_DATA
* Gets the internal buffer.
* @param self @ref tsk_buffer_t object.
*/
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_SIZE
* Gets the size of the internal buffer.
* @param self @ref tsk_buffer_t object.
*/
#define TSK_BUFFER(self) ((tsk_buffer_t*)self)
#define TSK_BUFFER_DATA(self) (self ? TSK_BUFFER(self)->data : 0)
#define TSK_BUFFER_SIZE(self) (self ? TSK_BUFFER(self)->size : 0)
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_TO_STRING
* Gets a the internal buffer as a pointer to a string (const char*).
* @param self @ref tsk_buffer_t object.
*/
/**@ingroup tsk_buffer_group
* @def TSK_BUFFER_TO_U8
* Gets a the internal buffer as a pointer to an unsigned string (uint8_t*).
* @param self @ref tsk_buffer_t object.
*/
#define TSK_BUFFER_TO_STRING(self) (self ? (const char*)TSK_BUFFER_DATA(self) : 0)
#define TSK_BUFFER_TO_U8(self) (self ? (uint8_t*)TSK_BUFFER_DATA(self) : 0)
/**@ingroup tsk_buffer_group
* Buffer object.
*/
typedef struct tsk_buffer_s
{
TSK_DECLARE_OBJECT;
void *data;
size_t size;
void *data; /**< Interanl data. */
size_t size; /**< The size of the internal data. */
}
tsk_buffer_t;
typedef tsk_list_t tsk_buffers_L_t; /**< List of @ref tsk_buffer_t elements. */
typedef tsk_list_t tsk_buffers_L_t; /**<@ingroup tsk_buffer_group List of @ref tsk_buffer_t elements. */
TINYSAK_API int tsk_buffer_appendEx(tsk_buffer_t* self, const char* format, ...);
TINYSAK_API int tsk_buffer_append(tsk_buffer_t* self, const void* data, size_t size);

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_condwait.c
* @brief Pthread CondWait
* @brief Pthread/Windows functions for waiting an signaling on condition variables.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -31,7 +31,6 @@
#include "tsk_condwait.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
#include "tsk_macros.h"
#include "tsk_time.h"
#include <time.h>
@ -53,25 +52,44 @@
# include <errno.h>
#endif
/**@defgroup tsk_condwait_group Pthread CondWait
/**@defgroup tsk_condwait_group Pthread/Windows functions for waiting and signaling on condition variables (conwait).
* @code
* tsk_condwait_handle_t *condwait = tsk_condwait_create();
* @endcode
*
* In thread-1:
* @code
* // Bock the current thread until the condition is opened or until 1000ms have passed.
* int ret = tsk_condwait_timedwait(condwait, 1000);
* @endcode
*
* In thread-2:
* @code
* // Wakes up
* int ret = tsk_condwait_signal(condwait);
* // or tsk_condwait_broadcast(condwait)
* @endcode
*
* To free the condwait object:
* @code
* tsk_condwait_destroy(&condwait);
* @endcode
*/
/** Pthread CondWait.
/**@ingroup tsk_condwait_group
* Represents both PThread an Windows condwait object.
*/
typedef struct tsk_condwait_s
{
CONDWAIT_T pcond; /**< Handle pointing to the condwait */
CONDWAIT_T pcond; /**< Pthread handle pointing to the internal condwait object. */
#if !TSK_UNDER_WINDOWS
tsk_mutex_handle_t* mutex; /**< Locker*/
tsk_mutex_handle_t* mutex; /**< Locker. */
#endif
}
tsk_condwait_t;
/**@ingroup tsk_condwait_group
* Creates new Pthread conwait handle. You MUST call @ref tsk_condwait_destroy to free the handle.
* Creates new conwait handle. You MUST call @ref tsk_condwait_destroy to free the handle.
* @retval New condwait handle.
* @sa @ref tsk_condwait_destroy.
*/
@ -112,7 +130,7 @@ tsk_condwait_handle_t* tsk_condwait_create()
}
/**@ingroup tsk_condwait_group
* Wait for a condition indefinitely.
* Block the current thread until the condition is opened.
* @param handle CondWait handle created using @ref tsk_condwait_create.
* @retval Zero if succeed and non-zero otherwise.
* @sa @ref tsk_condwait_timedwait.
@ -123,13 +141,11 @@ int tsk_condwait_wait(tsk_condwait_handle_t* handle)
tsk_condwait_t *condwait = (tsk_condwait_t*)handle;
#if TSK_UNDER_WINDOWS
if((ret = (WaitForSingleObject(condwait->pcond, INFINITE) == WAIT_FAILED) ? -1 : 0))
{
if((ret = (WaitForSingleObject(condwait->pcond, INFINITE) == WAIT_FAILED) ? -1 : 0)){
TSK_DEBUG_ERROR("WaitForSingleObject function failed: %d", ret);
}
#else
if(condwait && condwait->mutex)
{
if(condwait && condwait->mutex){
tsk_mutex_lock(condwait->mutex);
if(ret = pthread_cond_wait(condwait->pcond, (pthread_mutex_t*)condwait->mutex))
{
@ -142,10 +158,10 @@ int tsk_condwait_wait(tsk_condwait_handle_t* handle)
}
/**@ingroup tsk_condwait_group
* Wait for a condition @ref ms milliseconds.
* @param handle CondWait context created using @ref tsk_condwait_create.
* Block the current thread until the condition is opened or until @a ms milliseconds have passed.
* @param handle condwait handle created using @ref tsk_condwait_create.
* @param ms The number of milliseconds to wait for a given condition.
* @retval Zero if succeed or @ref ETIMEDOUT if timedout and non-zero otherwise.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_condwait_wait.
*/
int tsk_condwait_timedwait(tsk_condwait_handle_t* handle, uint64_t ms)
@ -160,12 +176,10 @@ int tsk_condwait_timedwait(tsk_condwait_handle_t* handle, uint64_t ms)
#if TSK_UNDER_WINDOWS
if((ret = WaitForSingleObject(condwait->pcond, (DWORD)ms)) != WAIT_OBJECT_0)
{
if(ret == TIMED_OUT)
{
if(ret == TIMED_OUT){
//TSK_DEBUG_INFO("WaitForSingleObject function timedout: %d", ret);
}
else
{
else{
TSK_DEBUG_ERROR("WaitForSingleObject function failed: %d", ret);
}
return (ret == TIMED_OUT ? 0 : ret);
@ -204,7 +218,7 @@ int tsk_condwait_timedwait(tsk_condwait_handle_t* handle, uint64_t ms)
}
/**@ingroup tsk_condwait_group
* Wakes up at least one thread that is currently waiting on @ref condwait variable.
* Wakes up at least one thread that is currently waiting.
* @param handle CondWait handle created using @ref tsk_condwait_create.
* @retval Zero if succeed and non-zero otherwise.
* @sa @ref tsk_condwait_broadcast.
@ -215,14 +229,12 @@ int tsk_condwait_signal(tsk_condwait_handle_t* handle)
tsk_condwait_t *condwait = (tsk_condwait_t*)handle;
#if TSK_UNDER_WINDOWS
if(ret = ((SetEvent(condwait->pcond) && ResetEvent(condwait->pcond)) ? 0 : -1))
{
if(ret = ((SetEvent(condwait->pcond) && ResetEvent(condwait->pcond)) ? 0 : -1)){
ret = GetLastError();
TSK_DEBUG_ERROR("SetEvent/ResetEvent function failed: %d", ret);
}
#else
if(condwait && condwait->mutex)
{
if(condwait && condwait->mutex){
tsk_mutex_lock(condwait->mutex);
if(ret = pthread_cond_signal(condwait->pcond))
@ -235,23 +247,9 @@ int tsk_condwait_signal(tsk_condwait_handle_t* handle)
return ret;
}
///**@ingroup tsk_condwait_group
//* Gets the internal mutex used by the CondWait object.
//* @param handle The CondWait object holding the mutex.
//* @retval The internal mutex.
//*/
//tsk_mutex_handle_t* tsk_condwait_get_mutex(tsk_condwait_handle_t* handle)
//{
// tsk_condwait_t *condwait = (tsk_condwait_t*)handle;
// if(condwait)
// {
// return condwait->mutex;
// }
// return 0;
//}
/**@ingroup tsk_condwait_group
* Wakes up all threads that are currently waiting on @ref condwait variable.
* Wakes up all threads that are currently waiting for the condition.
* @param handle CondWait handle created using @ref tsk_condwait_create.
* @retval Zero if succeed and non-zero otherwise.
* @sa @ref tsk_condwait_signal.
@ -283,7 +281,7 @@ int tsk_condwait_broadcast(tsk_condwait_handle_t* handle)
}
/**@ingroup tsk_condwait_group
* Destroy/Free a condwait variable previously created using @ref tsk_condwait_create.
* Safely free a condwait variable previously created using @ref tsk_condwait_create.
* @param handle The condwait handle to free.
* @sa @ref tsk_condwait_create
*/
@ -291,8 +289,7 @@ void tsk_condwait_destroy(tsk_condwait_handle_t** handle)
{
tsk_condwait_t **condwait = (tsk_condwait_t**)handle;
if(condwait && *condwait)
{
if(condwait && *condwait){
#if TSK_UNDER_WINDOWS
CloseHandle((*condwait)->pcond);
#else
@ -302,8 +299,7 @@ void tsk_condwait_destroy(tsk_condwait_handle_t** handle)
#endif
tsk_free((void**)condwait);
}
else
{
else{
TSK_DEBUG_WARN("Cannot free an uninitialized condwait object");
}
}

View File

@ -35,8 +35,8 @@
TSK_BEGIN_DECLS
/**
* Pthread condwait handle.
/**@ingroup tsk_condwait_group
* An opaque handle to a condwait object.
*/
typedef void tsk_condwait_handle_t;

View File

@ -1,108 +0,0 @@
///*
//* Copyright (C) 2009 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
//*/
//
///**@file tsk_heap.c
// * @brief Useful string functions to manipulate strings.
// *
// * @author Mamadou Diop <diopmamadou(at)yahoo.fr>
// *
// * @date Created: Sat Nov 8 16:54:58 2009 mdiop
// */
//#include "tsk_heap.h"
//#include "tsk_memory.h"
//#include "tsk_debug.h"
//#include "tsk_macros.h"
//#include <stdlib.h>
//
///**@defgroup tsk_heap_group Memory heap
//*/
//
///**@page tsk_heap_page Heap Management Tutorial
//*/
//
///**@ingroup tsk_heap_group
//* Predicate function used to retrive an address by ref
//*/
//static int tsk_heap_find_by_address(const tsk_heap_address_t* item, const void* address)
//{
// return (item->data == address) ? 1 : 0;
//}
//
///**@ingroup tsk_heap_group
//* Initialize a memory heap. You MUST call this method before using the your heap memory.
//* @param heap the memory heap to initialize
//*/
///*void tsk_heap_init(tsk_heap_t *heap)
//{
// tsk_list_init(&heap->pool);
//}*/
//
///**@ingroup tsk_heap_group
//* Push new variable address into the heap
//* @param heap the heap into which to push the address
//* @param address the address to insert into the heap
//*/
//void tsk_heap_push(tsk_heap_t *heap, void * address)
//{
// tsk_heap_address_t *item;
//
// TSK_LIST_ITEM_CREATE(item);
// item->data = address;
// item->func_free = 0;
// tsk_list_add_item(&heap->pool, &item);
//}
//
///**@ingroup tsk_heap_group
//* Pop an address from the heap and free the corresponding memory
//* @param heap the heap from which to pop the address
//* @param address the address to pop from the heap
//*/
//void tsk_heap_pop(tsk_heap_t *heap, void * address)
//{
// tsk_list_remove_item2(&heap->pool, tsk_heap_find_by_address, (const void*)address);
//}
//
///**@ingroup tsk_heap_group
//* Free all addresses from the heap
//*/
//void tsk_heap_cleanup(tsk_heap_t *heap)
//{
// if(heap)
// {
// tsk_list_item_t* next = 0;
// tsk_heap_pool_t *pool = &heap->pool;
// tsk_list_item_t* curr = pool->head;
//
// while(curr)
// {
// next = curr->next;
// tsk_list_item_free(&curr);
// curr = next;
// }
// pool->head = 0;
// }
// else
// {
// TSK_DEBUG_WARN("Cannot cleanup an uninitialized heap object");
// }
//}

View File

@ -1,71 +0,0 @@
///*
//* Copyright (C) 2009 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
//*/
//
///**@file tsk_heap.h
//* @brief Useful string functions to manipulate strings.
//*
//* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
//*
//* @date Created: Sat Nov 8 16:54:58 2009 mdiop
//*/
//#ifndef _TINYSAK_HEAP_H_
//#define _TINYSAK_HEAP_H_
//
//#include "tinySAK_config.h"
//#include "tsk_list.h"
//#include "tsk_object.h"
//
///**@typedef tsk_heap_pool_t
//* Memory heap pool containing all aloocated variables.
//*/
//typedef tsk_list_t tsk_heap_pool_t;
//
///**@typedef tsk_heap_address_t
//* The address of one variable allocated on the heap memory.
//*/
//typedef tsk_list_item_t tsk_heap_address_t;
//
///** Defines the memory on which all variables will be allocated.
//* You must only allocate scalar variables on the heap memory otherwise they will not be
//* correctly freed.
//*/
//typedef struct tsk_heap_s
//{
// TSK_DECLARE_OBJECT;
// tsk_heap_pool_t pool; /**< Memory pool holding the address of all allocated variables */
//}
//tsk_heap_t;
//
///** PUSH new address to the heap pool
//*/
//#define HEAP_PUSH(heap, address) if(heap) tsk_heap_push(heap, (void*)address)
///** POP and free an address from the heap pool
//*/
//#define HEAP_POP(heap, address) if(heap) tsk_heap_pop(heap, (void*)address); else free(address)
//
////TINYSAK_API void tsk_heap_init(tsk_heap_t *heap);
//TINYSAK_API void tsk_heap_push(tsk_heap_t *heap, void * address);
//TINYSAK_API void tsk_heap_pop(tsk_heap_t *heap, void * address);
//TINYSAK_API void tsk_heap_cleanup(tsk_heap_t *heap);
//
//#endif /* _TINYSAK_HEAP_H_ */

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_list.c
* @brief Linked list
* @brief Linked list. For more information about linked list you can visit http://en.wikipedia.org/wiki/Linked_list.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -29,7 +29,6 @@
*/
#include "tsk_list.h"
#include "tsk_memory.h"
#include "tsk_macros.h"
#include "tsk_debug.h"
//#include <assert.h>

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_list.h
* @brief Linked list
* @brief Linked list. For more information about linked list you can visit http://en.wikipedia.org/wiki/Linked_list.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -35,67 +35,57 @@
TSK_BEGIN_DECLS
/**@def TSK_LIST_CREATE
* Create and initialize a linked list.
* You MUST use @ref TSK_OBJECT_SAFE_FREE to free a linked list.
* @sa @ref TSK_LIST_SAFE_FREE.
/** Create and initialize a linked list object.
* You MUST use @ref TSK_OBJECT_SAFE_FREE to safely free the object.
*/
#define TSK_LIST_CREATE() tsk_object_new(tsk_list_def_t)
/**@def TSK_LIST_ITEM_CREATE
* Create and initialize an item.
* You MUST use @ref TSK_OBJECT_SAFE_FREE to free an item.
* @sa @ref TSK_OBJECT_SAFE_FREE.
/** Create and initialize an item to be added to a linked list.
* You MUST use @ref TSK_OBJECT_SAFE_FREE to safely free the object.
*/
#define TSK_LIST_ITEM_CREATE() tsk_object_new(tsk_list_item_def_t)
/**@typedef tsk_list_item_func_free
* Used to define the function to call to free an @b item.
*
*@param item item to free
/** Check if the the linked list is empty or not.
* This function will fail if the list is NULL.
*/
//typedef void (*tsk_list_item_func_free)(void** item);
#define TSK_LIST_IS_EMPTY(self) (self ? (!self->head) : 1)
/** Item
/** Item for linked list.
*/
typedef struct tsk_list_item_s
{
TSK_DECLARE_OBJECT;
void* data; /**< opaque data encapsulated by the item. */
struct tsk_list_item_s* next; /**< next item. */
void* data; /**< Opaque data. */
struct tsk_list_item_s* next; /**< Next item. */
}
tsk_list_item_t;
/**Linked list
/** A Linked list.
*/
typedef struct tsk_list_s
{
TSK_DECLARE_OBJECT;
tsk_list_item_t* head; /**< head of the list. */
struct tsk_list_item_s* tail; /**< tail item. */
tsk_list_item_t* head; /**< The head of the linked list. */
tsk_list_item_t* tail; /**< The tail of the linked list. */
}
tsk_list_t;
/**@typedef tsk_list_func_predicate
* Function predicate used to match an item.
/** Function predicate used to match an item.
* @param item The current item to match.
* @data data Arbitrary data holding the object to compare.
* @retval 0 if match and <0 if first<second and >0 otherwise
*/
typedef int (*tsk_list_func_predicate)(const tsk_list_item_t* item, const void* data);
/**def tsk_list_foreach
*
/** tsk_list_foreach
* Loop through the linked list.
* @param item current item.
* @param list pointer to the list for which we want to get items.
* @param item The current item.
* @param list Pointer to the list for which we want to get items.
*
*/
#define tsk_list_foreach(item, list) for(item = list?list->head:0; item; item= item->next)
TINYSAK_API void tsk_list_remove_item(tsk_list_t* list, tsk_list_item_t* item);
TINYSAK_API void tsk_list_remove_item_by_data(tsk_list_t* list, const void * tskobj);
TINYSAK_API void tsk_list_remove_item_by_pred(tsk_list_t* list, tsk_list_func_predicate predicate, const void * data);
@ -123,9 +113,6 @@ TINYSAK_API void tsk_list_push_filtered_data(tsk_list_t* list, void** data, int
TINYSAK_API const tsk_list_item_t* tsk_list_find_item_by_data(const tsk_list_t* list, const void * tskobj);
TINYSAK_API const tsk_list_item_t* tsk_list_find_item_by_pred(const tsk_list_t* list, tsk_list_func_predicate predicate, const void * data);
TINYSAK_GEXTERN const void *tsk_list_def_t;
TINYSAK_GEXTERN const void *tsk_list_item_def_t;

View File

@ -1,70 +0,0 @@
///*
//* Copyright (C) 2009 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
//*/
//
///**@file tsk_macros.h
// * @brief Macro helpers
// *
// * @author Mamadou Diop <diopmamadou(at)yahoo.fr>
// *
// * @date Created: Sat Nov 8 16:54:58 2009 mdiop
// */
//#ifndef _TINYSAK_MACROS_H_
//#define _TINYSAK_MACROS_H_
//
///**@def TSK_XXX_CREATE
//* @brief Macro helper to create and initialize an object.
//* @param heap The memory on which to create the object
//* @param xxx object to create
//* @param prefix the prefix of the object to create
//*/
//#define TSK_XXX_CREATE(heap, xxx, prefix)\
// xxx = (tsk_##prefix##_t*)tsk_calloc(heap, 1, sizeof(tsk_##prefix##_t)); \
// tsk_##prefix##_init(xxx);
//
///**@def TSK_XXX_SAFE_FREE
//* @brief Macro helper to safely free an object.
//* @param heap The memory from which to free the object
//* @param xxx object to free
//* @param prefix the prefix of the object to free
//*/
//#define TSK_XXX_SAFE_FREE(heap, xxx, prefix)\
// if(xxx) { tsk_##prefix##_free(heap, &(xxx)); xxx = 0; }
//
///**@def TSK_XXX_CREATE2
//* @brief Macro helper to create and initialize an object.
//* @param xxx object to create
//* @param prefix the prefix of the object to create
//*/
//#define TSK_XXX_CREATE2(xxx, prefix)\
// xxx = (tsk_##prefix##_t*)tsk_calloc(1, sizeof(tsk_##prefix##_t)); \
// tsk_##prefix##_init(xxx);
//
///**@def TSK_XXX_SAFE_FREE2
//* @brief Macro helper to safely free an object.
//* @param xxx object to free
//* @param prefix the prefix of the object to free
//*/
//#define TSK_XXX_SAFE_FREE2(xxx, prefix)\
// if(xxx) { tsk_##prefix##_free(&(xxx)); xxx = 0; }
//
//#endif /* _TINYSAK_MACROS_H_ */

View File

@ -31,7 +31,6 @@
#define _TINYSAK_MEMORY_H_
#include "tinySAK_config.h"
#include "tsk_heap.h"
#include <stdlib.h> /* size_t */

View File

@ -31,6 +31,10 @@
#include "tsk_memory.h"
#include "tsk_debug.h"
/**@defgroup tsk_object_group Base object implementation.
* @brief Provides utility functions to ease Object Oriented Programming in C.
*/
#if defined (_DEBUG) || defined (DEBUG)
# define TSK_DEBUG_OBJECTS 0
static int tsk_objects_count = 0;
@ -38,14 +42,22 @@ static int tsk_objects_count = 0;
# define TSK_DEBUG_OBJECTS 0
#endif
typedef struct tsk_object_header_s
{
const void* base;
size_t refCount;
/** Object meta-data (definition).
*/
typedef struct tsk_object_header_s{
const void* base; /**< Opaque data holding a pointer to the actual meta-data(size, constructor, destructor and comparator) */
size_t refCount; /**< Reference counter. */
}
tsk_object_header_t;
#define TSK_OBJECT_HEADER_GET(object) ((tsk_object_header_t*)object)
/**@ingroup tsk_object_group
* Creates new object. The object MUST be declared using @ref TSK_DECLARE_OBJECT macro.
* @param objdef The object meta-data (definition). For more infomation see @ref tsk_object_def_t.
* @param ... List of parameters to pass to the constructor(defined in the meta-data).
* @retval The newly calloc()ed object with a reference counter equal to 1.
* @sa @ref tsk_object_new2.
*/
void* tsk_object_new(const tsk_object_def_t *objdef, ...)
{
void *newobj = tsk_calloc(1, objdef->size);
@ -75,6 +87,13 @@ void* tsk_object_new(const tsk_object_def_t *objdef, ...)
return newobj;
}
/**@ingroup tsk_object_group
* Creates new object. The object MUST be declared using @ref TSK_DECLARE_OBJECT macro.
* @param objdef The object meta-data (definition). For more infomation see @ref tsk_object_def_t.
* @param ap Variable argument list to pass to the constructor(defined in the meta-data).
* @retval The newly calloc()ed object with a reference counter equal to 1.
* @sa @ref tsk_object_new.
*/
void* tsk_object_new2(const tsk_object_def_t *objdef, va_list* ap)
{
void *newobj = tsk_calloc(1, objdef->size);
@ -97,6 +116,12 @@ void* tsk_object_new2(const tsk_object_def_t *objdef, va_list* ap)
return newobj;
}
/**@ingroup tsk_object_group
* Gets the size of an opaque object.
* @param self The object for which we want to get the size.
* The object MUST be declared using @ref TSK_DECLARE_OBJECT macro and created using @ref tsk_object_new or @ref tsk_object_new2.
* @retval The size of the object.
*/
size_t tsk_object_sizeof(const void *self)
{
const tsk_object_def_t **objdef = (const tsk_object_def_t **)self;
@ -109,26 +134,32 @@ size_t tsk_object_sizeof(const void *self)
}
}
int tsk_object_cmp(const void *self, const void *object)
/**@ingroup tsk_object_group
* Compares two objects. Both object MUST be declared using @ref TSK_DECLARE_OBJECT and created using @ref tsk_object_new or @ref tsk_object_new2.
* If the meta-data (definition) of the first object (@a object1) do not include a function comparator then this method will amlways return -1.
* @param object1 The first object to compare.
* @param object2 The second object to compare.
* @retval Zero if the two object are equal.
* Positive value if @a object1 is greater than @a object2 and a negative value otherwise.
*/
int tsk_object_cmp(const void *object1, const void *object2)
{
const tsk_object_def_t **objdef = (const tsk_object_def_t **)self;
const tsk_object_def_t **objdef = (const tsk_object_def_t **)object1;
if(objdef && *objdef && (*objdef)->objcmp){
return (*objdef)->objcmp(self, object);
return (*objdef)->objcmp(object1, object2);
}
return -1;
}
/*int tsk_object_icmp(const void *self, const void *object)
{
const tsk_object_def_t **objdef = self;
if(objdef && *objdef && (*objdef)->objicmp)
{
return (*objdef)->objicmp(self, object);
}
return 0;
}*/
/**@ingroup tsk_object_group
* Increment the refrence counting of the object.<br>
* Refernce counting: http://en.wikipedia.org/wiki/Reference_counting.<br>
* The object MUST be declared using @ref TSK_DECLARE_OBJECT macro and created using @ref tsk_object_new or @ref tsk_object_new2.
* @param self The object holding the counter to increment.
* @retval The new object (incremented).
* @sa tsk_object_unref.
*/
void* tsk_object_ref(void *self)
{
if(self){
@ -138,6 +169,15 @@ void* tsk_object_ref(void *self)
return 0;
}
/**@ingroup tsk_object_group
* Decrement the refrence counting of the object.<br>
* Refernce counting: http://en.wikipedia.org/wiki/Reference_counting.<br>
* The object MUST be declared using @ref TSK_DECLARE_OBJECT macro and created using @ref tsk_object_new or @ref tsk_object_new2.
* @param self The object holding the counter to decrement.
* @retval If the refernce counter is equal to zero then NULL is returned otherwise a new object (decremented) is returned.
* @sa ref tsk_object_ref.
* @sa ref TSK_OBJECT_SAFE_FREE.
*/
void* tsk_object_unref(void *self)
{
if(self)
@ -150,6 +190,13 @@ void* tsk_object_unref(void *self)
return self;
}
/**@ingroup tsk_object_group
* Delete an object. This function will delete the object even if it's reference counter is greater than 1.
* This mean that this function is not safe. You should use @ref TSK_OBJECT_SAFE_FREE to safely delete an object.
* The object MUST be declared using @ref TSK_DECLARE_OBJECT macro and created using @ref tsk_object_new or @ref tsk_object_new2.
* @param self The object to delete.
* @sa @ref TSK_OBJECT_SAFE_FREE.
*/
void tsk_object_delete(void *self)
{
const tsk_object_def_t ** objdef = self;

View File

@ -37,46 +37,114 @@
TSK_BEGIN_DECLS
/**
* @def TSK_OBJECT_SAFE_FREE(self) tsk_object_unref(self), self = 0
*
* @brief Safely free an object. If the reference count of the object was equal to 1 then this
* object will be freed otherwise the refrence count will be decremented.
* In all all case this operation will set the pointer (the object itself) to NULL.
*
* @remarks Mamadou, 1/20/2010.
*
/**@ingroup tsk_object_group
* Safely free any object created using @ref tsk_object_new and declared using @ref TSK_DECLARE_OBJECT. If the reference count of the object was equal to 1 then this
* object will be freed otherwise the refrence counter will be decremented.
* In all case this operation will set the pointer (the object itself) to NULL.
* @param self The object to free or unref.
**/
#define TSK_OBJECT_SAFE_FREE(self) tsk_object_unref(self), self = 0
/**@ingroup tsk_object_group
* tag a structure as an object. If this macro is used then you MUST
* provide a constructor and a destructor functions into an object definition (or meta-data).
* @ref tsk_object_new or @ref tsk_object_new2 are used to create the object and @ref tsk_object_unref or @ref tsk_object_delete to destroy it.
* @code
* typedef struct person_s{
* TSK_DECLARE_OBJECT;
* int id;
* char* firstName;
* char* lastName;
* } person_t;
* @endcode
* To create the object:
* @code
* // person_def_t: See bellow to understand how to create an object definition.
* person_t* person = tsk_object_new(person_def_t, "My First Name", "My last Name");
* @endcode
* To safely free the object:
* @code
* TSK_OBJECT_SAFE_FREE(person);
* @endcode
*/
#define TSK_DECLARE_OBJECT \
const void* base; \
size_t refCount
#define TSK_DECLARE_DEF(prefix, name) \
static const tsk_object_def_t ##prefix##_##name##_def_s = \
{\
sizeof(##prefix##_##name##_t), \
##prefix##_##name##_create, \
##prefix##_##name##_destroy, \
##prefix##_##name##_clone, \
##prefix##_##name##_cmp, \
##prefix##_##name##_icmp, \
};\
const void *##prefix##_##name##_def_t = &##prefix##_##name##_def_s;
/**@ingroup tsk_object_group
* Internal macro to get the definition of the object.
*/
#define TSK_OBJECT_DEF(self) ((const tsk_object_def_t*)self)
/**
* Base object.
/**@ingroup tsk_object_group
* Meta-data used of define an object.
* You MUST provide at least a constructor and a destructor. The comparator should
* be provided if you would like to compare opaque object or sort linked lists.
* @code
*
* // constructor
* static void* person_create(void * self, va_list * app)
* {
* static int unique_id = 0;
* person_t *person = self;
* if(person){
* person->id = ++unique_id;
* person->firstName = tsk_strdup(va_arg(*app, const char *));
* person->lastName = tsk_strdup(va_arg(*app, const char *));
* }
* return self;
* }
*
* // destructor
* static void* person_destroy(void * self)
* {
* person_t *person = self;
* if(person){
* TSK_FREE(person->firstName);
* TSK_FREE(person->lastName);
* }
* return self;
* }
*
* // comparator
* static int person_cmp(const void *object1, const void *object1)
* {
* const person_t *person1 = object1;
* const person_t *person2 = object2;
*
* return (person1 && person2) ? (person1->id - person2->id) : -1;
* }
*
* // Meta-data (Object defnition)
* static const tsk_object_def_t person_def_s =
* {
* sizeof(person_t),
* person_create,
* person_destroy,
* person_cmp,
* }person_def_t;
*
* @endcode
* Now, to create your object:
* @code
* person_t* person = tsk_object_new(person_def_t, "My First Name", "My last Name"); // Will call "person_create" function.
* @endcode
* Or
* @code
* #define PERSON_CREATE(firstName, lastName) tsk_object_new(person_def_t, firstName, lastName)
* person_t* person = PERSON_CREATE("My First Name", "My last Name") // For clarity, this form will be used in all projects declared using @ref TSK_DECLARE_OBJECT.
* @endcode
* To safely free your object:
* @code
* TSK_OBJECT_SAFE_FREE(person); // Will call "person_destroy" function.
* @endcode
*/
typedef struct tsk_object_def_s
{
size_t size; /**< The size of an tsk object. */
void* (* constructor) (void *self, va_list *app); /**< The constructor. */
void* (* destructor) (void *); /**< The destructor. */
int (* objcmp) (const void *object1, const void *object2); /**< Compare two object */
size_t size; /**< The size of the object. */
void* (* constructor) (void *self, va_list *app); /**< Pointer to the constructor. */
void* (* destructor) (void *); /**< Pointer to the destructor. */
int (* objcmp) (const void *object1, const void *object2); /**< Pointer to the comparator. */
}
tsk_object_def_t;
@ -84,7 +152,6 @@ TINYSAK_API void* tsk_object_new(const tsk_object_def_t *objdef, ...);
TINYSAK_API void* tsk_object_new2(const tsk_object_def_t *objdef, va_list* ap);
TINYSAK_API size_t tsk_object_sizeof(const void *self);
TINYSAK_API int tsk_object_cmp(const void *self, const void *object);
//TINYSAK_API int tsk_object_icmp(const void *self, const void *object);
TINYSAK_API void* tsk_object_ref(void *self);
TINYSAK_API void* tsk_object_unref(void *self);
TINYSAK_API void tsk_object_delete(void *self);

View File

@ -32,7 +32,6 @@
#include "tinySAK_config.h"
#include "tsk_heap.h"
#include "tsk_object.h"
#include "tsk_list.h"

View File

@ -21,7 +21,7 @@
*/
/**@file tsk_timer.c
* @brief Timers Mangement.
* @brief Timer Manager.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*

View File

@ -20,8 +20,8 @@
*
*/
/**@file tsk_timers.h
* @brief Timer Management.
/**@file tsk_timer.h
* @brief Timer Manager.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -43,7 +43,7 @@ TSK_BEGIN_DECLS
typedef void tsk_timer_manager_handle_t;
typedef uint64_t tsk_timer_id_t;
typedef int (*tsk_timer_callback)(const void* arg, tsk_timer_id_t timer_id); /**< Callback function called when scheduled timer timeout. */
typedef int (*tsk_timer_callback)(const void* arg, tsk_timer_id_t timer_id);
TINYSAK_API int tsk_timer_manager_start(tsk_timer_manager_handle_t *self);
TINYSAK_API int tsk_timer_manager_isready(tsk_timer_manager_handle_t *self);

View File

@ -32,8 +32,6 @@
#include "tinySAK_config.h"
#include "tsk_heap.h"
TSK_BEGIN_DECLS
TINYSAK_API char* tsk_url_encode(const char* url);

View File

@ -50,8 +50,6 @@ typedef struct tsip_dialog_subscribe
tsip_timer_t timerrefresh;
unsigned unsubscribing:1;
char* package;
}
tsip_dialog_subscribe_t;

View File

@ -224,6 +224,7 @@ typedef struct tsip_message_s
/*== */
tnet_fd_t sockfd;
unsigned update:1;
}
tsip_message_t;

View File

@ -158,6 +158,7 @@ tsip_request_t *tsip_dialog_request_new(const tsip_dialog_t *self, const char* m
request = tsip_request_new(method, request_uri, from_uri, to_uri, call_id, self->cseq_value);
request->To->tag = tsk_strdup(self->tag_remote);
request->From->tag = tsk_strdup(self->tag_local);
request->update = 1; /* No signal that the message should be updated by the transport layer (Contact, SigComp, IPSec, ...) */
/*
@ -172,26 +173,36 @@ tsip_request_t *tsip_dialog_request_new(const tsip_dialog_t *self, const char* m
provide a new contact address, should its address change during the
duration of the dialog.
*/
switch(request->request_type)
{
char* contact = 0;
tsip_header_Contacts_L_t *hdr_contacts;
tsk_sprintf(&contact, "m: <%s:%s@%s:%d>;expires=%d;doubs\r\n", /*self->issecure*/0?"sips":"sip", from_uri->user_name, "127.0.0.1", 5060, self->expires);
hdr_contacts = tsip_header_Contact_parse(contact, strlen(contact));
if(!TSK_LIST_IS_EMPTY(hdr_contacts)){
request->Contact = tsk_object_ref(hdr_contacts->head->data);
}
TSK_OBJECT_SAFE_FREE(hdr_contacts);
TSK_FREE(contact);
case tsip_MESSAGE:
case tsip_PUBLISH:
break;
/* Add capabilities as per RFC 3840. */
params = tsip_operation_get_caps(self->operation);
if(request->Contact){
tsk_list_foreach(item, params)
default:
{
param = (const tsk_param_t*)item->data;
tsk_params_add_param(&TSIP_HEADER(request->Contact)->params, param->name, param->value);
char* contact = 0;
tsip_header_Contacts_L_t *hdr_contacts;
tsk_sprintf(&contact, "m: <%s:%s@%s:%d>;expires=%d\r\n", /*self->issecure*/0?"sips":"sip", from_uri->user_name, "127.0.0.1", 5060, self->expires);
hdr_contacts = tsip_header_Contact_parse(contact, strlen(contact));
if(!TSK_LIST_IS_EMPTY(hdr_contacts)){
request->Contact = tsk_object_ref(hdr_contacts->head->data);
}
TSK_OBJECT_SAFE_FREE(hdr_contacts);
TSK_FREE(contact);
/* Add capabilities as per RFC 3840. */
params = tsip_operation_get_caps(self->operation);
if(request->Contact){
tsk_list_foreach(item, params)
{
param = (const tsk_param_t*)item->data;
tsk_params_add_param(&TSIP_HEADER(request->Contact)->params, param->name, param->value);
}
}
break;
}
}
}
/* Update authorizations */

View File

@ -228,28 +228,24 @@ int tsip_dialog_message_start(tsip_dialog_message_t *self)
const tsk_param_t* param;
const void* content = TSIP_NULL;
size_t content_length = 0;
const char* content_type = "text/plain";
tsip_request_t* request;
tsip_request_t* request = tsip_dialog_request_new(TSIP_DIALOG(self), "MESSAGE");
/* content-type */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "content-type"))){
content_type = param->value;
}
/* content-length */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "content-length"))){
content_length = atoi(param->value);
}
/* content */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "content"))){
content = param->value;
if(!content_length && content){
content_length = strlen(content);
if((request = tsip_dialog_request_new(TSIP_DIALOG(self), "MESSAGE"))){
/* content-length */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "content-length"))){
content_length = atoi(param->value);
}
/* content */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "content"))){
content = param->value;
if(!content_length && content){
content_length = strlen(content);
}
if(content){
tsip_message_add_content(request, TSIP_NULL, content, content_length);
}
}
}
if(content){
tsip_message_add_content(request, content_type, content, content_length);
}
/* Send request */

View File

@ -249,9 +249,7 @@ int tsip_dialog_subscribe_timer_callback(const tsip_dialog_subscribe_t* self, ts
* @param [in,out] self The dialog to initialize.
**/
int tsip_dialog_subscribe_init(tsip_dialog_subscribe_t *self)
{
const tsk_param_t* param;
{
/* Initialize the State Machine. */
tsk_fsm_set(self->fsm,
@ -312,11 +310,6 @@ int tsip_dialog_subscribe_init(tsip_dialog_subscribe_t *self)
// Any -> (hangup) -> Trying
TSK_FSM_ADD_NULL());
/* Package. */
if((param = tsip_operation_get_param(TSIP_DIALOG(self)->operation, "package"))){
self->package = tsk_strdup(param->value);
}
TSIP_DIALOG(self)->callback = TSIP_DIALOG_EVENT_CALLBACK(tsip_dialog_subscribe_event_callback);
@ -600,11 +593,6 @@ int send_subscribe(tsip_dialog_subscribe_t *self)
}
if((request = tsip_dialog_request_new(TSIP_DIALOG(self), "SUBSCRIBE"))){
/* Event package. */
if(self->package){
TSIP_MESSAGE_ADD_HEADER(request, TSIP_HEADER_EVENT_VA_ARGS(self->package));
}
ret = tsip_dialog_request_send(TSIP_DIALOG(self), request);
TSK_OBJECT_SAFE_FREE(request);
}
@ -681,8 +669,6 @@ static void* tsip_dialog_subscribe_destroy(void * self)
/* FSM */
TSK_OBJECT_SAFE_FREE(dialog->fsm);
TSK_FREE(dialog->package);
}
return self;
}

View File

@ -90,35 +90,32 @@ int tsip_transport_msg_update(const tsip_transport_t* self, tsip_message_t *msg)
tnet_port_t port;
int ret = 0;
if(!msg->update){
return 0;
}
if(tsip_transport_get_ip_n_port(self, &ip, &port)){
return -1;
}
/* VERY IMPORTANT: Only request/response with a contact header containing "doubs" parameter will be updated.
* The update will concern the contact header(sigcomp uuid, host, port, ...), ipsec headers (Security-Client, Security-Verify, ...), ...
*/
/* Update the contact header.*/
if(msg->Contact && TSIP_HEADER_HAVE_PARAM(msg->Contact, "doubs")){
/* Host and port */
if(msg->Contact->uri){
tsk_strupdate(&(msg->Contact->uri->scheme), self->scheme);
tsk_strupdate(&(msg->Contact->uri->host), ip);
msg->Contact->uri->port = port;
msg->Contact->uri->host_type = TNET_SOCKET_TYPE_IS_IPV6(self->type) ? host_ipv6 : host_ipv4;
tsk_params_add_param(&msg->Contact->uri->params, "transport", self->protocol);
}
/* IPSec headers */
if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)){
ret = tsip_transport_ipsec_updateMSG(TSIP_TRANSPORT_IPSEC(self), msg);
}
/* SigComp */
/* Remove the parameter */
TSIP_HEADER_REMOVE_PARAM(msg->Contact, "doubs");
/* Host and port */
if(msg->Contact && msg->Contact->uri){
tsk_strupdate(&(msg->Contact->uri->scheme), self->scheme);
tsk_strupdate(&(msg->Contact->uri->host), ip);
msg->Contact->uri->port = port;
msg->Contact->uri->host_type = TNET_SOCKET_TYPE_IS_IPV6(self->type) ? host_ipv6 : host_ipv4;
tsk_params_add_param(&msg->Contact->uri->params, "transport", self->protocol);
}
/* IPSec headers */
if(TNET_SOCKET_TYPE_IS_IPSEC(self->type)){
ret = tsip_transport_ipsec_updateMSG(TSIP_TRANSPORT_IPSEC(self), msg);
}
/* SigComp */
msg->update = 0; /* To avoid update of retrans. msg */
return ret;
}

View File

@ -140,7 +140,7 @@ void test_stack()
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
/*
tsip_stack_handle_t *stack = tsip_stack_create(test_stack_callback,
TSIP_STACK_SET_DISPLAY_NAME("Mamadou"),
TSIP_STACK_SET_PUBLIC_IDENTITY("sip:mamadou@ericsson.com"),
@ -157,8 +157,8 @@ void test_stack()
TSIP_STACK_SET_DEVICE_ID("DD1289FA-C3D7-47bd-A40D-F1F1B2CC5FFC"),
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
/*
*/
tsip_stack_handle_t *stack = tsip_stack_create(test_stack_callback,
TSIP_STACK_SET_DISPLAY_NAME("Mamadou"),
TSIP_STACK_SET_PUBLIC_IDENTITY("sip:mamadou@ims.inexbee.com"),
@ -167,15 +167,15 @@ void test_stack()
TSIP_STACK_SET_REALM("sip:ims.inexbee.com"), // FIXME: without sip:
TSIP_STACK_SET_LOCAL_IP(LOCAL_IP),
//TSIP_STACK_SET_DISCOVERY_NAPTR(1),
TSIP_STACK_SET_PROXY_CSCF("pcscf.ims.inexbee.com", "udp", 1),
TSIP_STACK_SET_PROXY_CSCF("pcscf.ims.inexbee.com", "udp", 0),
//TSIP_STACK_SET_PROXY_CSCF("192.168.0.15", "udp", 0),
TSIP_STACK_SET_PROXY_CSCF_PORT(4060),
TSIP_STACK_SET_SECAGREE_IPSEC("hmac-md5-96", "null", "trans", "esp"),
//TSIP_STACK_SET_SECAGREE_IPSEC("hmac-md5-96", "null", "trans", "esp"),
TSIP_STACK_SET_MOBILITY("fixed"),
TSIP_STACK_SET_DEVICE_ID("DD1289FA-C3D7-47bd-A40D-F1F1B2CC5FFC"),
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
TSIP_STACK_SET_NULL());
tsip_operation_handle_t *op = TSIP_OPERATION_CREATE(stack,
@ -183,6 +183,8 @@ void test_stack()
TSIP_OPERATION_SET_CAPS("language", "\"en,fr\""),
TSIP_OPERATION_SET_CAPS("+audio", ""),
TSIP_OPERATION_SET_CAPS("+g.oma.sip-im", ""),
TSIP_OPERATION_SET_NULL());
@ -201,9 +203,9 @@ void test_stack()
{
tsip_operation_handle_t *op2 = TSIP_OPERATION_CREATE(stack,
TSIP_OPERATION_SET_PARAM("to", "sip:mamadou@ericsson.com"),
TSIP_OPERATION_SET_PARAM("to", "sip:mamadou@ims.inexbee.com"),
TSIP_OPERATION_SET_PARAM("expires", "30"),
TSIP_OPERATION_SET_PARAM("package", "reg"),
TSIP_OPERATION_SET_HEADER("Event", "reg"),
TSIP_OPERATION_SET_HEADER("Accept", "application/reginfo+xml"),
TSIP_OPERATION_SET_HEADER("Allow-Events", "refer, presence, presence.winfo, xcap-diff"),
TSIP_OPERATION_SET_HEADER("Allow", "INVITE, ACK, CANCEL, BYE, MESSAGE, OPTIONS, NOTIFY, PRACK, UPDATE, REFER"),
@ -212,15 +214,17 @@ void test_stack()
tsip_subscribe(stack, op2);
}
//{
// tsip_operation_handle_t *op3 = TSIP_OPERATION_CREATE(stack,
// TSIP_OPERATION_SET_PARAM("to", "sip:alice@ericsson.com"),
// TSIP_OPERATION_SET_PARAM("content", "test"),
// TSIP_OPERATION_SET_PARAM("content-type", "text/plain"),
//
// TSIP_OPERATION_SET_NULL());
// tsip_message(stack, op3);
//}
{
tsip_operation_handle_t *op3 = TSIP_OPERATION_CREATE(stack,
TSIP_OPERATION_SET_PARAM("to", "sip:laurent@ims.inexbee.com"),
TSIP_OPERATION_SET_HEADER("Accept-Contact", "*;+g.oma.sip-im"),
TSIP_OPERATION_SET_HEADER("Content-Type", "text/plain"),
TSIP_OPERATION_SET_PARAM("content", "test"),
TSIP_OPERATION_SET_NULL());
tsip_message(stack, op3);
}
//while(1);//tsk_thread_sleep(500);
//while(1)

View File

@ -393,10 +393,6 @@
RelativePath="..\..\tinySAK\src\tsk_list.h"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_macros.h"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_md5.h"
>
@ -449,10 +445,6 @@
RelativePath="..\..\tinySAK\src\tsk_string.h"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_thread.h"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_time.h"
>
@ -507,10 +499,6 @@
RelativePath="..\..\tinySAK\src\tsk_fsm.c"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_heap.c"
>
</File>
<File
RelativePath="..\..\tinySAK\src\tsk_hmac.c"
>

View File

@ -459,6 +459,10 @@
RelativePath="..\..\tinySIP\src\headers\tsip_header_Date.c"
>
</File>
<File
RelativePath="..\..\tinySIP\src\headers\tsip_header_Dummy.c"
>
</File>
<File
RelativePath="..\..\tinySIP\src\headers\tsip_header_Error_Info.c"
>
@ -831,6 +835,10 @@
RelativePath="..\..\tinySIP\src\dialogs\tsip_dialog_message.c"
>
</File>
<File
RelativePath="..\..\tinySIP\src\dialogs\tsip_dialog_publish.client.c"
>
</File>
<File
RelativePath="..\..\tinySIP\src\dialogs\tsip_dialog_register.client.c"
>
@ -1009,6 +1017,10 @@
RelativePath="..\..\tinySIP\include\tinysip\headers\tsip_header_Date.h"
>
</File>
<File
RelativePath="..\..\tinySIP\include\tinysip\headers\tsip_header_Dummy.h"
>
</File>
<File
RelativePath="..\..\tinySIP\include\tinysip\headers\tsip_header_Error_Info.h"
>
@ -1381,6 +1393,10 @@
RelativePath="..\..\tinySIP\include\tinysip\dialogs\tsip_dialog_message.h"
>
</File>
<File
RelativePath="..\..\tinySIP\include\tinysip\dialogs\tsip_dialog_publish.h"
>
</File>
<File
RelativePath="..\..\tinySIP\include\tinysip\dialogs\tsip_dialog_register.h"
>