Changeset 12910 for fact/Evidence
- Timestamp:
- 02/20/12 22:04:50 (13 years ago)
- Location:
- fact/Evidence
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/Evidence/DColl.cc
r11205 r12910 393 393 // 394 394 int main() { 395 396 dic_disable_padding(); 397 dis_disable_padding(); 395 398 396 399 // Static ensures calling of destructor by exit() -
fact/Evidence/Doc/Evidence.tex
r10996 r12910 185 185 The methods \underline{\lstinline{Lock()}} and \underline{\lstinline{Unlock()}} work on an internal mutex.\footnote{Its type is \lstinline{PTHREAD_MUTEX_ERRORCHECK}. In case an already locked mutex is re-locked, the corresponding system call will therefore return a error and thus avoid dead-locking. Error messages from \lstinline{Lock()} and \lstinline{Unlock()} are written to the console and to the log file. They are not published using \lstinline{Message()} since this method itself uses locking and calling it would result in an infinite recursion.} They are used by \lstinline{GetConfig()} but are also available for the user application to serialize access from multiple threads. Calling functions in the locked state should be avoided as it might result in re-locking. 186 186 187 The static method \underline{\lstinline{ToString()}} translates the contents of a DIM service safely into a string that is returned. As no consistency between a service format and the contained data is guaranteed by DIM, precautions are necessary to avoid buffer overruns. The method currently handles the standardized message format \lstinline{"I:1;C"}, arrays of numbers and strings. All other formats are translated into a hex representation. The arguments are the DIM service format, a pointer to the service data and the data size in bytes. It is thread safe as it uses only the arguments and dynamically allocated storage.187 The static method \underline{\lstinline{ToString()}} translates the contents of a DIM service safely into a string that is returned. As no consistency between a service format and the contained data is guaranteed by DIM, precautions are necessary to avoid buffer overruns. The method handles all DIM formats, as long as padding is disabled in DIM. The arguments are the DIM service format, a pointer to the service data and the data size in bytes. It is thread safe as it uses only the arguments and dynamically allocated storage. A format entry \lstinline{C} with no length indication is treated as a string, all other as numbers. 188 188 189 189 The static methods \underline{\lstinline{ServiceOK()}} take a pointer to a received service update or result of a remote procedure call (as available in the respective handlers) and safely checks if its contents is identical to the constant \lstinline{NO_LINK}. If so, they return false. If using the same constant in the service declaration, this provides a safe way of being informed if a particular service becomes unavailable. Then, the handler is called once for that service with the data content \lstinline{NO_LINK}. … … 298 298 \multicolumn{2}{l}{\lstinline|History <Directory for storing history buffers>|} \\[1ex] 299 299 \multicolumn{2}{l}{\textbf{Configuration section \lstinline|[History]|}} \\ 300 \lstinline|minchange| & Minimum absolute change necessary for a service to be added to the history buffer. The format is \lstinline|ServiceName:MinChange|. This is only meaningful for services that represent numbers or number arrays. For an array, the difference of the sum of the absolute values of all elements is compared to \lstinline|MinChange|.\\300 \lstinline|minchange| & Minimum absolute change of a value or of the average of a range of values necessary for adding to the history buffer. This can extend the time reach of the ring buffer by avoiding noise entries. The format is \lstinline|ServiceName:MinChange| or \lstinline|ServiceName:IndexRange:MinChange|, where \lstinline|IndexRange| can be a single number of in the form a-b.\\ 301 301 \lstinline|maxsize_kb| & Maximum size of a single history buffer in kByte. Default value is 2000.\\ 302 302 \lstinline|numentries| & Numer of entries that a history buffer should hold, provided its size does not exceed the defined maximum. Default value is 1000. For DIM services of varying size, buffer sizes are recalculated at each update and never shrink.\\ -
fact/Evidence/Evidence.cc
r12894 r12910 103 103 This = this; 104 104 105 dis_disable_padding(); 106 dic_disable_padding(); 107 105 108 // Initialise mutex 106 109 int Ret; … … 407 410 408 411 // Translates DIM data safely to string (assures no invalid memory accesses are made) 409 string EvidenceServer::ToString(char *Format, void *Data, int Size) { 412 // Structure evaluation requires that no padding is used 413 string EvidenceServer::ToString(char *Format, const void *Data, int Size) { 410 414 411 415 ostringstream Text; 412 413 // 'Message' service format handled here 414 if (strcmp(Format, "I:1;C") == 0 && Size >= (int) sizeof(struct Message)) { 415 struct Message *Msg = (struct Message *) Data; 416 // Safely extract string and limit to length of C string (padding might make it longer) 417 string MsgText(Msg->Text, Size-sizeof(struct Message)); 418 Text << Msg->Severity << " " << MsgText.erase(strlen(MsgText.c_str())); 419 420 return Text.str(); 421 } 422 423 // String if format "C" and terminated with \0 424 if (strcmp(Format, "C") == 0 && Size > 0 && *((char *) Data+Size-1)=='\0') { 425 return string((char *) Data); 426 } 427 428 // Check if format is made of identical component types 429 vector<string> Components = Tokenize(Format, ";"); 430 431 for (unsigned int i=0; i<Components.size(); i++) { 432 if (Components[i].empty()) return string(); 433 434 // Print hex representation if format complex 435 if (Components[i][0] != Components[0][0]) { 436 for (int i=0; i<Size; i++) { 437 Text << setw(2) << hex << *((char *) Data + i) << " "; 438 } 439 return Text.str(); 440 } 441 } 442 443 // Number array 444 int ElementSize; 445 446 switch (toupper(*Format)) { 447 case 'B': 448 case 'V': 449 case 'C': ElementSize = sizeof(char); break; 450 case 'I': 451 case 'L': ElementSize = sizeof(int); break; 452 case 'S': ElementSize = sizeof(short); break; 453 case 'F': ElementSize = sizeof(float); break; 454 case 'D': ElementSize = sizeof(double); break; 455 case 'X': ElementSize = sizeof(long long); break; 456 default: return string(); 457 } 458 459 for (int i=0; i<Size/ElementSize; i++) { 460 // Space between entries 461 if (i != 0) Text << " "; 462 463 // Translate data 464 switch (toupper(*Format)) { 416 vector<string> Components; 417 int ElementSize, N, Byte = 0; 418 419 // Find component types 420 Components = Tokenize(Format, ";"); 421 422 for (unsigned int n=0; n<Components.size(); n++) { 423 // If empty, format error 424 if (Components[n].empty()) return string(); 425 426 // Determine maximum number of elements 427 if (Components[n].size() > 2) N = atoi(Components[n].c_str()+2); 428 else N = numeric_limits<int>::max(); 429 430 // Determine length in bytes of elements 431 switch (toupper(Components[n][0])) { 465 432 case 'B': 466 433 case 'V': 467 case 'C': Text << *((char *) Data + i); break; 468 case 'I': 469 case 'L': Text << *((int *) Data + i); break; 470 case 'S': Text << *((short *) Data + i); break; 471 case 'F': Text << *((float *) Data + i); break; 472 case 'D': Text << *((double *) Data + i); break; 473 case 'X': Text << *((long long *) Data + i); break; 434 case 'C': ElementSize = sizeof(char); break; 435 case 'I': 436 case 'L': ElementSize = sizeof(int); break; 437 case 'S': ElementSize = sizeof(short); break; 438 case 'F': ElementSize = sizeof(float); break; 439 case 'D': ElementSize = sizeof(double); break; 440 case 'X': ElementSize = sizeof(long long); break; 441 default: return string(); 474 442 } 475 } 476 443 444 // Covert elements 445 for (int i=0; i<N; i++) { 446 // Check that not overrunning memory 447 if (Byte + ElementSize > Size) return Text.str(); 448 449 // Translate elements into text (handle string specially when format is 'C') 450 switch (toupper(Components[n][0])) { 451 case 'C': if (Components[n].size() == 1) { 452 string String((char *) Data, Size-Byte); 453 454 // Remove trailing '\0' 455 if (!String.empty() && String[String.size()-1] == '\0') String.resize(String.size()-1); 456 457 Text << String; 458 return Text.str(); 459 } 460 Text << *((char *) Data); 461 break; 462 case 'B': 463 case 'V': Text << *((char *) Data); 464 break; 465 case 'I': 466 case 'L': Text << *((int *) Data); 467 break; 468 case 'S': Text << *((short *) Data); 469 break; 470 case 'F': Text << *((float *) Data); 471 break; 472 case 'D': Text << *((double *) Data); 473 break; 474 case 'X': Text << *((long long *) Data); 475 break; 476 } 477 478 Byte += ElementSize; 479 Data = (void *) ((char *) Data + ElementSize); 480 481 // Space between entries 482 Text << " "; 483 } 484 } 477 485 return Text.str(); 478 486 } -
fact/Evidence/Evidence.h
r12892 r12910 11 11 #include <map> 12 12 #include <set> 13 #include <limits> 13 14 14 15 #include <exception> … … 79 80 static void Lock(); 80 81 static void Unlock(); 81 static std::string ToString(char *, void *, int);82 static std::string ToString(char *, const void *, int); 82 83 static bool ServiceOK(DimInfo *); 83 84 static bool ServiceOK(DimRpcInfo *); -
fact/Evidence/GUI.cc
r12894 r12910 29 29 if (strcmp(Service, "Edd/Rate_kBSec") == 0) Format = "F"; 30 30 else if (Hist == NULL || Hist->GetFormat() == NULL) { 31 //QMessageBox::warning(NULL, "Edd Message", QString("Could not retrieve history for service ") + Service ,QMessageBox::Ok);32 31 printf("Edd Message: Could not retrieve history for service %s\n", Service); 33 32 } … … 49 48 QGridLayout *Layout = new QGridLayout(M->centralWidget()); 50 49 51 if (Format. size() == 1 && Format[0] == 'C') Layout->addWidget(new EddText(Service), 0, 0);50 if (Format.endsWith('C', Qt::CaseInsensitive)) Layout->addWidget(new EddText(Service), 0, 0); 52 51 else { 53 52 EddPlot *W = new EddPlot(Service, FromIndex); … … 387 386 double Number=0; 388 387 while ((R=Hist->Next()) != NULL) { 389 switch (*(Hist->GetFormat())) { 390 case 'I': 391 case 'L': Number = *((int *) R->Data + N.Index); break; 392 case 'S': Number = *((short *) R->Data + N.Index); break; 393 case 'F': Number = *((float *) R->Data + N.Index); break; 394 case 'D': Number = *((double *) R->Data + N.Index); break; 395 case 'X': Number = *((long long *) R->Data + N.Index); break; 396 default: break; 397 } 388 std::vector<std::string> Data = EvidenceServer::Tokenize(EvidenceServer::ToString(Hist->GetFormat(), R->Data, R->Size)); 389 if (N.Index > 0 && N.Index < (int) Data.size()) Number = atof(Data[N.Index].c_str()); 398 390 AddPoint(List.size()-1, R->Time, Number); 399 391 } -
fact/Evidence/History.cc
r12909 r12910 426 426 } 427 427 428 dic_disable_padding(); 429 dis_disable_padding(); 430 428 431 // Static ensures calling of destructor by exit() 429 432 static History Hist(argv[1]); -
fact/Evidence/readme.txt
r12909 r12910 60 60 into account (e.g. Service:a-b:0.4 requires an minimum absolute change of 0.4 for the average 61 61 value of indices a to b) 62 20/2/2012 Disabled padding per default in Evidence class constructor, and also in History and DColl 63 servers. EvidenceServer::ToString() can because of this now handle all format strings.
Note:
See TracChangeset
for help on using the changeset viewer.