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