rllib  1
rlfifo.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           rlfifo.cpp  -  description
00003                              -------------------
00004     begin                : Tue Jan 02 2001
00005     copyright            : (C) 2001 by Rainer Lehrig
00006     email                : lehrig@t-online.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as        *
00013  *   published by the Free Software Foundation                             *
00014  *                                                                         *
00015  ***************************************************************************/
00016 #include <stdio.h>
00017 #include <stdarg.h>
00018 #include "rlfifo.h"
00019 #include "rlcutil.h"
00020 #include "string.h"
00021 
00022 rlFifo::rlFifo(int maxmessages)
00023 {
00024   maxmes = maxmessages;
00025   nmes = 0;
00026   list = NULL;
00027   rlwthread_mutex_init(&mutex, NULL);
00028   rlwrapinit_semaphore(&semaphore, 1000);
00029 }
00030 
00031 rlFifo::~rlFifo()
00032 {
00033 MessageList *ptr,*lastptr;
00034 
00035   ptr = list;
00036   if(ptr != NULL)
00037   {
00038     do
00039     {
00040       lastptr = ptr;
00041       ptr = ptr->next;
00042       delete [] lastptr->mes;
00043       delete lastptr;
00044     }
00045     while(ptr != NULL);
00046   }
00047   rlwthread_mutex_destroy(&mutex);
00048   rlwrapdestroy_semaphore(&semaphore);
00049 }
00050 
00051 int rlFifo::read(void *buf, int maxlen)
00052 {
00053   int retlen;
00054   MessageList *ptr;
00055   char *cbuf;
00056 
00057   cbuf = (char *) buf;
00058   rlwrapwait_semaphore(&semaphore);
00059   rlwthread_mutex_lock(&mutex);
00060 
00061   if(list->len > maxlen)
00062   {
00063     rlwrapincrement_semaphore(&semaphore);
00064     rlwthread_mutex_unlock(&mutex);
00065     return MESSAGE_TO_BIG;
00066   }
00067 
00068   ptr = list;
00069   if(ptr->next == NULL)
00070   {
00071     retlen = ptr->len;
00072     memcpy(buf,ptr->mes,retlen);
00073     delete [] ptr->mes;
00074     delete ptr;
00075     list = NULL;
00076     nmes--;
00077     rlwthread_mutex_unlock(&mutex);
00078     if(retlen < maxlen && retlen >= 0) cbuf[retlen] = '\0';
00079     return retlen;
00080   }
00081   ptr = ptr->next;
00082   retlen = list->len;
00083   memcpy(buf,list->mes,retlen);
00084   delete [] list->mes;
00085   delete list;
00086   list = ptr;
00087   nmes--;
00088   rlwthread_mutex_unlock(&mutex);
00089   if(retlen < maxlen && retlen >= 0) cbuf[retlen] = '\0';
00090   return retlen;
00091 }
00092 
00093 int rlFifo::poll()
00094 {
00095   if(nmes > 0) return DATA_AVAILABLE;
00096   return              NO_DATA_AVAILABLE;
00097 }
00098 
00099 int rlFifo::write(const void *buf, int len)
00100 {
00101   MessageList *ptr;
00102 
00103   if(maxmes == 0);
00104   else if(nmes >= maxmes) return FIFO_FULL;
00105 
00106   rlwthread_mutex_lock(&mutex);
00107   if(list == NULL)
00108   {
00109     list = new MessageList;
00110     list->mes  = new char [len];
00111     list->len  = len;
00112     list->next = NULL;
00113     nmes++;
00114     memcpy(list->mes,buf,len);
00115     rlwthread_mutex_unlock(&mutex);
00116     rlwrapincrement_semaphore(&semaphore);
00117     return len;
00118   }
00119 
00120   // go to end of list
00121   ptr = list;
00122   while(ptr->next != NULL) ptr = ptr->next;
00123 
00124   ptr->next = new MessageList;
00125   ptr = ptr->next;
00126   ptr->mes  = new char [len];
00127   ptr->len  = len;
00128   ptr->next = NULL;
00129   nmes++;
00130   memcpy(ptr->mes,buf,len);
00131   rlwthread_mutex_unlock(&mutex);
00132   rlwrapincrement_semaphore(&semaphore);
00133   return len;
00134 }
00135 
00136 int rlFifo::printf(const char *format, ...)
00137 {
00138   int ret;
00139   char message[rl_PRINTF_LENGTH]; // should be big enough
00140 
00141   va_list ap;
00142   va_start(ap,format);
00143   ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap);
00144   va_end(ap);
00145   if(ret < 0) return ret;
00146   return write(message,strlen(message));
00147 }