annotate soap.cpp @ 331:0c908093082f

fixed another potential NULL string de-reference in soap.cpp
author mas01mc
date Sat, 30 Aug 2008 23:35:13 +0000
parents b1c48012cd3d
children cc3f9d1ca2cd
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@239 2 #include "adb.nsmap"
mas01cr@239 3
mas01cr@239 4 /* Command-line client definitions */
mas01cr@239 5
mas01cr@239 6 // FIXME: this can't propagate the sequence length argument (used for
mas01cr@239 7 // dudCount). See adb__status() definition for the other half of
mas01cr@239 8 // this. -- CSR, 2007-10-01
mas01cr@239 9 void audioDB::ws_status(const char*dbName, char* hostport){
mas01cr@239 10 struct soap soap;
mas01cr@239 11 adb__statusResponse adbStatusResponse;
mas01cr@239 12
mas01cr@239 13 // Query an existing adb database
mas01cr@239 14 soap_init(&soap);
mas01cr@239 15 if(soap_call_adb__status(&soap,hostport,NULL,(char*)dbName,adbStatusResponse)==SOAP_OK) {
mas01cr@239 16 std::cout << "numFiles = " << adbStatusResponse.result.numFiles << std::endl;
mas01cr@239 17 std::cout << "dim = " << adbStatusResponse.result.dim << std::endl;
mas01cr@239 18 std::cout << "length = " << adbStatusResponse.result.length << std::endl;
mas01cr@239 19 std::cout << "dudCount = " << adbStatusResponse.result.dudCount << std::endl;
mas01cr@239 20 std::cout << "nullCount = " << adbStatusResponse.result.nullCount << std::endl;
mas01mc@324 21 std::cout << "flags = " << (adbStatusResponse.result.flags & 0x00FFFFFF) << std::endl;
mas01cr@239 22 } else {
mas01cr@239 23 soap_print_fault(&soap,stderr);
mas01cr@239 24 }
mas01cr@239 25
mas01cr@239 26 soap_destroy(&soap);
mas01cr@239 27 soap_end(&soap);
mas01cr@239 28 soap_done(&soap);
mas01cr@239 29 }
mas01cr@239 30
mas01mc@308 31 // WS_QUERY (CLIENT SIDE)
mas01mc@307 32 void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
mas01cr@239 33 struct soap soap;
mas01cr@239 34 adb__queryResponse adbQueryResponse;
mas01mc@329 35 VERB_LOG(1, "Calling fileName query on database %s with featureFile=%s\n", dbName, featureFileName);
mas01cr@239 36 soap_init(&soap);
mas01cr@239 37 if(soap_call_adb__query(&soap,hostport,NULL,
mas01mc@307 38 (char*)dbName,(char*)featureFileName,(char*)trackFileName,(char*)timesFileName,
mas01cr@239 39 queryType, queryPoint, pointNN, trackNN, sequenceLength, adbQueryResponse)==SOAP_OK){
mas01cr@239 40 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
mas01cr@239 41 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
mas01cr@239 42 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
mas01cr@239 43 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
mas01cr@239 44 }
mas01cr@239 45 else
mas01cr@239 46 soap_print_fault(&soap,stderr);
mas01cr@239 47
mas01cr@239 48 soap_destroy(&soap);
mas01cr@239 49 soap_end(&soap);
mas01cr@239 50 soap_done(&soap);
mas01cr@239 51 }
mas01mc@307 52
mas01mc@308 53 // WS_QUERY_BY_KEY (CLIENT SIDE)
mas01mc@328 54 void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* featureFileName, const char* hostport){
mas01mc@307 55 struct soap soap;
mas01mc@307 56 adb__queryResponse adbQueryResponse;
mas01mc@314 57 /* JUST TRY TO USE A DATA STRUCTURE WITH PHP
mas01mc@314 58 adb__sequenceQueryParms asqp;
mas01mc@314 59 asqp.keyList = (char*)trackFileName;
mas01mc@314 60 asqp.timesFileName = (char*)timesFileName;
mas01mc@314 61 asqp.queryPoint = queryPoint;
mas01mc@314 62 asqp.pointNN = pointNN;
mas01mc@314 63 asqp.trackNN = trackNN;
mas01mc@314 64 asqp.sequenceLength = sequenceLength;
mas01mc@314 65 asqp.radius = radius;
mas01mc@314 66 asqp.relative_threshold = relative_threshold;
mas01mc@314 67 asqp.absolute_threshold = absolute_threshold;
mas01mc@314 68 asqp.usingQueryPoint = usingQueryPoint;
mas01mc@314 69 asqp.lsh_exact = lsh_exact;
mas01mc@314 70 */
mas01mc@331 71 VERB_LOG(1, "Calling %s query on database %s with %s=%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName);
mas01mc@307 72 soap_init(&soap);
mas01mc@307 73 if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
mas01mc@314 74 if(soap_call_adb__sequenceQueryByKey(&soap,hostport,NULL,
mas01mc@328 75 (char*)dbName,
mas01mc@328 76 (char*)trackKey,
mas01mc@328 77 (char*)featureFileName,
mas01mc@328 78 queryType,
mas01mc@328 79 (char*)trackFileName, // this means keyFileName
mas01mc@328 80 (char*)timesFileName,
mas01mc@314 81 queryPoint,
mas01mc@328 82 pointNN,
mas01mc@328 83 trackNN,
mas01mc@328 84 sequenceLength,
mas01mc@328 85 radius,
mas01mc@328 86 absolute_threshold,
mas01mc@328 87 usingQueryPoint,
mas01mc@314 88 lsh_exact,
mas01mc@314 89 adbQueryResponse)==SOAP_OK){
mas01mc@307 90 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
mas01mc@307 91 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
mas01mc@307 92 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
mas01mc@307 93 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
mas01mc@307 94 }
mas01mc@307 95 else
mas01mc@307 96 soap_print_fault(&soap,stderr);
mas01mc@307 97 }else
mas01mc@307 98 ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
mas01mc@307 99
mas01mc@307 100 soap_destroy(&soap);
mas01mc@307 101 soap_end(&soap);
mas01mc@307 102 soap_done(&soap);
mas01mc@307 103 }
mas01mc@307 104
mas01cr@239 105
mas01cr@239 106 /* Server definitions */
mas01cr@239 107 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
mas01mc@307 108 char* const argv[]={"./audioDB",COM_STATUS,"-d",dbName};
mas01cr@239 109 const unsigned argc = 4;
mas01cr@239 110 try {
mas01cr@239 111 audioDB(argc, argv, &adbStatusResponse);
mas01cr@239 112 return SOAP_OK;
mas01cr@239 113 } catch(char *err) {
mas01cr@239 114 soap_receiver_fault(soap, err, "");
mas01cr@239 115 return SOAP_FAULT;
mas01cr@239 116 }
mas01cr@239 117 }
mas01mc@308 118
mas01cr@239 119 // Literal translation of command line to web service
mas01cr@239 120 int adb__query(struct soap* soap, xsd__string dbName, xsd__string qKey, xsd__string keyList, xsd__string timesFileName, xsd__int qType, xsd__int qPos, xsd__int pointNN, xsd__int trackNN, xsd__int seqLen, adb__queryResponse &adbQueryResponse){
mas01cr@239 121 char queryType[256];
mas01mc@329 122
mas01mc@329 123 fprintf(stderr,"Calling fileName query on database %s with featureFile=%s\n", dbName, qKey);
mas01mc@329 124
mas01cr@239 125 for(int k=0; k<256; k++)
mas01cr@239 126 queryType[k]='\0';
mas01cr@239 127 if(qType == O2_POINT_QUERY)
mas01cr@239 128 strncpy(queryType, "point", strlen("point"));
mas01cr@239 129 else if (qType == O2_SEQUENCE_QUERY)
mas01cr@239 130 strncpy(queryType, "sequence", strlen("sequence"));
mas01cr@239 131 else if(qType == O2_TRACK_QUERY)
mas01cr@239 132 strncpy(queryType,"track", strlen("track"));
mas01mc@324 133 else if(qType == O2_N_SEQUENCE_QUERY)
mas01mc@324 134 strncpy(queryType,"nsequence", strlen("nsequence"));
mas01cr@239 135
mas01cr@239 136 if(pointNN==0)
mas01cr@239 137 pointNN=10;
mas01cr@239 138 if(trackNN==0)
mas01cr@239 139 trackNN=10;
mas01cr@239 140 if(seqLen==0)
mas01cr@239 141 seqLen=16;
mas01cr@239 142
mas01cr@239 143 char qPosStr[256];
mas01cr@239 144 sprintf(qPosStr, "%d", qPos);
mas01cr@239 145 char pointNNStr[256];
mas01cr@239 146 sprintf(pointNNStr,"%d",pointNN);
mas01cr@239 147 char trackNNStr[256];
mas01cr@239 148 sprintf(trackNNStr,"%d",trackNN);
mas01cr@239 149 char seqLenStr[256];
mas01cr@239 150 sprintf(seqLenStr,"%d",seqLen);
mas01cr@239 151
mas01cr@239 152 const char* argv[] ={
mas01cr@239 153 "./audioDB",
mas01cr@239 154 COM_QUERY,
mas01cr@239 155 queryType, // Need to pass a parameter
mas01cr@239 156 COM_DATABASE,
mas01cr@239 157 ENSURE_STRING(dbName),
mas01cr@239 158 COM_FEATURES,
mas01cr@239 159 ENSURE_STRING(qKey),
mas01cr@239 160 COM_KEYLIST,
mas01cr@239 161 ENSURE_STRING(keyList),
mas01cr@239 162 COM_TIMES,
mas01cr@239 163 ENSURE_STRING(timesFileName),
mas01cr@239 164 COM_QPOINT,
mas01cr@239 165 qPosStr,
mas01cr@239 166 COM_POINTNN,
mas01cr@239 167 pointNNStr,
mas01cr@239 168 COM_TRACKNN,
mas01cr@239 169 trackNNStr, // Need to pass a parameter
mas01cr@239 170 COM_SEQLEN,
mas01cr@239 171 seqLenStr
mas01cr@239 172 };
mas01cr@239 173
mas01cr@239 174 const unsigned argc = 19;
mas01cr@239 175 try {
mas01cr@239 176 audioDB(argc, (char* const*)argv, &adbQueryResponse);
mas01cr@239 177 return SOAP_OK;
mas01cr@239 178 } catch (char *err) {
mas01cr@239 179 soap_receiver_fault(soap, err, "");
mas01cr@239 180 return SOAP_FAULT;
mas01cr@239 181 }
mas01cr@239 182 }
mas01cr@239 183
mas01mc@314 184 int adb__sequenceQueryByKey(struct soap* soap,xsd__string dbName,
mas01mc@314 185 xsd__string trackKey,
mas01mc@328 186 xsd__string featureFileName,
mas01mc@314 187 xsd__int queryType,
mas01mc@328 188 xsd__string keyFileName,
mas01mc@314 189 xsd__string timesFileName,
mas01mc@314 190 xsd__int queryPoint,
mas01mc@314 191 xsd__int pointNN,
mas01mc@314 192 xsd__int trackNN,
mas01mc@314 193 xsd__int sequenceLength,
mas01mc@314 194 xsd__double radius,
mas01mc@314 195 xsd__double absolute_threshold,
mas01mc@314 196 xsd__int usingQueryPoint,
mas01mc@314 197 xsd__int lsh_exact,
mas01mc@314 198 struct adb__queryResponse& adbQueryResponse){
mas01mc@307 199 char radiusStr[256];
mas01cr@239 200 char qPosStr[256];
mas01cr@239 201 char pointNNStr[256];
mas01cr@239 202 char trackNNStr[256];
mas01cr@239 203 char seqLenStr[256];
mas01cr@239 204 char absolute_thresholdStr[256];
mas01mc@307 205 char qtypeStr[256];
mas01cr@239 206
mas01mc@331 207 fprintf(stderr, "Calling %s query on database %s with %s=%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName);
mas01mc@329 208
mas01cr@239 209 /* When the branch is merged, move this to a header and use it
mas01cr@239 210 elsewhere */
mas01cr@239 211 #define INTSTRINGIFY(val, str) \
mas01cr@239 212 snprintf(str, 256, "%d", val);
mas01cr@239 213 #define DOUBLESTRINGIFY(val, str) \
mas01cr@239 214 snprintf(str, 256, "%f", val);
mas01cr@239 215
mas01mc@314 216 INTSTRINGIFY(queryPoint, qPosStr);
mas01mc@314 217 INTSTRINGIFY(pointNN, pointNNStr);
mas01mc@314 218 INTSTRINGIFY(trackNN, trackNNStr);
mas01mc@314 219 INTSTRINGIFY(sequenceLength, seqLenStr);
mas01mc@314 220 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
mas01mc@314 221 DOUBLESTRINGIFY(radius, radiusStr);
mas01mc@307 222
mas01mc@307 223 // WS queries only support 1-nearest neighbour point reporting
mas01mc@307 224 // at the moment, until we figure out how to better serve results
mas01mc@307 225 snprintf(qtypeStr, 256, "nsequence");
mas01mc@310 226 const char *argv[]={
mas01cr@239 227 "./audioDB",
mas01cr@239 228 COM_QUERY,
mas01mc@307 229 qtypeStr,
mas01cr@239 230 COM_DATABASE,
mas01cr@239 231 dbName,
mas01mc@330 232 (trackKey&&strlen(trackKey))?COM_QUERYKEY:COM_FEATURES,
mas01mc@330 233 (trackKey&&strlen(trackKey))?ENSURE_STRING(trackKey):ENSURE_STRING(featureFileName),
mas01cr@239 234 COM_KEYLIST,
mas01mc@328 235 ENSURE_STRING(keyFileName),
mas01mc@314 236 usingQueryPoint?COM_QPOINT:COM_EXHAUSTIVE,
mas01mc@314 237 usingQueryPoint?qPosStr:"",
mas01cr@239 238 COM_POINTNN,
mas01cr@239 239 pointNNStr,
mas01cr@239 240 COM_TRACKNN,
mas01cr@239 241 trackNNStr,
mas01mc@307 242 COM_RADIUS,
mas01mc@307 243 radiusStr,
mas01cr@239 244 COM_SEQLEN,
mas01cr@239 245 seqLenStr,
mas01cr@239 246 COM_ABSOLUTE_THRESH,
mas01mc@310 247 absolute_thresholdStr,
mas01mc@314 248 lsh_exact?COM_LSH_EXACT:""
mas01cr@239 249 };
mas01cr@239 250
mas01mc@310 251 const unsigned argc = 22;
mas01mc@310 252
mas01mc@310 253
mas01cr@239 254 try {
mas01cr@239 255 audioDB(argc, (char* const*)argv, &adbQueryResponse);
mas01cr@239 256 return SOAP_OK;
mas01cr@239 257 } catch (char *err) {
mas01cr@239 258 soap_receiver_fault(soap, err, "");
mas01cr@239 259 return SOAP_FAULT;
mas01cr@239 260 }
mas01cr@239 261 }
mas01cr@239 262
mas01cr@239 263 /* Server loop */
mas01cr@239 264 void audioDB::startServer(){
mas01cr@239 265 struct soap soap;
mas01cr@239 266 int m, s; // master and slave sockets
mas01cr@239 267 soap_init(&soap);
mas01cr@239 268 // FIXME: largely this use of SO_REUSEADDR is to make writing (and
mas01cr@239 269 // running) test cases more convenient, so that multiple test runs
mas01cr@239 270 // in close succession don't fail because of a bin() error.
mas01cr@239 271 // Investigate whether there are any potential drawbacks in this,
mas01cr@239 272 // and also whether there's a better way to write the tests. --
mas01cr@239 273 // CSR, 2007-10-03
mas01cr@239 274 soap.bind_flags |= SO_REUSEADDR;
mas01cr@239 275 m = soap_bind(&soap, NULL, port, 100);
mas01cr@239 276 if (m < 0)
mas01cr@239 277 soap_print_fault(&soap, stderr);
mas01cr@239 278 else
mas01cr@239 279 {
mas01cr@239 280 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
mas01mc@308 281 // Make a global Web Services LSH Index (SINGLETON)
mas01mc@313 282 if(WS_load_index && dbName && !index_exists(dbName, radius, sequenceLength)){
mas01mc@313 283 error("Can't find requested index file:", index_get_name(dbName,radius,sequenceLength));
mas01mc@313 284 }
mas01mc@308 285 if(WS_load_index && dbName && index_exists(dbName, radius, sequenceLength)){
mas01mc@308 286 char* indexName = index_get_name(dbName, radius, sequenceLength);
mas01mc@308 287 fprintf(stderr, "Loading LSH hashtables: %s...\n", indexName);
mas01mc@308 288 lsh = new LSH(indexName, true);
mas01mc@308 289 assert(lsh);
mas01mc@308 290 SERVER_LSH_INDEX_SINGLETON = lsh;
mas01mc@308 291 fprintf(stderr, "LSH INDEX READY\n");
mas01mc@308 292 fflush(stderr);
mas01mc@308 293 delete[] indexName;
mas01mc@308 294 }
mas01mc@324 295
mas01mc@324 296 // Server-side path prefix to databases and features
mas01mc@324 297 if(adb_root)
mas01mc@324 298 SERVER_ADB_ROOT = (char*)adb_root; // Server-side database root
mas01mc@324 299 if(adb_feature_root)
mas01mc@324 300 SERVER_ADB_FEATURE_ROOT = (char*)adb_feature_root; // Server-side features root
mas01mc@308 301
mas01cr@239 302 for (int i = 1; ; i++)
mas01cr@239 303 {
mas01cr@239 304 s = soap_accept(&soap);
mas01cr@239 305 if (s < 0)
mas01cr@239 306 {
mas01cr@239 307 soap_print_fault(&soap, stderr);
mas01cr@239 308 break;
mas01cr@239 309 }
mas01cr@239 310 /* FIXME: find a way to play nice with logging when run from
mas01cr@239 311 /etc/init.d scripts: at present this just goes nowhere */
mas01cr@239 312 fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i,
mas01cr@239 313 (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
mas01cr@239 314 if (soap_serve(&soap) != SOAP_OK) // process RPC request
mas01cr@239 315 soap_print_fault(&soap, stderr); // print error
mas01cr@239 316 fprintf(stderr, "request served\n");
mas01cr@239 317 soap_destroy(&soap); // clean up class instances
mas01cr@239 318 soap_end(&soap); // clean up everything and close socket
mas01cr@239 319 }
mas01cr@239 320 }
mas01cr@239 321 soap_done(&soap); // close master socket and detach environment
mas01cr@239 322 }