Index: fact/Evidence/DColl.cc
===================================================================
--- fact/Evidence/DColl.cc	(revision 12909)
+++ fact/Evidence/DColl.cc	(revision 12910)
@@ -393,4 +393,7 @@
 //
 int main() {
+
+  dic_disable_padding();
+  dis_disable_padding();
         
   // Static ensures calling of destructor by exit()
Index: fact/Evidence/Doc/Evidence.tex
===================================================================
--- fact/Evidence/Doc/Evidence.tex	(revision 12909)
+++ fact/Evidence/Doc/Evidence.tex	(revision 12910)
@@ -185,5 +185,5 @@
 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.
 
-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.
+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.
 
 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,5 +298,5 @@
 \multicolumn{2}{l}{\lstinline|History <Directory for storing history buffers>|} \\[1ex]
 \multicolumn{2}{l}{\textbf{Configuration section \lstinline|[History]|}} \\
-\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|.\\
+\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.\\
 \lstinline|maxsize_kb| & Maximum size of a single history buffer in kByte. Default value is 2000.\\
 \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.\\
Index: fact/Evidence/Evidence.cc
===================================================================
--- fact/Evidence/Evidence.cc	(revision 12909)
+++ fact/Evidence/Evidence.cc	(revision 12910)
@@ -103,4 +103,7 @@
   This = this;
 
+  dis_disable_padding();
+  dic_disable_padding();
+  
   // Initialise mutex
   int Ret;
@@ -407,72 +410,77 @@
 
 // Translates DIM data safely to string (assures no invalid memory accesses are made)
-string EvidenceServer::ToString(char *Format, void *Data, int Size) {
+// Structure evaluation requires that no padding is used
+string EvidenceServer::ToString(char *Format, const void *Data, int Size) {
 
   ostringstream Text;
-  
-  // 'Message' service format handled here
-  if (strcmp(Format, "I:1;C") == 0 && Size >= (int) sizeof(struct Message)) {
-	struct Message *Msg = (struct Message *) Data;
-	// Safely extract string and limit to length of C string (padding might make it longer)
-	string MsgText(Msg->Text, Size-sizeof(struct Message));
-	Text << Msg->Severity << " " << MsgText.erase(strlen(MsgText.c_str()));
-
-	return Text.str();
-  }
-
-  // String if format "C" and terminated with \0
-  if (strcmp(Format, "C") == 0 && Size > 0 && *((char *) Data+Size-1)=='\0') {
-	return string((char *) Data);
-  }
-  
-  // Check if format is made of identical component types
-  vector<string> Components = Tokenize(Format, ";");
-  
-  for (unsigned int i=0; i<Components.size(); i++) {
-  	if (Components[i].empty()) return string();
-
-	// Print hex representation if format complex
-	if (Components[i][0] != Components[0][0]) {
-	  for (int i=0; i<Size; i++) {
-		Text << setw(2) << hex << *((char *) Data + i) << " ";
-	  } 
-	  return Text.str();
-	}
-  }
-  
-  // Number array
-  int ElementSize;
-
-  switch (toupper(*Format)) {
-    case 'B':
-	case 'V':
-    case 'C': ElementSize = sizeof(char);		break;
-    case 'I':
-    case 'L': ElementSize = sizeof(int);		break;
-    case 'S': ElementSize = sizeof(short);		break;
-    case 'F': ElementSize = sizeof(float);		break;
-    case 'D': ElementSize = sizeof(double);		break;
-    case 'X': ElementSize = sizeof(long long);	break;
-    default: return string();
-  }
-
-  for (int i=0; i<Size/ElementSize; i++) {
-	// Space between entries
-    if (i != 0) Text << " ";
-
-	// Translate data
-	switch (toupper(*Format)) {
+  vector<string> Components;
+  int ElementSize, N, Byte = 0;
+
+  // Find component types
+  Components = Tokenize(Format, ";");
+  
+  for (unsigned int n=0; n<Components.size(); n++) {
+    // If empty, format error
+  	if (Components[n].empty()) return string();
+
+	// Determine maximum number of elements 
+	if (Components[n].size() > 2) N = atoi(Components[n].c_str()+2); 
+	else N = numeric_limits<int>::max();
+
+	// Determine length in bytes of elements
+	switch (toupper(Components[n][0])) {
 	  case 'B':
 	  case 'V':
-      case 'C': Text << *((char *) Data + i);		break;
-      case 'I':
-      case 'L': Text << *((int *) Data + i);		break;
-      case 'S': Text << *((short *) Data + i);		break;
-      case 'F': Text << *((float *) Data + i);		break;
-      case 'D': Text << *((double *) Data + i);		break;
-      case 'X': Text << *((long long *) Data + i);	break;
+	  case 'C': ElementSize = sizeof(char);			break;
+	  case 'I':
+	  case 'L': ElementSize = sizeof(int);			break;
+	  case 'S': ElementSize = sizeof(short);		break;
+	  case 'F': ElementSize = sizeof(float);		break;
+	  case 'D': ElementSize = sizeof(double);		break;
+	  case 'X': ElementSize = sizeof(long long);	break;
+	  default: return string();
 	}
-  }
-  
+
+	// Covert elements
+	for (int i=0; i<N; i++) {	
+	  // Check that not overrunning memory
+	  if (Byte + ElementSize > Size) return Text.str();
+	  
+	  // Translate elements into text (handle string specially when format is 'C')
+	  switch (toupper(Components[n][0])) {
+    	case 'C': if (Components[n].size() == 1) {
+					string String((char *) Data, Size-Byte);
+					
+					// Remove trailing '\0'
+					if (!String.empty() && String[String.size()-1] == '\0') String.resize(String.size()-1);
+					
+					Text << String;
+					return Text.str();
+				  }
+				  Text << *((char *) Data);
+				  break;
+		case 'B':
+		case 'V': Text << *((char *) Data);
+				  break;
+    	case 'I':
+    	case 'L': Text << *((int *) Data);
+				  break;
+    	case 'S': Text << *((short *) Data);
+				  break;
+    	case 'F': Text << *((float *) Data);
+				  break;
+    	case 'D': Text << *((double *) Data);
+				  break;
+    	case 'X': Text << *((long long *) Data);
+			      break;
+	  }
+
+	  Byte += ElementSize;
+	  Data = (void *) ((char *) Data + ElementSize);
+
+	  // Space between entries
+	  Text << " ";
+	}
+  }
   return Text.str();
 }
Index: fact/Evidence/Evidence.h
===================================================================
--- fact/Evidence/Evidence.h	(revision 12909)
+++ fact/Evidence/Evidence.h	(revision 12910)
@@ -11,4 +11,5 @@
 #include <map>
 #include <set>
+#include <limits>
 
 #include <exception>
@@ -79,5 +80,5 @@
 	static void Lock();
 	static void Unlock();
-	static std::string ToString(char *, void *, int);
+	static std::string ToString(char *, const void *, int);
 	static bool ServiceOK(DimInfo *);
 	static bool ServiceOK(DimRpcInfo *);
Index: fact/Evidence/GUI.cc
===================================================================
--- fact/Evidence/GUI.cc	(revision 12909)
+++ fact/Evidence/GUI.cc	(revision 12910)
@@ -29,5 +29,4 @@
   if (strcmp(Service, "Edd/Rate_kBSec") == 0) Format = "F";
   else if (Hist == NULL || Hist->GetFormat() == NULL) {
-	//QMessageBox::warning(NULL, "Edd Message", QString("Could not retrieve history for service ") + Service ,QMessageBox::Ok);
 	printf("Edd Message: Could not retrieve history for service %s\n", Service);
   }
@@ -49,5 +48,5 @@
   QGridLayout *Layout = new QGridLayout(M->centralWidget());
   
-  if (Format.size() == 1 && Format[0] == 'C') Layout->addWidget(new EddText(Service), 0, 0);
+  if (Format.endsWith('C', Qt::CaseInsensitive)) Layout->addWidget(new EddText(Service), 0, 0);
   else  {
     EddPlot *W = new EddPlot(Service, FromIndex);
@@ -387,13 +386,6 @@
 	double Number=0;
 	while ((R=Hist->Next()) != NULL) {
-	  switch (*(Hist->GetFormat())) {
-    	case 'I':
-		case 'L':  Number = *((int *) R->Data + N.Index);   break;
-    	case 'S':  Number = *((short *) R->Data + N.Index);   break;
-    	case 'F':  Number = *((float *) R->Data + N.Index);   break;
-    	case 'D':  Number = *((double *) R->Data + N.Index);   break;
-    	case 'X':  Number = *((long long *) R->Data + N.Index);   break;
-    	default: break;
-	  }
+	  std::vector<std::string> Data = EvidenceServer::Tokenize(EvidenceServer::ToString(Hist->GetFormat(), R->Data, R->Size));
+	  if (N.Index > 0 && N.Index < (int) Data.size()) Number = atof(Data[N.Index].c_str());
 	  AddPoint(List.size()-1, R->Time, Number);
 	}
Index: fact/Evidence/History.cc
===================================================================
--- fact/Evidence/History.cc	(revision 12909)
+++ fact/Evidence/History.cc	(revision 12910)
@@ -426,4 +426,7 @@
   }
 
+  dic_disable_padding();
+  dis_disable_padding();
+
   // Static ensures calling of destructor by exit()
   static History Hist(argv[1]);
Index: fact/Evidence/readme.txt
===================================================================
--- fact/Evidence/readme.txt	(revision 12909)
+++ fact/Evidence/readme.txt	(revision 12910)
@@ -60,2 +60,4 @@
 			into account (e.g. Service:a-b:0.4 requires an minimum absolute change of 0.4 for the average
 			value of indices a to b)
+20/2/2012	Disabled padding per default in Evidence class constructor, and also in History and DColl
+			servers. EvidenceServer::ToString() can because of this now handle all format strings. 
Index: fact/tools/Edd/Edd.cc
===================================================================
--- fact/tools/Edd/Edd.cc	(revision 12909)
+++ fact/tools/Edd/Edd.cc	(revision 12910)
@@ -962,5 +962,5 @@
   // Check if index was given
   if (List.size() == 1) {
-	OpenHistory(List[0].toAscii().data(), 0);
+	OpenHistory(List[0].toAscii().data(), -1);
 	return;
   }
@@ -1114,4 +1114,8 @@
   if (argc>1 && strcmp(argv[1],"drsdaq")==0) DRSBoard = "drsdaq";
 
+  // EvidenceServer::ToString() works for structures only without padding
+  dic_disable_padding();
+  dis_disable_padding();
+
   // Make RPC to get pixelmap
   DimRpcInfo RPC((char *) "ConfigRequest", (char *) "");
