introducing status management: The processing per subdetector is divided into several...
[u/mrichter/AliRoot.git] / SHUTTLE / AliDCSMessage.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.4  2006/07/04 14:59:57  jgrosseo
19 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
20
21 Revision 1.3  2006/06/12 09:11:16  jgrosseo
22 coding conventions (Alberto)
23
24 Revision 1.2  2006/03/07 07:52:34  hristov
25 New version (B.Yordanov)
26
27 Revision 1.3  2005/11/17 17:47:34  byordano
28 TList changed to TObjArray
29
30 Revision 1.2  2005/11/17 14:43:23  byordano
31 import to local CVS
32
33 Revision 1.1.1.1  2005/10/28 07:33:58  hristov
34 Initial import as subdirectory in AliRoot
35
36 Revision 1.1.1.1  2005/09/12 22:11:40  byordano
37 SHUTTLE package
38
39 Revision 1.2  2005/08/30 10:53:23  byordano
40 some more descriptions added
41
42 */
43
44
45 //
46 // This class is a wrapper of AliDCSMessage.
47 // These are the messages which form AliDCSProtocol.
48 // Every message has header and body. The body size is written in the header.
49 // There are five message types:
50 //      1) Request - used by the client to form a single request to DCS server
51 //      2) Count - returned by the server to inidicate the total number of 
52 //              values which would be sent to the client.
53 //      3) ResultSet - returned by the server and contains part of values set
54 //              which forms the server resposen. 
55 //      4) Error - returned by the server in case of error
56 //      5) MultiRequest - used by the client to form multi request.
57 //              This is a request which serves many aliases/dp at the same time
58 //              For all aliases/dp the same time interval is used.      
59 // Short description of the schema:
60 //      The client sends a request (Request or MultiRequest) and the server 
61 //      returns:
62 //              1) Count - the total number of values that the client should 
63 //                      expect.
64 //              2) ResultSet* - every ResultSet message contains a part
65 //                      of valueSet (some values) which the client should expect
66 //                      The client can wait for ResultMessage until it gets
67 //                      all values (total number) which was returned by the
68 //                      Count message at the beginning of the ResutlSet sereie.
69 //      In case of error:
70 //              1) Error - contains the error code and error description
71 //
72
73 #include "AliDCSMessage.h"
74
75 #include "AliLog.h"
76
77 #include <Bytes.h>
78 #include <TObjString.h>
79
80 #include <ctype.h>
81 #include <assert.h>
82
83 ClassImp(AliDCSMessage)
84
85 //______________________________________________________________________
86 AliDCSMessage::AliDCSMessage():
87         fMessage(NULL), fMessageSize(0), fType(kInvalid)
88 {
89 // default constructor
90
91 }
92
93 //______________________________________________________________________
94 AliDCSMessage::AliDCSMessage(const char* message, UInt_t size):
95         fMessageSize(size), fType(kInvalid)
96 {
97 // default constructor
98
99         fMessage = new char[size];
100
101         memcpy(fMessage, message, size);
102 }
103
104 //______________________________________________________________________
105 AliDCSMessage::AliDCSMessage(const AliDCSMessage& /*other*/):
106 TObject()
107 {
108 // copy constructor (not implemented)
109
110 }
111
112 //______________________________________________________________________
113 AliDCSMessage &AliDCSMessage::operator=(const AliDCSMessage& /*other*/)
114 {
115 // assignment operator (not implemented)
116
117 return *this;
118 }
119
120 //______________________________________________________________________
121 AliDCSMessage::~AliDCSMessage() 
122 {
123 // destructor
124
125         DestroyMessage();
126         DestroyBuffer();
127 }
128
129 //______________________________________________________________________
130 void AliDCSMessage::CreateRequestMessage(RequestType type, 
131         UInt_t startTime, UInt_t endTime, const char* request)
132 {
133 // Create request message
134
135         DestroyMessage();
136
137         fType = AliDCSMessage::kRequest;
138         fRequestType = type;
139         fStartTime = startTime;
140         fEndTime = endTime;
141         fRequestString = request;
142 }
143
144 //______________________________________________________________________
145 void AliDCSMessage::CreateMultiRequestMessage(RequestType type, 
146         UInt_t startTime, UInt_t endTime)
147 {
148 // Create multi request message
149
150         DestroyMessage();
151
152         fType = AliDCSMessage::kMultiRequest;
153         fRequestType = type;
154         fStartTime = startTime;
155         fEndTime = endTime;
156 }
157         
158 //______________________________________________________________________
159 void AliDCSMessage::CreateCountMessage(UInt_t count) 
160 {
161 // Create count request message
162
163         DestroyMessage();
164
165         fType = AliDCSMessage::kCount;
166         fCount = count;
167 }
168
169 //______________________________________________________________________
170 void AliDCSMessage::CreateResultSetMessage(AliDCSValue::Type type)
171 {
172   // Create result set message
173
174         DestroyMessage();
175
176         fType = AliDCSMessage::kResultSet;
177         fValueType = type;
178 }
179
180 //______________________________________________________________________
181 void AliDCSMessage::CreateErrorMessage(ErrorCode errorCode, 
182         const char* errorString)
183 {
184 // Create error message
185
186         DestroyMessage();
187
188         fType = AliDCSMessage::kError;
189         fErrorCode = errorCode;
190         fErrorString = errorString;
191 }
192
193 /*
194 void AliDCSMessage::CreateNextMessage() {
195         DestroyMessage();
196
197         fType = AliDCSMessage::kNext;
198 } */
199
200 //______________________________________________________________________
201 void AliDCSMessage::DestroyMessage() 
202 {
203 // Destroy message
204
205         fType = kInvalid;
206         ClearValues();
207         ClearRequestStrings();
208 }
209
210 //______________________________________________________________________
211 void AliDCSMessage::SetBool(char* buf, Bool_t val) 
212 {
213 // Set bool value to buf 
214
215         tobuf(buf, val);
216 }
217
218 //______________________________________________________________________
219 void AliDCSMessage::SetByte(char* buf, Char_t val) 
220 {
221 // Set byte value to buf 
222
223         tobuf(buf, val);
224 }
225
226 //______________________________________________________________________
227 void AliDCSMessage::SetUByte(char* buf, UChar_t val) 
228 {
229 // Set ubyte value to buf
230
231         tobuf(buf, val);
232 }
233
234 //______________________________________________________________________
235 void AliDCSMessage::SetInt(char* buf, Int_t val) 
236 {
237 // Set int value to buf 
238
239         tobuf(buf, val);
240 }
241
242 //______________________________________________________________________
243 void AliDCSMessage::SetUInt(char* buf, UInt_t val) 
244 {
245 // Set uint value to buf 
246
247         tobuf(buf, val);
248 }
249
250 //______________________________________________________________________
251 void AliDCSMessage::SetFloat(char* buf, Float_t val) 
252 {
253 // Set float value to buf 
254
255         tobuf(buf, val);
256 }
257
258 //______________________________________________________________________
259 Bool_t AliDCSMessage::GetBool(const char* buf) 
260 {
261 // get bool value from buf 
262
263         Bool_t val;
264         char* aBuffer = (char*) buf;
265
266         frombuf(aBuffer, &val);
267
268         return val;
269 }
270
271 //______________________________________________________________________
272 Char_t AliDCSMessage::GetByte(const char* buf) 
273 {
274 // get byte value from buf 
275
276         Char_t val;
277         char* aBuffer = (char*) buf;
278
279         frombuf(aBuffer, &val);
280
281         return val;
282 }
283
284 //______________________________________________________________________
285 UChar_t AliDCSMessage::GetUByte(const char* buf) 
286 {
287 // get ubyte value from buf 
288
289         UChar_t val;
290         char* aBuffer = (char*) buf;
291
292         frombuf(aBuffer, &val);
293
294         return val;
295 }
296
297 //______________________________________________________________________
298 Int_t AliDCSMessage::GetInt(const char* buf) 
299 {
300 // get int value from buf 
301
302         Int_t val;
303         char* aBuffer = (char*) buf;
304
305         frombuf(aBuffer, &val);
306
307         return val;
308 }
309
310 //______________________________________________________________________
311 UInt_t AliDCSMessage::GetUInt(const char* buf) 
312 {
313 // get uint value from buf 
314
315         UInt_t val;
316         char* aBuffer = (char*) buf;
317
318         frombuf(aBuffer, &val);
319
320         return val;
321 }
322
323 //______________________________________________________________________
324 Float_t AliDCSMessage::GetFloat(const char* buf) 
325 {
326 // get float value from buf 
327
328         Float_t val;
329         char* aBuffer = (char*) buf;
330
331         frombuf(aBuffer, &val);
332
333         return val;
334 }
335
336 //______________________________________________________________________
337 TString AliDCSMessage::GetString(const char* buf, Int_t maxLen) 
338 {
339 // get string from buf 
340
341         for (Int_t k = 0; k < maxLen; k ++) {
342                 if (buf[k] == 0) {
343                         return TString(buf);
344                 }
345         }
346
347         return TString(buf, maxLen);
348 }
349
350 //______________________________________________________________________
351 void AliDCSMessage::StoreHeader() 
352 {
353 // store header message
354         
355         SetUByte(fMessage + ID_OFFSET, 'A');
356         SetUByte(fMessage + ID_OFFSET + 1, 'D');
357
358         SetUByte(fMessage + VERSION_OFFSET, 1);
359
360         SetUByte(fMessage + TYPE_OFFSET, fType);
361
362         SetUInt(fMessage + BODY_SIZE_OFFSET, fMessageSize - HEADER_SIZE);
363 }
364
365 //______________________________________________________________________
366 void AliDCSMessage::StoreRequestMessage() 
367 {
368 // store request message
369         
370         fMessageSize = REQUEST_STRING_OFFSET +
371                 fRequestString.Length() + 1;
372         
373         fMessage = new char[fMessageSize];
374
375         StoreHeader();
376
377         SetUByte(fMessage + REQUEST_TYPE_OFFSET, fRequestType);
378         SetUInt(fMessage + START_TIME_OFFSET, fStartTime);
379         SetUInt(fMessage + END_TIME_OFFSET, fEndTime);
380         strcpy(fMessage + REQUEST_STRING_OFFSET, fRequestString.Data());
381 }
382
383 //______________________________________________________________________
384 void AliDCSMessage::StoreCountMessage() 
385 {
386 // store count message
387
388         fMessageSize = COUNT_OFFSET + sizeof(UInt_t);
389
390         fMessage = new char[fMessageSize];
391
392         StoreHeader();
393
394         SetUInt(fMessage + COUNT_OFFSET, fCount);
395 }
396
397 //______________________________________________________________________
398 void AliDCSMessage::StoreResultSetMessage()
399 {
400 // store result set message
401
402   TIter iter(&fValues);
403   AliDCSValue* aValue;
404
405   UInt_t valueDataSize = 0;
406   while ((aValue = (AliDCSValue*) iter.Next())) {
407     valueDataSize += aValue->GetSize();
408   }
409
410   fMessageSize = VALUES_OFFSET + valueDataSize;
411
412   fMessage = new char[fMessageSize];
413
414   StoreHeader();
415
416   SetUByte(fMessage + SVT_OFFSET, fValueType);
417   SetUInt(fMessage + VALUE_COUNT_OFFSET, GetValueCount());
418
419   UInt_t cursor = VALUES_OFFSET;
420
421   iter.Reset();
422
423   if (fValueType == AliDCSValue::kBool) {
424     while ((aValue = (AliDCSValue*) iter.Next())) {
425       SetBool(fMessage + cursor, aValue->GetBool());
426       cursor += 1;
427       SetUInt(fMessage + cursor, aValue->GetTimeStamp());
428             cursor += sizeof(UInt_t);
429     }
430   } else if (fValueType == AliDCSValue::kChar) {
431     while ((aValue = (AliDCSValue*) iter.Next())) {
432       SetByte(fMessage + cursor, aValue->GetChar());
433       cursor += sizeof(Char_t);
434       SetUInt(fMessage + cursor, aValue->GetTimeStamp());
435       cursor += sizeof(UInt_t);
436     }
437   } else if (fValueType == AliDCSValue::kInt) {
438     while ((aValue = (AliDCSValue*) iter.Next())) {
439       SetInt(fMessage + cursor, aValue->GetInt());
440       cursor += sizeof(Int_t);
441       SetUInt(fMessage + cursor, aValue->GetTimeStamp());
442       cursor += sizeof(UInt_t);
443     }
444   } else if (fValueType == AliDCSValue::kUInt) {
445     while ((aValue = (AliDCSValue*) iter.Next())) {
446       SetUInt(fMessage + cursor, aValue->GetUInt());
447       cursor += sizeof(UInt_t);
448       SetUInt(fMessage + cursor, aValue->GetTimeStamp());
449       cursor += sizeof(UInt_t);
450     }
451   } else if (fValueType == AliDCSValue::kFloat) {
452     while ((aValue = (AliDCSValue*) iter.Next())) {
453       SetFloat(fMessage + cursor, aValue->GetFloat());
454       cursor += sizeof(Float_t);
455       SetUInt(fMessage + cursor, aValue->GetTimeStamp());
456       cursor += sizeof(UInt_t);
457     }
458   } else {
459     AliError("Invalid or unknown ValueType!");
460     return;
461   }     
462
463 }
464
465 //______________________________________________________________________
466 void AliDCSMessage::StoreErrorMessage() 
467 {
468 // store error message
469
470         fMessageSize = ERROR_STRING_OFFSET + fErrorString.Length() + 1;
471
472         fMessage = new char[fMessageSize];
473
474         StoreHeader();
475
476         SetUByte(fMessage + ERROR_CODE_OFFSET, fErrorCode);
477         strcpy(fMessage + ERROR_STRING_OFFSET, fErrorString.Data());
478 }
479
480 //______________________________________________________________________
481 void AliDCSMessage::StoreMultiRequestMessage() 
482 {
483 // store multi request message
484         
485         UInt_t requestDataSize = 0;
486
487         TIter iter(&fRequestStrings);
488         TObjString* anObjString;
489
490         while ((anObjString = (TObjString*) iter.Next())) {
491                 assert(anObjString->String().Length() <= 255);
492                 requestDataSize += anObjString->String().Length() + 1;
493         }
494
495         fMessageSize = REQUEST_STRINGS_OFFSET + requestDataSize;
496
497         fMessage = new char[fMessageSize];
498         
499         StoreHeader();
500
501         SetUByte(fMessage + REQUEST_TYPE_OFFSET, fRequestType);
502         SetUInt(fMessage + START_TIME_OFFSET, fStartTime);
503         SetUInt(fMessage + END_TIME_OFFSET, fEndTime);
504         
505         iter.Reset();
506
507         UInt_t cursor = REQUEST_STRINGS_OFFSET;
508
509         while ((anObjString = (TObjString*) iter.Next())) {
510                 UChar_t strLength = anObjString->String().Length();
511                 SetUByte(fMessage + cursor, strLength);
512                 cursor += 1;
513                 strncpy(fMessage + cursor, anObjString->String().Data(), 
514                         strLength);
515                 cursor += strLength;
516         }
517 }
518
519 //______________________________________________________________________
520 /*
521 void AliDCSMessage::StoreNextMessage() {
522
523         fMessageSize = HEADER_SIZE;
524
525         fMessage = new char[fMessageSize];
526
527         StoreHeader(); 
528 } */
529
530 //______________________________________________________________________
531 Bool_t AliDCSMessage::ValidateHeader(const char* buf) 
532 {
533 // validate message header
534
535         if (!(buf[ID_OFFSET] == 'A' && buf[ID_OFFSET + 1] == 'D')) {
536                 AliError("Bad message ID!");
537                 return kFALSE;
538         }
539
540         if (buf[VERSION_OFFSET] != 1) {
541                 AliError("Bad message version!");
542                 return kFALSE;
543         }
544
545         Type type = (Type) GetUByte(buf + TYPE_OFFSET); 
546         switch (type) {
547                 case kRequest:
548                 case kCount:
549                 case kResultSet:
550                 case kError:
551                 case kMultiRequest:
552                         break;
553                 default:
554                         AliError("Unknown message type!");
555                         return kFALSE;
556         }
557
558         UInt_t bodySize = GetInt(buf + BODY_SIZE_OFFSET);
559         if (bodySize > MAX_BODY_SIZE) {
560                 AliError("Too big message body size!");
561                 return kFALSE;
562         } 
563
564         return kTRUE;
565 }
566
567 //______________________________________________________________________
568 void AliDCSMessage::LoadRequestMessage() 
569 {
570 // load request message
571
572         if (fMessageSize < REQUEST_STRING_OFFSET) {
573                 AliError("Body size is too small for request message!");
574                 return;
575         }
576
577         fRequestType = (RequestType) GetUByte(fMessage + REQUEST_TYPE_OFFSET);
578
579         fStartTime = GetUInt(fMessage + START_TIME_OFFSET);
580         fEndTime = GetUInt(fMessage + END_TIME_OFFSET);
581         fRequestString = GetString(fMessage + REQUEST_STRING_OFFSET,
582                 fMessageSize - REQUEST_STRING_OFFSET);
583
584         switch (fRequestType) {
585                 case kAlias:
586                 case kDPName:
587                         fType = kRequest;
588                         break;
589                 default:
590                         AliError("Invalid request type!");
591         }
592 }
593
594 //______________________________________________________________________
595 void AliDCSMessage::LoadCountMessage() 
596 {
597 // load count message
598
599         if (fMessageSize < HEADER_SIZE + sizeof(UInt_t)) {
600                 AliError("Body size is too small for count message!");
601                 return;
602         }
603
604         fCount = GetUInt(fMessage + COUNT_OFFSET);
605
606         fType = kCount;
607 }
608
609 //______________________________________________________________________
610 void AliDCSMessage::LoadResultSetMessage()
611 {
612   // load result message
613
614   if (fMessageSize < VALUES_OFFSET) {
615     AliError("Body size is too small for result set message!");
616     return;
617   }
618
619   fValueType = (AliDCSValue::Type) GetUByte(fMessage + SVT_OFFSET);
620   UInt_t count = GetUInt(fMessage + VALUE_COUNT_OFFSET);
621
622   UInt_t cursor = VALUES_OFFSET;
623
624   if (fValueType == AliDCSValue::kBool) {
625     if (VALUES_OFFSET + count + count * sizeof(UInt_t) >
626       fMessageSize) {
627       AliError("Too many bool values for this buffer size!");
628       return;
629     }
630
631     for (UInt_t k = 0; k < count; k ++) {
632       Bool_t aBool = GetBool(fMessage + cursor);
633       cursor += 1;
634       UInt_t timeStamp = GetUInt(fMessage + cursor);
635       cursor += sizeof(UInt_t);
636       fValues.Add(new AliDCSValue(aBool, timeStamp));
637     }
638   } else if (fValueType == AliDCSValue::kChar) {
639     if (VALUES_OFFSET + count + count * sizeof(UInt_t) >
640       fMessageSize) {
641       AliError("Too many byte values for this buffer size!");
642       return;
643     }
644
645     for (UInt_t k = 0; k < count; k ++) {
646       Char_t aByte = GetByte(fMessage + cursor);
647       cursor += sizeof(Char_t);
648       UInt_t timeStamp = GetUInt(fMessage + cursor);
649       cursor += sizeof(UInt_t);
650       fValues.Add(new AliDCSValue(aByte, timeStamp));
651     }
652   } else if (fValueType == AliDCSValue::kInt) {
653     if (VALUES_OFFSET + count * sizeof(Int_t) +
654       count * sizeof(UInt_t) > fMessageSize) {
655             AliError("Too many int values for this buffer size!");
656             return;
657     }
658
659     for (UInt_t k = 0; k < count; k ++) {
660             Int_t aInt = GetInt(fMessage + cursor);
661             cursor += sizeof(Int_t);
662             UInt_t timeStamp = GetUInt(fMessage + cursor);
663             cursor += sizeof(UInt_t);
664             fValues.Add(new AliDCSValue(aInt, timeStamp));
665     }
666
667   } else if (fValueType == AliDCSValue::kUInt) {
668     if (VALUES_OFFSET + count * sizeof(UInt_t) +
669       count * sizeof(UInt_t) > fMessageSize) {
670       AliError("Too many uint values for this buffer size!");
671       return;
672     }
673
674     for (UInt_t k = 0; k < count; k ++) {
675       UInt_t aUInt = GetUInt(fMessage + cursor);
676       cursor += sizeof(UInt_t);
677       UInt_t timeStamp = GetUInt(fMessage + cursor);
678       cursor += sizeof(UInt_t);
679       fValues.Add(new AliDCSValue(aUInt, timeStamp));
680     }
681   } else if (fValueType == AliDCSValue::kFloat) {
682     if (VALUES_OFFSET + count * sizeof(Float_t) +
683       count * sizeof(UInt_t) > fMessageSize) {
684       AliError("Too many float values for this buffer size!");
685       return;
686     }
687
688     for (UInt_t k = 0; k < count; k ++) {
689       Float_t aFloat = GetFloat(fMessage + cursor);
690       cursor += sizeof(Float_t);
691       UInt_t timeStamp = GetUInt(fMessage + cursor);
692       cursor += sizeof(UInt_t);
693       fValues.Add(new AliDCSValue(aFloat, timeStamp));
694     }
695
696   } else {
697     AliError("Unknown or invalid value type!");
698   }
699
700   fType = kResultSet;
701 }
702
703 //______________________________________________________________________
704 void AliDCSMessage::LoadErrorMessage() 
705 {
706 // load error message
707         
708         if (fMessageSize < ERROR_STRING_OFFSET) {
709                 AliError("Body size is too small for error message!");
710                 return;
711         }
712
713         fErrorCode = (ErrorCode) GetUByte(fMessage + ERROR_CODE_OFFSET);
714         fErrorString = GetString(fMessage + ERROR_STRING_OFFSET,
715                 fMessageSize - ERROR_STRING_OFFSET);
716
717         switch (fErrorCode) {
718                 case kUnknownAliasDPName:
719                 case kInvalidTimeRange:
720                 case kInvalidBufferSize:
721                 case kInvalidRequest:
722                 case kUnsupportedType:
723                 case kUnknownError:
724                         fType = kError;
725                         break;
726                 default:
727                         AliError("Invalid error code!");
728         }
729 }
730
731 //______________________________________________________________________
732 void AliDCSMessage::LoadMultiRequestMessage() 
733 {
734 // load multi request message
735         
736         if (fMessageSize - HEADER_SIZE < REQUEST_STRINGS_OFFSET) {
737                 AliError("Body size is too small for multi request message!");
738                 return;
739         }
740
741         fRequestType = (RequestType) GetUByte(fMessage + REQUEST_TYPE_OFFSET);
742
743         fStartTime = GetUInt(fMessage + START_TIME_OFFSET);
744         fEndTime = GetUInt(fMessage + END_TIME_OFFSET);
745
746         switch (fRequestType) { 
747                 case kAlias:
748                 case kDPName:
749                         fType = kRequest;
750                         break; 
751                 default:
752                         AliError("Invalid request type!");
753                         return;
754         }
755
756         UInt_t cursor = REQUEST_STRINGS_OFFSET;
757         
758         while ((cursor < fMessageSize)) {
759                 UChar_t strSize = GetUByte(fMessage + cursor);
760                 cursor += 1;
761
762                 if (cursor + strSize > fMessageSize) {
763                         AliError("Invalid multi request message!");
764                         return;
765                 }               
766
767                 TObjString* anObjString = new TObjString(
768                         GetString(fMessage + cursor, strSize));
769                 fRequestStrings.AddLast(anObjString);
770
771                 cursor += strSize;
772         }       
773
774         fType = kMultiRequest;
775 }
776
777 //______________________________________________________________________
778 /*
779 void AliDCSMessage::LoadNextMessage() {
780         
781         fType = kNext;
782 } */
783
784 //______________________________________________________________________
785 void AliDCSMessage::StoreToBuffer() 
786 {
787         // Creates an underlying message buffer which can be sent to the socket.
788
789         DestroyBuffer();
790         
791         switch (fType) {
792                 case kRequest: 
793                         StoreRequestMessage();
794                         break;
795                 case kCount:
796                         StoreCountMessage();
797                         break;
798                 case kResultSet:
799                         StoreResultSetMessage();
800                         break;
801                 case kError:
802                         StoreErrorMessage();
803                         break;
804                 case kMultiRequest:
805                         StoreMultiRequestMessage();
806                         break;
807 /*              case kNext:
808                         StoreNextMessage();
809                         break; */
810                 default:
811                         AliError("Can't store to buffer invalid message!");
812         }
813 }
814
815 //______________________________________________________________________
816 void AliDCSMessage::LoadFromBuffer() 
817 {
818         // Reads the underlying message buffer and if it's valid message
819         // creates the corresponding message.  
820         // If not set the message type kInvalid.
821         // This buffer is read from the socket.
822         
823         DestroyMessage();
824
825         if (!fMessage) {
826                 AliError("Message buffer is empty! Can't load it.");
827                 return;
828         }
829         
830         if (fMessageSize < HEADER_SIZE) {
831                 AliError("Invalid message buffer. Too small for the header!");
832                 return;
833         }
834
835         if (!ValidateHeader(fMessage)) {
836                 AliError("Invalid message header!");
837                 return;
838         }
839
840         UInt_t bodySize = GetUInt(fMessage + BODY_SIZE_OFFSET);
841         if (bodySize > fMessageSize - HEADER_SIZE) {
842                 AliError("Message size is to small for the message body!");
843                 return;
844         }
845
846         fMessageSize = HEADER_SIZE + bodySize;
847
848         Type aType = (Type) GetUByte(fMessage + TYPE_OFFSET);
849         
850         switch (aType) {
851                 case kRequest:
852                         LoadRequestMessage();
853                         break;
854                 case kCount:
855                         LoadCountMessage();
856                         break;
857                 case kResultSet:
858                         LoadResultSetMessage();
859                         break;
860                 case kError:
861                         LoadErrorMessage();
862                         break;
863                 case kMultiRequest:
864                         LoadMultiRequestMessage();
865                         break;
866 /*              case kNext:
867                         LoadNextMessage();
868                         break; */
869                 default:
870                         AliError("Invalid message type!");
871         }       
872 }
873
874 //______________________________________________________________________
875 AliDCSMessage::RequestType AliDCSMessage::GetRequestType() const 
876 {
877         // Request and MultiRequest.
878         // Returns the request type: alias or dp (Data Point)
879
880         if (!(fType == kRequest || fType == kMultiRequest)) {
881                 AliError("Invalid AliDCSMessage type!");
882                 return kNoneType;
883         }
884
885         return fRequestType;
886 }
887
888 //______________________________________________________________________
889 UInt_t AliDCSMessage::GetStartTime() const 
890 {
891         // Request and MultiRequest.
892         // Returns the request start time. (begining of the time interval).
893
894         if (!(fType == kRequest || fType == kMultiRequest)) {
895                 AliError("Invalid AliDCSMessage type!");
896                 return 0;
897         }
898
899         return fStartTime;
900 }
901
902 //______________________________________________________________________
903 UInt_t AliDCSMessage::GetEndTime() const 
904 {
905         // Request and MultiRequest.
906         // Returns the request start time. (end of the time interval).
907
908         
909         if (!(fType == kRequest || fType == kMultiRequest)) {
910                 AliError("Invalid AliDCSMessage type!");
911                 return 0;
912         }
913
914         return  fEndTime;
915 }
916
917 //______________________________________________________________________
918 TString AliDCSMessage::GetRequestString() const 
919 {
920         // Request.
921         // Returns the request string. (alias or dp)
922
923         if (fType != kRequest) {
924                 AliError("Invalid AliDCSMessage type!");
925                 return TString("");
926         }
927
928         return fRequestString;
929 }
930
931 //______________________________________________________________________
932 Bool_t AliDCSMessage::AddRequestString(const char* request) 
933 {
934         // MultRequest.
935         // Add a request to the request set.
936         // Returns kFALSE in case of invalid request (too long request string).
937         // Otherwise returns kTRUE.
938  
939         
940         if (fType != kMultiRequest) {
941                 AliError("Invalid AliDCSMessage type!");
942                 return kFALSE;
943         }
944
945         if (strlen(request) > 255) {
946                 AliError("Alias/dpName is too long! Max size 255.");
947                 return kFALSE;  
948         }
949
950         fRequestStrings.AddLast(new TObjString(request));
951         return kTRUE;
952 }
953
954 //______________________________________________________________________
955 void AliDCSMessage::ClearRequestStrings() 
956 {
957         // MultRequest.
958         // Clears the request set.
959  
960         fRequestStrings.Delete();
961 }
962
963 //______________________________________________________________________
964 void AliDCSMessage::GetRequestStrings(TObjArray& result) const 
965 {
966         // MultRequest.
967         // Returns all request strings in this message.
968         // result: container where the requests are returned. Collection of
969         // TObjString.
970
971
972         if (fType != kMultiRequest) {
973                 AliError("Invalid AliDCSMessage type!");
974                 return;
975         }
976
977         TIter iter(&fRequestStrings);
978         TObjString* anObjString;
979         
980         while ((anObjString = (TObjString*) iter.Next())) {
981                 result.AddLast(new TObjString(*anObjString));
982         }
983 }
984
985 //______________________________________________________________________
986 UInt_t AliDCSMessage::GetCount() const 
987 {
988         // Count.
989         // Returns the total number of values.
990
991
992         if (fType != kCount) {
993                 AliError("Invalid AliDCSMessage type!");
994                 return 0;
995         }
996
997         return fCount;
998 }
999
1000 //______________________________________________________________________
1001 AliDCSValue::Type AliDCSMessage::GetValueType() const
1002 {
1003   // ResultSet.
1004   // Returns simple value type (see AliDCSValue) for the values
1005   // in this ResultSet.
1006
1007   if (fType != kResultSet) {
1008           AliError("Invalid AliDCSMessage type!");
1009           return AliDCSValue::kInvalid;
1010   }
1011
1012   return fValueType;
1013 }
1014
1015 //______________________________________________________________________
1016 UInt_t AliDCSMessage::GetValueCount() const 
1017 {
1018   // ResultSet.
1019   // Returns the count of values in this ResultSet.
1020
1021
1022   if (fType != kResultSet) {
1023           AliError("Invalid AliDCSMessage type!");
1024           return 0;
1025   }
1026
1027   return fValues.GetEntriesFast();
1028 }
1029
1030 //______________________________________________________________________
1031 UInt_t AliDCSMessage::GetValues(TObjArray& result) const
1032 {
1033   // ResultSet.
1034   // Returns the number of values got from the message.
1035   // result: used to return the values. Collection of AliDCSValue.
1036
1037   // TODO do not copy
1038
1039         if (fType != kResultSet) {
1040                 AliError("Invalid AliDCSMessage type!");
1041                 return 0;
1042         }
1043
1044         TIter iter(&fValues);
1045         AliDCSValue* aValue;
1046         
1047         while ((aValue = (AliDCSValue*) iter.Next())) {
1048                 result.AddLast(new AliDCSValue(*aValue));
1049         }
1050
1051         return fValues.GetEntriesFast();
1052 }
1053
1054 //______________________________________________________________________
1055 Bool_t AliDCSMessage::AddValue(const AliDCSValue& value) 
1056 {
1057   // Adds value to the ResultSet value list.
1058   // Returns kFALSE in case of error.
1059   // Otherwise returns kTRUE;
1060
1061   if (fType != kResultSet) {
1062     AliError("Invalid AliDCSMessage type!");
1063     return kFALSE;
1064   }
1065
1066   if (value.GetType() != fValueType) {
1067     AliError(Form("Can't add value with type %d to this message!", value.GetType()));
1068     return kFALSE;
1069   }
1070
1071   fValues.Add(new AliDCSValue(value));
1072
1073   return kTRUE;
1074 }
1075
1076 //______________________________________________________________________
1077 void AliDCSMessage::ClearValues() 
1078 {
1079 // clear values array
1080
1081         fValues.Delete();
1082 }
1083
1084 //______________________________________________________________________
1085 AliDCSMessage::ErrorCode AliDCSMessage::GetErrorCode() const 
1086 {
1087         //
1088         // Error.
1089         // Returns the error code which has this error message.
1090         //
1091
1092         if (fType != kError) {
1093                 AliError("Invalid AliDCSMessage type!");
1094                 return kNoneError;
1095         }
1096
1097         return fErrorCode;
1098 }
1099
1100 //______________________________________________________________________
1101 TString AliDCSMessage::GetErrorString() const 
1102 {
1103         //
1104         // Error.
1105         // Returns the error string (error description) which has this 
1106         // error message.
1107         //
1108
1109         if (GetType() != kError) {
1110                 AliError("Invalid AliDCSMessage type!");
1111                 return TString("");
1112         }
1113
1114         return fErrorString;
1115 }
1116
1117
1118 //______________________________________________________________________
1119 void AliDCSMessage::Print(Option_t* /*option*/) const 
1120 {
1121 // print message
1122
1123         if (AliLog::GetGlobalDebugLevel() < 2) {
1124                 return;
1125         }
1126
1127         TString printString;
1128         printString += "\n <<AliDCSMessage>>\n";
1129
1130         printString += " Size: ";
1131         printString += fMessageSize;
1132         printString += '\n';
1133
1134         printString += " Type: ";
1135         switch (GetType()) {
1136                 case kRequest: {
1137                         printString += "Request\n";
1138
1139                         printString += " RequestType: ";
1140                         if (GetRequestType() == kDPName) {
1141                                 printString += "DPName";
1142                         } else {
1143                                 printString += "Alias";
1144                         }
1145                         printString += '\n';
1146
1147                         printString += " RequestString: ";
1148                         printString += GetRequestString();
1149                         printString += '\n';
1150                         printString += " StartTime: ";
1151                         printString += GetStartTime();
1152                         printString += '\n';
1153                         printString += " EndTime: ";
1154                         printString += GetEndTime();
1155                         printString += '\n';
1156                         break;
1157                 }
1158
1159                 case kCount: {
1160                         printString += "Count\n";
1161                         printString += " Count: ";
1162                         printString += GetCount();
1163                         printString += '\n';    
1164                         break;
1165                 } 
1166
1167                 case kResultSet: {
1168                         printString += "ResultSet\n";
1169                         printString += " SimpleValueType: ";
1170                         printString += fValueType;
1171                         printString += '\n';
1172                         printString += " ValueCount: ";
1173                         printString += GetValueCount();
1174                         printString += '\n';
1175                         break;
1176                 }
1177
1178                 case kError: {
1179                         printString += "Error\n";
1180                         printString += " ErrorCode: ";
1181                         switch (GetErrorCode()) {
1182                                 case AliDCSMessage::kNoneError:
1183                                         printString += "NoneError";
1184                                         break;
1185                                 case AliDCSMessage::kUnknownAliasDPName:
1186                                         printString += "UnknownAliasDPName";
1187                                         break;
1188                                 case AliDCSMessage::kInvalidTimeRange:
1189                                         printString += "InvalidTimeRange";
1190                                         break;
1191                                 case AliDCSMessage::kInvalidBufferSize:
1192                                         printString += "InvalidBufferSize";
1193                                         break;
1194                                 case AliDCSMessage::kInvalidRequest:
1195                                         printString += "InvalidRequest";
1196                                         break;
1197                                 case AliDCSMessage::kUnsupportedType:
1198                                         printString += "UnsupportedType";
1199                                         break;
1200                                 case AliDCSMessage::kUnknownError:
1201                                         printString += "UnknownError";
1202                                         break;
1203                                 default:
1204                                         printString += "Invalid";
1205                         }
1206
1207                         printString += '\n';
1208                         printString += " ErrorString: ";
1209                         printString += GetErrorString();
1210                         printString += '\n';
1211                         break;
1212                 }
1213
1214                 case kMultiRequest: {
1215                         printString += "MultiRequest\n";
1216
1217                         printString += " RequestType: ";
1218                         if (GetRequestType() == kDPName) {
1219                                 printString += "DPName";
1220                         } else {
1221                                 printString += "Alias";
1222                         }
1223                         printString += '\n';
1224
1225                         printString += " RequestStrings: ";
1226                         TIter iter(&fRequestStrings);
1227                         TObjString* anObjString;
1228                         while ((anObjString = (TObjString*) iter.Next())) {
1229                                 printString += anObjString->String();
1230                                 printString += ' ';
1231                         }
1232                         printString += '\n';
1233
1234                         printString += " StartTime: ";
1235                         printString += GetStartTime();
1236                         printString += '\n';
1237                         printString += " EndTime: ";
1238                         printString += GetEndTime();
1239                         printString += '\n';
1240                         break;
1241                 }       
1242
1243 /*              case kNext: {
1244                         printString += "Next\n";
1245                         break;
1246                 } */
1247
1248                 default:
1249                         printString += "Invalid\n";
1250         }
1251
1252         if (AliLog::GetGlobalDebugLevel() >= 3 && fMessage) {
1253                 PrintBuffer(fMessage, fMessageSize, printString);
1254         }
1255
1256         AliDebug(2, printString);
1257
1258
1259 //______________________________________________________________________
1260 Bool_t AliDCSMessage::SetRawHeader(const char* header) 
1261 {
1262         //
1263         // Checks if the header buffer represents a valid header message.
1264         // If so it creates a message buffer with the appropriate body size
1265         // and returns true.
1266         // If not returns false.
1267         // header: header buffer
1268         //
1269
1270         if (!ValidateHeader(header)) {
1271                 AliError("Invalid message header!");
1272                 return kFALSE;
1273         }
1274         
1275         DestroyBuffer();
1276
1277         UInt_t bodySize = GetUInt(header + BODY_SIZE_OFFSET);
1278         fMessageSize = HEADER_SIZE + bodySize;
1279         
1280         fMessage = new char[fMessageSize];
1281         
1282         memcpy(fMessage, header, HEADER_SIZE);
1283
1284         return kTRUE;
1285 }
1286
1287
1288 //______________________________________________________________________
1289 void AliDCSMessage::DestroyBuffer() 
1290 {
1291         //
1292         // Destroy the underlying message buffer.
1293         //
1294         
1295         if (fMessage) {
1296                 delete[] fMessage;
1297                 fMessage = NULL;
1298         }
1299
1300         fMessageSize = 0;
1301 }
1302
1303 //______________________________________________________________________
1304 void AliDCSMessage::PrintBuffer(const char* buffer, UInt_t size, 
1305                 TString& output)
1306 {
1307 // print buffer
1308
1309         UInt_t index = 0;
1310
1311         while (index < size) {
1312                 if (!(index % 16)) {
1313                         output += Form("\n %.4x:", index); 
1314                 }       
1315
1316                 if (!(index % 8)) {
1317                         output += ' ';
1318                 }
1319
1320                 output += Form(" %.2x", (UChar_t) buffer[index]);
1321
1322                 if (!((index + 1) % 16) || index + 1 == size) {
1323                         if (index + 1 == size) {
1324                                 output.Append(' ',3 * (15 - index % 16));
1325                                 if (index % 16 < 8) {
1326                                         output.Append(' ');
1327                                 }
1328                         }
1329
1330                         output.Append(' ', 2);
1331                         for (Int_t k = index % 16; k >= 0; k --) {
1332                                 Char_t aChar = buffer[index - k];
1333                                 output += isgraph(aChar) ? aChar: '.';
1334                         }
1335                 } 
1336
1337                 index ++;
1338         }
1339
1340         output += '\n';
1341 }