filter.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033
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
00128
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 }
00140
00141 if (!maxFree) {
00142 DBG_INFO(GWEN_LOGDOMAIN, "Buffers are full");
00143 return GWEN_Filter_ResultFull;
00144 }
00145
00146
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
00164
00165 assert(written==maxFree);
00166
00167 f=GWEN_Filter_List_Next(f);
00168 }
00169 GWEN_RingBuffer_SkipBytesRead(filter->outBuffer, maxFree);
00170 }
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
00186 res=GWEN_Filter__Work(filter);
00187 if (res==GWEN_Filter_ResultError)
00188 return res;
00189
00190
00191 res=GWEN_Filter__WriteToAllNext(filter);
00192 if (res==GWEN_Filter_ResultFull) {
00193 if (wasFull)
00194
00195 return res;
00196 wasFull=1;
00197 }
00198 else if (res!=GWEN_Filter_ResultOk)
00199 return res;
00200
00201
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 }
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 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244