Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

dataclient.cc

Go to the documentation of this file.
00001 //**************************************************************************
00002 #include <signal.h>
00003 #include <unistd.h>
00004 #include <stdio.h>
00005 #include "dataclient.h"
00006 #include "errcode.h"
00007 //**************************************************************************
00008 DataClient::DataClient()
00009 {
00010 keytable = new KeyTable;
00011 connected = false;
00012 portnum = 0;
00013 strcpy(servername, "");
00014 }
00015 //**************************************************************************
00016 DataClient::DataClient(char *host, int port)
00017 {
00018 keytable = new KeyTable;
00019 connected = false;
00020 portnum = 0;
00021 strcpy(servername, "");
00022 Connect(host, port);
00023 }
00024 //**************************************************************************
00025 DataClient::~DataClient()
00026 {
00027 Disconnect();
00028 delete keytable;
00029 }
00030 //**************************************************************************
00031 int DataClient::Connect(char *host, int port)
00032 {
00033 //trap_sigpipe();
00034 signal(SIGPIPE, SIG_IGN);
00035 signal(SIGABRT, SIG_IGN);
00036 
00037 if (!TCPSocket::Connect(host, port))
00038         {
00039 //       cout << "Retrying after 5 seconds." << endl;
00040 //       mySleep(5*1000000);
00041          return POSSE_RETRY;
00042         }
00043 
00044 int a;
00045 try
00046         {
00047          SendClientName();
00048          int size = QueryKeyword("_start_private");
00049          a = RecvVar<int>();
00050         }
00051 catch (int &e)
00052         {
00053          if (e == ERR_RECV_MESG)
00054                 {
00055 #ifdef ANIDEBUG
00056                  cerr << "DataClient: Error: Initialization failed!! " << endl;
00057                  cerr << "\tNo DataServer listening on " << host << ":" << port << endl << flush;
00058                  cerr << "\tExiting!" << endl;
00059 #endif
00060                 }
00061          return POSSE_FAILURE;
00062         }
00063 
00064 if (a != VERIFICATION_NUMBER)
00065         {
00066          cerr << "DataClient: Error: Initialization failed!! ";
00067          cerr << "[Recd " << a << ", expected " << VERIFICATION_NUMBER << "]!" << endl << flush;
00068          cerr << "\tExiting!" << endl;
00069          return POSSE_FAILURE;
00070         }
00071 
00072 RecvKeyTable(keytable);
00073 
00074 connected = true;
00075 portnum = port;
00076 strcpy(servername, host);
00077 
00078 return POSSE_SUCCESS;
00079 }
00080 //**************************************************************************
00081 int DataClient::Disconnect()
00082 {
00083 int a = 0;
00084 if (connected)
00085         {
00086          try {
00087                 a = SendKeyword("_q_private");
00088                 TCPSocket::Close();
00089                 }
00090          catch (int &err)
00091                 {
00092                  cout << "DataClient::Disconnect(): Caught exception!!" << endl << flush;
00093                 }
00094         }
00095 portnum = 0;
00096 strcpy(servername, "");
00097 return a;
00098 }
00099 //**************************************************************************
00100 int DataClient::RecvKeyTable(KeyTable *K)
00101 {
00102 if (K == NULL)
00103         K = keytable;
00104 SendKeyword("keytable");
00105 RemoteSocket::RecvStruct(K);
00106 return 1;
00107 }
00108 //**************************************************************************
00109 VariableType DataClient::VarType(char *keyword)
00110 {
00111 int handle = keytable->getKeyHandle(keyword);
00112 if (handle == keytable->n)
00113         {
00114          cout << "Error: Unknown keyword \"" << keyword << "\"!!" << endl << flush;
00115          return UNKNOWN;
00116         }
00117 
00118 return keytable->key[handle].vartype;
00119 }
00120 //**************************************************************************
00121 char *DataClient::RecvValue(char *keyword)
00122 {
00123 char *val = new char[100];
00124 VariableType vtype = UNKNOWN;
00125 
00126 int handle = keytable->getKeyHandle(keyword);
00127 if (handle < keytable->n && keytable->isViewableVar(handle))
00128         vtype = keytable->key[handle].vartype;
00129 
00130 switch (vtype)
00131         {
00132          case CHAR:
00133                 if (keytable->isCharArray(handle))
00134                         {
00135                          char s[100];
00136                          RecvArray(keyword, s);
00137                          memcpy(val, s, 99);
00138                          val[99] = '\0';
00139                         }
00140                 else
00141                         {
00142                          char x_char;
00143                          RecvVariable(keyword, &x_char);
00144                          sprintf(val, "%c\0", x_char);
00145                         }
00146                 break;
00147 
00148          case SHORT:
00149                 short x_short;
00150                 RecvVariable(keyword, &x_short);
00151                 sprintf(val, "%d\0", x_short);
00152                 break;
00153 
00154          case INT:
00155                 int x_int;
00156                 RecvVariable(keyword, &x_int);
00157                 sprintf(val, "%d\0", x_int);
00158                 break;
00159 
00160          case LONG:
00161                 long x_long;
00162                 RecvVariable(keyword, &x_long);
00163                 sprintf(val, "%ld\0", x_long);
00164                 break;
00165 
00166          case FLOAT:
00167                 float x_float;
00168                 RecvVariable(keyword, &x_float);
00169                 sprintf(val, "%g\0", x_float);
00170                 break;
00171 
00172          case DOUBLE:
00173                 double x_double;
00174                 RecvVariable(keyword, &x_double);
00175                 sprintf(val, "%g\0", x_double);
00176                 break;
00177 
00178          default:       // case UNKNOWN:
00179                 strcpy(val, "error");
00180                 break;
00181         }
00182         
00183 return val;
00184 }
00185 //**************************************************************************
00186 int DataClient::SendValue(char *keyword, char *value)
00187 {
00188 int handle = keytable->getKeyHandle(keyword);
00189 
00190 if (handle == keytable->n)
00191         {
00192          cout << "Error: Keyword \"" << keyword << "\" not found!" << endl << flush;
00193          return POSSE_INVALID_KEY;
00194         }
00195 
00196 if (!keytable->isViewableVar(handle))
00197         {
00198          cout << "Error: Keyword \"" << keyword << "\" not a valid Variable!" << endl << flush;
00199          return POSSE_INVALID_VARIABLE;
00200         }
00201 
00202 if (!isWritable(keytable->key[handle].key))
00203         {
00204          return POSSE_READONLY_KEY;
00205         }
00206 
00207 switch (keytable->key[handle].vartype)
00208         {
00209          case CHAR:
00210                 if (keytable->isCharArray(handle))
00211                         {
00212                          SendArray(keyword, value);
00213                         }
00214                 else
00215                         {
00216                          char x_char;
00217                          sscanf(value, "%c", &x_char);
00218                          SendVariable(keyword, x_char);
00219                         }
00220                 break;
00221 
00222 
00223          case SHORT:
00224                 short x_short;
00225                 sscanf(value, "%d", &x_short);
00226                 SendVariable(keyword, x_short);
00227                 break;
00228 
00229          case INT:
00230                 int x_int;
00231                 sscanf(value, "%d", &x_int);
00232                 SendVariable(keyword, x_int);
00233                 break;
00234 
00235          case LONG:
00236                 long x_long;
00237                 sscanf(value, "%ld", &x_long);
00238                 SendVariable(keyword, x_long);
00239                 break;
00240 
00241          case FLOAT:
00242                 float x_float;
00243                 sscanf(value, "%f", &x_float);
00244                 SendVariable(keyword, x_float);
00245                 break;
00246 
00247          case DOUBLE:
00248                 double x_double;
00249                 sscanf(value, "%lf", &x_double);
00250                 SendVariable(keyword, x_double);
00251                 break;
00252 
00253          default:       // case UNKNOWN:
00254                 cout << "Error: Undefined type for keyword \"" << keyword << "\"!!" << endl << flush;
00255                 return -3;
00256                 break;
00257         }
00258         
00259 return POSSE_SUCCESS;
00260 }
00261 //**************************************************************************
00262 void DataClient::ListKeywords()
00263 {
00264 keytable->List();
00265 }
00266 //**************************************************************************
00267 void DataClient::ListValues()
00268 {
00269 RecvKeyTable(keytable);
00270 keytable->ListValues();
00271 }
00272 //**************************************************************************
00273 KeyTable *DataClient::GetTable()
00274 {
00275 return keytable;
00276 }
00277 //**************************************************************************
00278 bool DataClient::isValidKeyword(char *keyword, int *handle)
00279 {
00280 #ifdef ANIDEBUG
00281 cout << "DataClient::isValidKeyword: Checking for validity of keyword \"" << keyword << "\"." << endl << flush;
00282 #endif
00283 int i = keytable->getKeyHandle(keyword);
00284 if (handle)
00285         *handle = i;
00286 if (i == keytable->n)
00287         {
00288          cout << "Error!! Server does not identify keyword \"" << keyword << "\"!!" << endl << flush;
00289          return false;
00290         }
00291 return true;
00292 }
00293 //**************************************************************************
00294 bool DataClient::isWritable(int handle)
00295 {
00296 if (!keytable->isWritable(handle))
00297         {
00298          cout << "Error!! Data for keyword \"" << keytable->key[handle].key << "\" cannot be modified. ";
00299          cout << "It is marked READ-ONLY by the server!" << endl << flush;
00300          return false;
00301         }
00302 return true;
00303 }
00304 //**************************************************************************
00305 bool DataClient::isWritable(char *keyword)
00306 {
00307 int handle = keytable->getKeyHandle(keyword);
00308 if (handle < keytable->n)
00309         return isWritable(handle);
00310 return false;
00311 }
00312 //**************************************************************************
00313 bool DataClient::isVariable(int handle)
00314 {
00315 int size = keytable->key[handle].elem_size;
00316 if (!keytable->isVar(handle))
00317         {
00318          cout << "Error!! Incompatible data types for keyword \"" << keytable->key[handle].key << "\"!!" << endl;
00319          cout << "\tServer expects a \"" << keytable->key[handle].description << "\" of type \"" << keytable->key[handle].type << "\"." << endl;
00320          cout << "\tClient expects a \"Variable\"!!" << endl << flush;
00321          return false;
00322         }
00323 return true;
00324 }
00325 //**************************************************************************
00326 bool DataClient::VerifyElementSize(int handle, int elem_size)
00327 {
00328 int size = keytable->key[handle].elem_size;
00329 if (size != elem_size)
00330         {
00331          cout << "Error!! Incompatible element type for keyword \"" << keytable->key[handle].key << "\"!!" << endl;
00332          cout << "\tServer expects element of type \"" << keytable->key[handle].type << "\" [" << size << " bytes]." << endl;
00333          cout << "\tClient expects element of size " << elem_size << " bytes!!" << endl << flush;
00334          return false;
00335         }
00336 return true;
00337 }
00338 //**************************************************************************
00339 bool DataClient::SendKeyword(char *keyword)
00340 {
00341 #ifdef ANIDEBUG
00342 cout << "DataClient::SendKeyword: Sending keyword \"" << keyword << "\"." << e
00343 ndl << flush;
00344 #endif
00345 
00346 SendLine(keyword);
00347 
00348 return true;
00349 }
00350 //**************************************************************************
00351 bool DataClient::SendKeyForDataSend(int handle)
00352 {
00353 #ifdef ANIDEBUG
00354 cout << "DataClient::SendKeyForDataSend: Sending key \"" << keytable->key[handle].key << "\" to server." << endl << flush;
00355 #endif
00356 if (!isWritable(handle)) return false;
00357 
00358 char key[100];
00359 key[0] = 'R';
00360 strcpy(&key[1], keytable->key[handle].key);
00361 SendLine(key);
00362 
00363 return true;
00364 }
00365 //**************************************************************************
00366 bool DataClient::SendKeyForDataSend(char *keyword)
00367 {
00368 int handle = keytable->getKeyHandle(keyword);
00369 if (handle < keytable->n)
00370         return SendKeyForDataSend(handle);
00371 return false;
00372 }
00373 //**************************************************************************
00374 int DataClient::RecvDummyBytes(int size)
00375 {
00376 cout << endl;   
00377 cout << "Receiving " << size << " bytes of dummy data before exiting." << endl;
00378 cout << flush; 
00379         
00380 unsigned char *data; 
00381 ALLOC1D(&data, size);
00382 RecvBytes(size, data);
00383 FREE1D(&data, size);
00384 
00385 Release();
00386 return 0;
00387 }
00388 //**************************************************************************
00389 bool DataClient::isBigEndian()
00390 {
00391 int size = QueryKeyword("_isBigEndian");
00392 int val = RecvVar<int>();
00393 return (val == 1);
00394 }
00395 //**************************************************************************
00396 int DataClient::SendClientName()
00397 {
00398 char hostname[200];
00399 gethostname(hostname,200);
00400 SendLine(hostname);
00401 
00402 return 0;
00403 }
00404 //**************************************************************************
00405 bool DataClient::isDynamicArray(int handle, int dim)
00406 {
00407 bool result = (keytable->key[handle].description == DYNAMIC_1D_ARRAY+dim-1);
00408 
00409 if (!result)
00410         {
00411          cout << "Error!! Incompatible data type for keyword \"" << keytable->key[handle].key << "\"!!" << endl;
00412          cout << "\tServer expects a \"" << keytable->Description(handle) << "\" of type \"" << keytable->key[handle].type << "\"." << endl;
00413          cout << "\tClient expects a \"Dynamic " << dim << "D Array\"!!" << endl << flush;
00414         }
00415 return result;
00416 }
00417 //**************************************************************************
00418 int DataClient::getArrayDim(char *keyword, int dim)
00419 {
00420 int handle;
00421 int err = ERR_BAD_DATA;
00422 if (!isValidKeyword(keyword, &handle)) throw err;
00423 if (!strstr(keytable->Description(handle), "Dynamic"))
00424         {
00425          cout << "DataClient::getArrayDim: Error!!" << endl;
00426          cout << "\t\"" << keyword << "\" is non-dynamic array!!" << endl << flush;
00427          exit(-1);
00428          throw err;
00429         }
00430 int ndims = keytable->key[handle].description-DYNAMIC_1D_ARRAY+1;;
00431 
00432 if (dim > ndims)
00433         {
00434          cout << "DataClient::getArrayDim: Error!!" << endl;
00435          cout << "\tDimension " << dim << " requested for a " << ndims << "D array!" << endl << flush;
00436          throw err;
00437         }
00438 
00439 char key[100];
00440 sprintf(key, "%s_dim%d", keyword, dim);
00441 
00442 return RecvVariable<int>(key);
00443 }
00444 //**************************************************************************

Generated on Sun Jun 16 17:36:49 2002 for POSSE: Portable Object-oriented Scientific Steering Environment by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001