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