filter.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003  -------------------
00004  cvs         : $Id$
00005  begin       : Fri Feb 07 2003
00006  copyright   : (C) 2003 by Martin Preuss
00007  email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032 
00033 /* #define DISABLE_DEBUGLOG */
00034 
00035 
00036 #include "filter_p.h"
00037 #include <gwenhywfar/misc.h>
00038 #include <gwenhywfar/text.h>
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <strings.h>
00043 #include <errno.h>
00044 
00045 #include <gwenhywfar/debug.h>
00046 #include <gwenhywfar/misc.h>
00047 
00048 
00049 GWEN_LIST_FUNCTIONS(GWEN_FILTER, GWEN_Filter)
00050 GWEN_INHERIT_FUNCTIONS(GWEN_FILTER)
00051 
00052 
00053 GWEN_FILTER *GWEN_Filter_new(const char *name){
00054   GWEN_FILTER *f;
00055 
00056   assert(name);
00057   GWEN_NEW_OBJECT(GWEN_FILTER, f);
00058   GWEN_INHERIT_INIT(GWEN_FILTER, f);
00059   GWEN_LIST_INIT(GWEN_FILTER, f);
00060   f->filterName=strdup(name);
00061   f->inBuffer=GWEN_RingBuffer_new(GWEN_FILTER_BUFFERSIZE);
00062   f->outBuffer=GWEN_RingBuffer_new(GWEN_FILTER_BUFFERSIZE);
00063 
00064   f->nextElements=GWEN_Filter_List_new();
00065 
00066   return f;
00067 }
00068 
00069 
00070 
00071 void GWEN_Filter_free(GWEN_FILTER *f){
00072   if (f) {
00073     GWEN_INHERIT_FINI(GWEN_FILTER, f);
00074     GWEN_Filter_List_free(f->nextElements);
00075     GWEN_RingBuffer_free(f->inBuffer);
00076     GWEN_RingBuffer_free(f->outBuffer);
00077     free(f->filterName);
00078     GWEN_LIST_FINI(GWEN_FILTER, f);
00079     GWEN_FREE_OBJECT(f);
00080   }
00081 }
00082 
00083 
00084 
00085 GWEN_RINGBUFFER *GWEN_Filter_GetInBuffer(const GWEN_FILTER *f){
00086   assert(f);
00087   return f->inBuffer;
00088 }
00089 
00090 
00091 
00092 GWEN_RINGBUFFER *GWEN_Filter_GetOutBuffer(const GWEN_FILTER *f){
00093   assert(f);
00094   return f->outBuffer;
00095 }
00096 
00097 
00098 
00099 void GWEN_Filter_SetWorkFn(GWEN_FILTER *f, GWEN_FILTER_WORKFN fn){
00100   assert(f);
00101   f->workFn=fn;
00102 }
00103 
00104 
00105 
00106 GWEN_FILTER_RESULT GWEN_Filter__Work(GWEN_FILTER *f){
00107   assert(f);
00108   assert(f->workFn);
00109   return f->workFn(f);
00110 }
00111 
00112 
00113 
00114 void GWEN_Filter_AppendNext(GWEN_FILTER *fPredecessor, GWEN_FILTER *fNew){
00115   assert(fPredecessor);
00116   assert(fNew);
00117   GWEN_Filter_List_Add(fNew, fPredecessor->nextElements);
00118 }
00119 
00120 
00121 
00122 GWEN_FILTER_RESULT GWEN_Filter__WriteToAllNext(GWEN_FILTER *filter) {
00123   GWEN_FILTER *f;
00124   uint32_t maxFree;
00125   const char *p;
00126 
00127   /* get maximum of bytes for the next level (least number of writeable
00128    * bytes) */
00129   maxFree=GWEN_RingBuffer_GetMaxUnsegmentedRead(filter->outBuffer);
00130   if (maxFree) {
00131     f=GWEN_Filter_List_First(filter->nextElements);
00132     while(f) {
00133       uint32_t currFree;
00134 
00135       currFree=GWEN_RingBuffer_GetMaxUnsegmentedWrite(f->inBuffer);
00136       if (currFree<maxFree)
00137         maxFree=currFree;
00138       f=GWEN_Filter_List_Next(f);
00139     } /* while */
00140 
00141     if (!maxFree) {
00142       DBG_INFO(GWEN_LOGDOMAIN, "Buffers are full");
00143       return GWEN_Filter_ResultFull;
00144     }
00145 
00146     /* write to every next element */
00147     p=GWEN_RingBuffer_GetReadPointer(filter->outBuffer);
00148     DBG_INFO(GWEN_LOGDOMAIN,
00149              "Writing %u bytes",
00150              maxFree);
00151     assert(p);
00152     f=GWEN_Filter_List_First(filter->nextElements);
00153     while(f) {
00154       uint32_t written;
00155 
00156       written=maxFree;
00157       if (GWEN_RingBuffer_WriteBytes(f->inBuffer, p, &written)) {
00158         DBG_ERROR(GWEN_LOGDOMAIN,
00159                   "Error writing bytes to inbuffer of filter \"%s\"",
00160                   f->filterName);
00161         return GWEN_Filter_ResultError;
00162       }
00163       /* here the number of bytes written must also equal the number of
00164        * bytes to write */
00165       assert(written==maxFree);
00166 
00167       f=GWEN_Filter_List_Next(f);
00168     } /* while */
00169     GWEN_RingBuffer_SkipBytesRead(filter->outBuffer, maxFree);
00170   } /* if there is something to write */
00171 
00172   return GWEN_Filter_ResultOk;
00173 }
00174 
00175 
00176 
00177 GWEN_FILTER_RESULT GWEN_Filter_Work(GWEN_FILTER *filter, int oneLoop) {
00178   int wasFull=0;
00179 
00180   for (;;) {
00181     GWEN_FILTER *f;
00182     GWEN_FILTER_RESULT res;
00183     int allNeedData=0;
00184 
00185     /* let only this element work */
00186     res=GWEN_Filter__Work(filter);
00187     if (res==GWEN_Filter_ResultError)
00188       return res;
00189 
00190     /* write to all next elements */
00191     res=GWEN_Filter__WriteToAllNext(filter);
00192     if (res==GWEN_Filter_ResultFull) {
00193       if (wasFull)
00194         /* was already full the last time we tried, return */
00195         return res;
00196       wasFull=1;
00197     }
00198     else if (res!=GWEN_Filter_ResultOk)
00199       return res;
00200 
00201     /* let all next elements flush */
00202     allNeedData=1;
00203     f=GWEN_Filter_List_First(filter->nextElements);
00204     while(f) {
00205       res=GWEN_Filter_Work(f, oneLoop);
00206       if (res==GWEN_Filter_ResultError)
00207         return res;
00208       else if (res!=GWEN_Filter_ResultNeedMore)
00209         allNeedData=0;
00210       f=GWEN_Filter_List_Next(f);
00211     } /* while */
00212 
00213     if (allNeedData && wasFull) {
00214       DBG_INFO(GWEN_LOGDOMAIN,
00215                "All elements need data, finished");
00216       return GWEN_Filter_ResultNeedMore;
00217     }
00218 
00219     if (oneLoop)
00220       return GWEN_Filter_ResultOk;
00221   } /* for */
00222 }
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 

Generated on Thu Aug 20 13:54:38 2009 for gwenhywfar by  doxygen 1.5.9