Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Examples  

cyclic_buffer.c

Go to the documentation of this file.
00001 /*! \file cyclic_buffer.c
00002     This file contains a basic implementation of cyclic buffer.
00003  */
00004 
00005 #include "cyclic_buffer.h"
00006 
00007 
00008 /*! \brief Create a new cyclic buffer. 
00009     \param size Maximum number of elements of the buffer.
00010     \return The function return a handle on the newly vreated cyclic buffer, or NULL if an error occured (out of memory).
00011     \warning The function create_cyclic_buffer() allocates memory (using malloc()). Therefore, when you don't need the
00012              buffer anymore, you should destry it using destroy_cyclic_buffer().
00013  */
00014 
00015 cyclic_buffer create_cyclic_buffer (unsigned long size)
00016 {
00017    cyclic_buffer buffer;
00018    unsigned long i;
00019 
00020    /* ======================================================= */
00021    /* Allocate new data structure                             */
00022    /* ======================================================= */
00023 
00024    buffer = (cyclic_buffer)malloc(sizeof(struct s_cyclic_buffer));
00025    if (buffer == NULL) { return NULL; }
00026 
00027    buffer->buffer = (void**)malloc(size*sizeof(void*));
00028    if (buffer->buffer == NULL)
00029    {
00030      free (buffer);
00031      return NULL;
00032    }
00033 
00034    /* ======================================================= */
00035    /* Initialize data structure                               */
00036    /* ======================================================= */
00037 
00038    for (i=0; i<size; i++) { (buffer->buffer)[i] = NULL; }
00039    buffer->size         = size;
00040    buffer->start        = 0;
00041    buffer->stop         = 0;
00042    buffer->current      = 0;
00043    buffer->current_size = 0;
00044    buffer->n            = 0;
00045 
00046    return buffer;
00047 }
00048 
00049 /*! \example test_cyclic_buffer.c
00050     This file shows how to use the function create_cyclic_buffer().
00051  */
00052 
00053 /*! \brief Destroy a cyclic buffer (free all allocated memory).
00054     \param buffer Handle to the cyclic buffer to destroy.
00055  */
00056 
00057 void destroy_cyclic_buffer (cyclic_buffer buffer)
00058 {
00059    unsigned long i;
00060 
00061    /* ======================================================= */
00062    /* Free all alocated memory                                */
00063    /* ======================================================= */
00064 
00065    for (i=0; i<buffer->size; i++) 
00066    {
00067      if ((buffer->buffer)[i] != NULL) { free ((buffer->buffer)[i]); }
00068    }
00069 
00070    free (buffer->buffer);
00071    free (buffer);
00072 }
00073 
00074 /*! \example test_cyclic_buffer.c
00075     This file shows how to use the function destroy_cyclic_buffer().
00076  */
00077 
00078 /*! \brief Add a new element to the cyclic buffer.
00079     \param buffer Handle to the cyclic buffer that will be used to receive the new element.
00080     \param element Pointer to the element to add to the cyclic buffer.
00081     \param element_size Size (in bytes) of the element to add.
00082     \return If succees, the function returns a pointer to the element in the cyclic buffer. Otherwise, if an error occured,
00083             the function returns NULL.
00084     \warning Please note that the element is <B>copied</B> into the cyclic buffer. This implies that memory is allocated.
00085  */
00086 
00087 void* cyclic_buffer_add_element (cyclic_buffer buffer, void* element, unsigned element_size)
00088 {
00089   void *elem;
00090 
00091   /* ======================================================== */
00092   /* Delete element if necessary                              */ 
00093   /* ======================================================== */
00094 
00095   if ((buffer->buffer)[buffer->stop] != NULL)
00096   {
00097     free ((buffer->buffer)[buffer->stop]);
00098     (buffer->buffer)[buffer->stop] = NULL;
00099   }
00100 
00101   /* ======================================================== */
00102   /* Allocate new element                                     */
00103   /* ======================================================== */
00104 
00105   (buffer->buffer)[buffer->stop] = (void*)malloc(element_size);
00106   if ((buffer->buffer)[buffer->stop] == NULL) { return NULL; }
00107 
00108   /* ======================================================== */
00109   /* Copy element                                             */
00110   /* ======================================================== */
00111 
00112   memcpy ((buffer->buffer)[buffer->stop], element, element_size);
00113   elem = (buffer->buffer)[buffer->stop];
00114 
00115   /* ======================================================== */
00116   /* update indexes                                           */
00117   /* ======================================================== */
00118 
00119   buffer->stop = (buffer->stop + 1) % buffer->size; 
00120   if (buffer->stop == buffer->start) { buffer->start = (buffer->stop + 1) % buffer->size; }
00121 
00122   /* ======================================================== */
00123   /* One more element                                         */
00124   /* ======================================================== */
00125 
00126   if (buffer->current_size < buffer->size) { buffer->current_size += 1; }
00127 
00128   return elem;
00129 }
00130 
00131 /*! \example test_cyclic_buffer.c
00132     This file shows how to use the function add_element().
00133  */
00134 
00135 
00136 /*! \brief Reset the current buffer's pointer (used to extract element from the buffer).
00137     \param buffer Handle to the cyclic buffer.
00138  */
00139 
00140 void rewind_cyclic_buffer (cyclic_buffer buffer)
00141 {
00142   buffer->current = buffer->start;
00143   buffer->n       = 0;
00144 }
00145 
00146 /*! \example test_cyclic_buffer.c
00147     This file shows how to use the function rewind_cyclic_buffer().
00148  */
00149 
00150 /*! \brief Returns the current element of the cyclic buffer.
00151     \param buffer Handle to the cyclic buffer.
00152     \return The function returns a pointer to the current buffer's element, or NULL if the buffer's pointer reached the end
00153             of the buffer.
00154     \warning Before calling get_element(), you should call rewind_cyclic_buffer() first.
00155  */
00156 
00157 void* cyclic_buffer_get_element(cyclic_buffer buffer)
00158 {
00159   void    *elem; 
00160 
00161   if (buffer->n >= buffer->current_size) { buffer->n = 0;  return NULL; }
00162 
00163   elem = (buffer->buffer)[buffer->current];
00164   buffer->current = (buffer->current + 1) % buffer->size;
00165   (buffer->n)++;
00166 
00167   return elem;
00168 }
00169 
00170 /*! \example test_cyclic_buffer.c
00171     This file shows how to use the function get_element().
00172  */
00173 
00174 /*! \brief Return the index of the first element in the buffer.
00175     \param buffer Handle to the cyclic buffer.
00176     \return The function returns the index of the first element in the buffer.
00177  */
00178 
00179 unsigned long cyclic_buffer_get_start(cyclic_buffer buffer) { return buffer->start; }
00180 
00181 /*! \example test_cyclic_buffer.c
00182     This file shows how to use the function get_start().
00183  */
00184 
00185 /*! \brief Return the index of the last element in the buffer.
00186     \param buffer Handle to the cyclic buffer.
00187     \return The function returns the index of the last element in the buffer.
00188  */
00189 
00190 unsigned long cyclic_buffer_get_stop(cyclic_buffer buffer) { return buffer->stop; }
00191 
00192 /*! \example test_cyclic_buffer.c
00193     This file shows how to use the function get_stop().
00194  */
00195 
00196 /*! \brief Return the number of elements in the cyclic buffer.
00197     \param buffer Handle to the cyclic buffer.
00198     \return The function returns the number of elements in the cyclic buffer.
00199  */ 
00200 
00201 unsigned long cyclic_buffer_get_current_size(cyclic_buffer buffer) { return buffer->current_size; }
00202 
00203 /*! \example test_cyclic_buffer.c
00204     This file shows how to use the function get_current_size().
00205  */
00206 
00207 

Generated on Thu Apr 3 16:23:42 2003 for Common_C_libraries by doxygen1.3-rc1