Ignore:
Timestamp:
02/20/12 22:04:50 (13 years ago)
Author:
ogrimm
Message:
EvidenceServer::ToString() can handle all DIM formats as long as padding is disabled
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fact/Evidence/Evidence.cc

    r12894 r12910  
    103103  This = this;
    104104
     105  dis_disable_padding();
     106  dic_disable_padding();
     107 
    105108  // Initialise mutex
    106109  int Ret;
     
    407410
    408411// 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
     413string EvidenceServer::ToString(char *Format, const void *Data, int Size) {
    410414
    411415  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])) {
    465432          case 'B':
    466433          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();
    474442        }
    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  }
    477485  return Text.str();
    478486}
Note: See TracChangeset for help on using the changeset viewer.