rllib  1
rldataprovider.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           rldataprovider.cpp  -  description
00003                              -------------------
00004     begin                : Fri Dec 20 2002
00005     copyright            : (C) 2002 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 "rldataprovider.h"
00017 #include <stdio.h>
00018 #include <string.h>
00019 
00020 rlDataProvider::rlDataProvider(int numInteger, int numFloat, int numString)
00021 {
00022   int i;
00023 
00024   num_integer = numInteger;
00025   num_float   = numFloat;
00026   num_string  = numString;
00027   if(num_integer < 0) num_integer = 0;
00028   if(num_float   < 0) num_float   = 0;
00029   if(num_string  < 0) num_string  = 0;
00030   ints    = NULL;
00031   floats  = NULL;
00032   strings = NULL;
00033   if(num_integer > 0)
00034   {
00035     ints = new int[num_integer];
00036     for(i=0; i<num_integer; i++) ints[i] = 0;
00037   }
00038   if(num_float > 0)
00039   {
00040     floats = new float[num_float];
00041     for(i=0; i<num_float; i++) floats[i] = 0.0f;
00042   }
00043   if(num_string > 0)
00044   {
00045     strings = new CHARPTR[num_string];
00046     for(i=0; i<num_string; i++)
00047     {
00048       strings[i] = new char [1];
00049       *strings[i] = '\0';
00050     }
00051   }
00052 }
00053 
00054 rlDataProvider::~rlDataProvider()
00055 {
00056   int i;
00057 
00058   if(ints    != NULL) delete [] ints;
00059   if(floats  != NULL) delete [] floats;
00060   for(i=0; i<num_string; i++)
00061   {
00062     if(strings[i] != NULL) delete [] strings[i];
00063   }
00064   if(strings != NULL) delete [] strings;
00065 }
00066 
00067 int rlDataProvider::getInt(int id)
00068 {
00069   int ret;
00070 
00071   if(id < 0)            return -1;
00072   if(id >= num_integer) return -1;
00073   mutex.lock();
00074   ret = ints[id];
00075   mutex.unlock();
00076   return ret;
00077 }
00078 
00079 float rlDataProvider::getFloat(int id)
00080 {
00081   float ret;
00082 
00083   if(id < 0)          return 0.0f;
00084   if(id >= num_float) return 0.0f;
00085   mutex.lock();
00086   ret = floats[id];
00087   mutex.unlock();
00088   return ret;
00089 }
00090 
00091 int rlDataProvider::getIntArray(int id, int *array, int nmax)
00092 {
00093   int ret;
00094   const char *cptr = getString(id);
00095   if(cptr == NULL) return -1;
00096 
00097   ret = 0;
00098   while(1)
00099   {
00100     if(cptr == NULL || *cptr == '\0') break;
00101     if(*cptr != ',' && *cptr != '\"')
00102     {
00103       sscanf(cptr,"%d",&array[ret++]);
00104       cptr = strchr(cptr,',');
00105       if(cptr != NULL) cptr++;
00106       if(ret >= nmax) break;
00107     }
00108     else
00109     {
00110       cptr++;
00111     }
00112   }
00113   return ret;
00114 }
00115 
00116 int rlDataProvider::getFloatArray(int id, float *array, int nmax)
00117 {
00118   int ret;
00119   const char *cptr = getString(id);
00120   if(cptr == NULL) return -1;
00121 
00122   ret = 0;
00123   while(1)
00124   {
00125     if(cptr == NULL || *cptr == '\0') break;
00126     if(*cptr != ',' && *cptr != '\"')
00127     {
00128       sscanf(cptr,"%f",&array[ret++]);
00129       cptr = strchr(cptr,',');
00130       if(cptr != NULL) cptr++;
00131       if(ret >= nmax) break;
00132     }
00133     else
00134     {
00135       cptr++;
00136     }
00137   }
00138   return ret;
00139 }
00140 
00141 const char *rlDataProvider::getString(int id)
00142 {
00143   const char *ret;
00144 
00145   if(id < 0)           return NULL;
00146   if(id >= num_string) return NULL;
00147   mutex.lock();
00148   ret = strings[id];
00149   mutex.unlock();
00150   return ret;
00151 }
00152 
00153 int rlDataProvider::setInt(int id, int i)
00154 {
00155   if(id < 0)            return -1;
00156   if(id >= num_integer) return -1;
00157   mutex.lock();
00158   ints[id] = i;
00159   mutex.unlock();
00160   return 0;
00161 }
00162 
00163 int rlDataProvider::setFloat(int id, float f)
00164 {
00165   if(id < 0)          return -1;
00166   if(id >= num_float) return -1;
00167   mutex.lock();
00168   floats[id] = f;
00169   mutex.unlock();
00170   return 0;
00171 }
00172 
00173 int rlDataProvider::setIntArray(int id, int *array, int num)
00174 {
00175   char buf[rl_PRINTF_LENGTH],val[100];
00176   int nmax,ipos,ind;
00177 
00178   if(num <= 0) return -1;
00179   nmax = rl_PRINTF_LENGTH - 1;
00180   buf[0] = '\0';
00181   ipos = strlen(buf);
00182   for(ind=0; ind<num; ind++)
00183   {
00184     sprintf(val,"%d,",array[ind]);
00185     if(ipos+(int)strlen(val) >= nmax) return -1;
00186     strcat(buf,val);
00187     ipos = strlen(buf);
00188   }
00189   return setString(id,buf);
00190 }
00191 
00192 int rlDataProvider::setFloatArray(int id, float *array, int num)
00193 {
00194   char buf[rl_PRINTF_LENGTH],val[100];
00195   int nmax,ipos,ind;
00196 
00197   if(num <= 0) return -1;
00198   nmax = rl_PRINTF_LENGTH - 1;
00199   buf[0] = '\0';
00200   ipos = strlen(buf);
00201   for(ind=0; ind<num; ind++)
00202   {
00203     sprintf(val,"%f,",array[ind]);
00204     if(ipos+(int)strlen(val) >= nmax) return -1;
00205     strcat(buf,val);
00206     ipos = strlen(buf);
00207   }
00208   return setString(id,buf);
00209 }
00210 
00211 int rlDataProvider::setString(int id, const char *str)
00212 {
00213   if(id < 0)           return -1;
00214   if(id >= num_string) return -1;
00215   mutex.lock();
00216   if(strings[id] != NULL) delete [] strings[id];
00217   strings[id] = new char[strlen(str)+1];
00218   strcpy(strings[id],str);
00219   mutex.unlock();
00220   return 0;
00221 }
00222 
00223 int rlDataProvider::getIntAndReset(int id)
00224 {
00225   int ret;
00226 
00227   if(id < 0)            return -1;
00228   if(id >= num_integer) return -1;
00229   mutex.lock();
00230   ret = ints[id];
00231   ints[id] = -1;
00232   mutex.unlock();
00233   return ret;
00234 }
00235 
00236 int rlDataProvider::setIntAndWaitForReset(int id, int i)
00237 {
00238   if(id < 0)            return -1;
00239   if(id >= num_integer) return -1;
00240   while(1)
00241   {
00242     mutex.lock();
00243     if(ints[id] == -1)
00244     {
00245       ints[id] = i;
00246       mutex.unlock();
00247       return 0;
00248     }
00249     mutex.unlock();
00250     rlsleep(10);
00251   }
00252 }
00253 
00254 int rlDataProvider::setInt0Semaphore(int i)
00255 {
00256   int ret;
00257 
00258   ret = setInt(0,i);
00259   int0semaphore.incrementSemaphore();
00260   return ret;
00261 }
00262 
00263 int rlDataProvider::getInt0Semaphore()
00264 {
00265   int0semaphore.waitSemaphore();
00266   return getInt(0);
00267 }
00268 
00269 int rlDataProvider::run(rlSocket *socket)
00270 {
00271   int   id,ival,ret;
00272   float fval;
00273   char  cval[rl_PRINTF_LENGTH];
00274   const char *cptr;
00275   rlInterpreter interpreter;
00276 
00277   while(socket->isConnected())
00278   {
00279     ret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1);
00280     if(ret <= 0) break;
00281     if     (interpreter.isCommand("int("))
00282     {
00283       sscanf(interpreter.line,"int(%d,%d)",&id,&ival);
00284       setInt(id,ival);
00285     }
00286     else if(interpreter.isCommand("intAndReset("))
00287     {
00288       sscanf(interpreter.line,"intAndReset(%d,%d)",&id,&ival);
00289       setIntAndWaitForReset(id,ival);
00290     }
00291     else if(interpreter.isCommand("float("))
00292     {
00293       sscanf(interpreter.line,"float(%d,%f)",&id,&fval);
00294       setFloat(id,fval);
00295     }
00296     else if(interpreter.isCommand("string("))
00297     {
00298       sscanf(interpreter.line,"string(%d,",&id);
00299       interpreter.copyStringParam(cval,0);
00300       setString(id,cval);
00301     }
00302     else if(interpreter.isCommand("getInt("))
00303     {
00304       sscanf(interpreter.line,"getInt(%d)",&id);
00305       socket->printf("intResult(%d)\n",getInt(id));
00306     }
00307     else if(interpreter.isCommand("getIntAndReset("))
00308     {
00309       sscanf(interpreter.line,"getIntAndReset(%d)",&id);
00310       socket->printf("intResult(%d)\n",getIntAndReset(id));
00311     }
00312     else if(interpreter.isCommand("getInt0Semaphore("))
00313     {
00314       socket->printf("intResult(%d)\n",getInt0Semaphore());
00315     }
00316     else if(interpreter.isCommand("getFloat("))
00317     {
00318       sscanf(interpreter.line,"getFloat(%d)",&id);
00319       socket->printf("floatResult(%f)\n",getFloat(id));
00320     }
00321     else if(interpreter.isCommand("getString("))
00322     {
00323       sscanf(interpreter.line,"getString(%d)",&id);
00324       cptr = getString(id);
00325       if(cptr == NULL) socket->printf("stringResult(\"\")\n");
00326       else             socket->printf("stringResult(\"%s\")\n",cptr);
00327     }
00328   }
00329   return 0;
00330 }
00331 
00332 //------------------------------------------------------------------------------------
00333 #define CLIENT_TIMEOUT 1000
00334 
00335 rlDataProviderClient::rlDataProviderClient()
00336 {
00337   rlwsa();
00338 }
00339 
00340 rlDataProviderClient::~rlDataProviderClient()
00341 {
00342 }
00343 
00344 int rlDataProviderClient::getInt(rlSocket *socket, int id, int *status)
00345 {
00346   int ret;
00347 
00348   *status = -1;
00349   if(socket->isConnected() == 0) return 0;
00350   socket->printf("getInt(%d)\n",id);
00351   ret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1,CLIENT_TIMEOUT);
00352   if(ret == 0)  // timeout
00353   {
00354     socket->disconnect();
00355     socket->connect();
00356     *status = -2;
00357     return 0;
00358   }
00359   if(interpreter.isCommand("intResult("))
00360   {
00361     sscanf(interpreter.line,"intResult(%d)",&ret);
00362     *status = 0;
00363     return ret;
00364   }
00365   return 0;
00366 }
00367 
00368 float rlDataProviderClient::getFloat(rlSocket *socket, int id, int *status)
00369 {
00370   float ret;
00371   int iret;
00372 
00373   *status = -1;
00374   if(socket->isConnected() == 0) return 0.0f;
00375   socket->printf("getFloat(%d)\n",id);
00376   iret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1,CLIENT_TIMEOUT);
00377   if(iret == 0) // timeout
00378   {
00379     socket->disconnect();
00380     socket->connect();
00381     *status = -2;
00382     return 0;
00383   }
00384   if(interpreter.isCommand("floatResult("))
00385   {
00386     sscanf(interpreter.line,"floatResult(%f)",&ret);
00387     *status = 0;
00388     return ret;
00389   }
00390   return 0.0f;
00391 }
00392 
00393 int rlDataProviderClient::getIntArray(rlSocket *socket, int id, int *array, int nmax)
00394 {
00395   int status,ret;
00396   const char *cptr = getString(socket,id,&status);
00397   if(status != 0) return -1;
00398 
00399   ret = 0;
00400   while(1)
00401   {
00402     if(cptr == NULL || *cptr == '\0') break;
00403     if(*cptr != ',' && *cptr != '\"')
00404     {
00405       sscanf(cptr,"%d",&array[ret++]);
00406       cptr = strchr(cptr,',');
00407       if(cptr != NULL) cptr++;
00408       if(ret >= nmax) break;
00409     }
00410     else
00411     {
00412       cptr++;
00413     }
00414   }
00415   return ret;
00416 }
00417 
00418 int rlDataProviderClient::getFloatArray(rlSocket *socket, int id, float *array, int nmax)
00419 {
00420   int status,ret;
00421   const char *cptr = getString(socket,id,&status);
00422   if(status != 0) return -1;
00423 
00424   ret = 0;
00425   while(1)
00426   {
00427     if(cptr == NULL || *cptr == '\0') break;
00428     if(*cptr != ',' && *cptr != '\"')
00429     {
00430       sscanf(cptr,"%f",&array[ret++]);
00431       cptr = strchr(cptr,',');
00432       if(cptr != NULL) cptr++;
00433       if(ret >= nmax) break;
00434     }
00435     else
00436     {
00437       cptr++;
00438     }
00439   }
00440   return ret;
00441 }
00442 
00443 const char *rlDataProviderClient::getString(rlSocket *socket, int id, int *status)
00444 {
00445   int ret;
00446 
00447   *status = -1;
00448   if(socket->isConnected() == 0) return NULL;
00449   socket->printf("getString(%d)\n",id);
00450   ret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1,CLIENT_TIMEOUT);
00451   if(ret == 0) // timeout
00452   {
00453     socket->disconnect();
00454     socket->connect();
00455     *status = -2;
00456     return 0;
00457   }
00458   if(interpreter.isCommand("stringResult("))
00459   {
00460     interpreter.copyStringParam(cret,0);
00461     *status = 0;
00462     return cret;
00463   }
00464   return NULL;
00465 }
00466 
00467 int rlDataProviderClient::setInt(rlSocket *socket, int id, int i)
00468 {
00469   if(socket->isConnected() == 0) return -1;
00470   return socket->printf("int(%d,%d)\n",id,i);
00471 }
00472 
00473 int rlDataProviderClient::setFloat(rlSocket *socket, int id, float f)
00474 {
00475   if(socket->isConnected() == 0) return -1;
00476   return socket->printf("float(%d,%d)\n",id,f);
00477 }
00478 
00479 int rlDataProviderClient::setIntArray(rlSocket *socket, int id, int *i, int num)
00480 {
00481   char buf[rl_PRINTF_LENGTH],val[100];
00482   int nmax,ipos,ind;
00483 
00484   if(num <= 0) return -1;
00485   nmax = rl_PRINTF_LENGTH - strlen("\")\n") - 1;
00486   sprintf(buf,"string(%d,\"",id);
00487   ipos = strlen(buf);
00488   for(ind=0; ind<num; ind++)
00489   {
00490     sprintf(val,"%d,",i[ind]);
00491     if(ipos+(int)strlen(val) >= nmax) return -1;
00492     strcat(buf,val);
00493     ipos = strlen(buf);
00494   }
00495   strcat(buf,"\"\n");
00496   return socket->printf(buf);
00497 }
00498 
00499 int rlDataProviderClient::setFloatArray(rlSocket *socket, int id, float *f, int num)
00500 {
00501   char buf[rl_PRINTF_LENGTH],val[100];
00502   int nmax,ipos,ind;
00503 
00504   if(num <= 0) return -1;
00505   nmax = rl_PRINTF_LENGTH - strlen("\")\n") - 1;
00506   sprintf(buf,"string(%d,\"",id);
00507   ipos = strlen(buf);
00508   for(ind=0; ind<num; ind++)
00509   {
00510     sprintf(val,"%f,",f[ind]);
00511     if(ipos+(int)strlen(val) >= nmax) return -1;
00512     strcat(buf,val);
00513     ipos = strlen(buf);
00514   }
00515   strcat(buf,"\"\n");
00516   return socket->printf(buf);
00517 }
00518 
00519 int rlDataProviderClient::setString(rlSocket *socket, int id, const char *str)
00520 {
00521   if(socket->isConnected() == 0) return -1;
00522   return socket->printf("string(%d,\"%d\")\n",id,str);
00523 }
00524 
00525 int rlDataProviderClient::getIntAndReset(rlSocket *socket, int id, int *status)
00526 {
00527   int ret;
00528 
00529   *status = -1;
00530   if(socket->isConnected() == 0) return 0;
00531   socket->printf("getIntAndReset(%d)\n",id);
00532   ret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1,CLIENT_TIMEOUT);
00533   if(ret == 0) // timeout
00534   {
00535     socket->disconnect();
00536     socket->connect();
00537     *status = -2;
00538     return 0;
00539   }
00540   if(interpreter.isCommand("intResult("))
00541   {
00542     sscanf(interpreter.line,"intResult(%d)",&ret);
00543     *status = 0;
00544     return ret;
00545   }
00546   return 0;
00547 }
00548 
00549 int rlDataProviderClient::setIntAndWaitForReset(rlSocket *socket, int id, int i)
00550 {
00551   if(socket->isConnected() == 0) return -1;
00552   return socket->printf("intAndReset(%d,%d)\n",id,i);
00553 }
00554 
00555 int rlDataProviderClient::getInt0Semaphore(rlSocket *socket, int *status)
00556 {
00557   int ret;
00558 
00559   *status = -1;
00560   if(socket->isConnected() == 0) return 0;
00561   socket->printf("getInt0Semaphore()\n");
00562   ret = socket->readStr(interpreter.line,rl_PRINTF_LENGTH-1,CLIENT_TIMEOUT*60*60); // 1 hour timeout
00563   if(ret == 0) { *status = -2; return 0; } // timeout
00564   if(interpreter.isCommand("intResult("))
00565   {
00566     sscanf(interpreter.line,"intResult(%d)",&ret);
00567     *status = 0;
00568     return ret;
00569   }
00570   return 0;
00571 }
00572 
00573 //------------------------------------------------------------------------------------
00574 typedef struct
00575 {
00576   rlDataProviderThreads *thread;
00577   int socket;
00578 }WORKER_DATA;
00579 
00580 static void *workerThread(void *arg)
00581 {
00582   WORKER_DATA *worker_data;
00583   THREAD_PARAM *p = (THREAD_PARAM *) arg;
00584   if(arg == NULL) return NULL;
00585   worker_data = (WORKER_DATA *) p->user;
00586   rlSocket socket(worker_data->socket);
00587 
00588   worker_data->thread->provider->run(&socket);
00589 
00590   return NULL;
00591 }
00592 
00593 static void *rlDataProviderAccept(void *arg)
00594 {
00595   int s;
00596   rlThread worker;
00597   WORKER_DATA worker_data;
00598   rlDataProviderThreads *provider_threads;
00599   THREAD_PARAM *p = (THREAD_PARAM *) arg;
00600   if(arg == NULL) return NULL;
00601   provider_threads = (rlDataProviderThreads *) p->user;
00602   if(provider_threads == NULL) return NULL;
00603   rlSocket socket("localhost",provider_threads->port,0);
00604 
00605   while(1)
00606   {
00607     s = socket.connect();
00608     if(s == -1) break;
00609     worker_data.thread = provider_threads;
00610     worker_data.socket = s;
00611     worker.create(workerThread,&worker_data);
00612     rlsleep(100);
00613   }
00614   return NULL;
00615 }
00616 
00617 rlDataProviderThreads::rlDataProviderThreads(int Port, rlDataProvider *Provider)
00618 {
00619   rlwsa();
00620   port = Port;
00621   provider = Provider;
00622 }
00623 
00624 rlDataProviderThreads::~rlDataProviderThreads()
00625 {
00626 }
00627 
00628 void rlDataProviderThreads::start()
00629 {
00630   if(port <= 0)        return;
00631   if(port >= 256*256)  return;
00632   if(provider == NULL) return;
00633   thread.create(rlDataProviderAccept,this);
00634 }