coding conventions (Alberto)
[u/mrichter/AliRoot.git] / SHUTTLE / AliDCSMessage.cxx
CommitLineData
73abe331 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$
58bc3020 18Revision 1.2 2006/03/07 07:52:34 hristov
19New version (B.Yordanov)
20
d477ad88 21Revision 1.3 2005/11/17 17:47:34 byordano
22TList changed to TObjArray
23
24Revision 1.2 2005/11/17 14:43:23 byordano
25import to local CVS
26
27Revision 1.1.1.1 2005/10/28 07:33:58 hristov
28Initial import as subdirectory in AliRoot
29
73abe331 30Revision 1.1.1.1 2005/09/12 22:11:40 byordano
31SHUTTLE package
32
33Revision 1.2 2005/08/30 10:53:23 byordano
34some 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
77ClassImp(AliDCSMessage)
78
58bc3020 79//______________________________________________________________________
73abe331 80AliDCSMessage::AliDCSMessage():
81 fMessage(NULL), fMessageSize(0), fType(kInvalid)
82{
58bc3020 83// default constructor
73abe331 84
85}
86
58bc3020 87//______________________________________________________________________
73abe331 88AliDCSMessage::AliDCSMessage(const char* message, UInt_t size):
89 fMessageSize(size), fType(kInvalid)
90{
58bc3020 91// default constructor
92
73abe331 93 fMessage = new char[size];
94
95 memcpy(fMessage, message, size);
96}
97
58bc3020 98//______________________________________________________________________
99AliDCSMessage::AliDCSMessage(const AliDCSMessage& /*other*/):
100TObject()
101{
102// copy constructor (not implemented)
103
104}
105
106//______________________________________________________________________
107AliDCSMessage &AliDCSMessage::operator=(const AliDCSMessage& /*other*/)
108{
109// assignment operator (not implemented)
110
111return *this;
112}
113
114//______________________________________________________________________
115AliDCSMessage::~AliDCSMessage()
116{
117// destructor
118
73abe331 119 DestroyMessage();
120 DestroyBuffer();
121}
122
58bc3020 123//______________________________________________________________________
73abe331 124void AliDCSMessage::CreateRequestMessage(RequestType type,
125 UInt_t startTime, UInt_t endTime, const char* request)
126{
58bc3020 127// Create request message
128
73abe331 129 DestroyMessage();
130
131 fType = AliDCSMessage::kRequest;
132 fRequestType = type;
133 fStartTime = startTime;
134 fEndTime = endTime;
135 fRequestString = request;
136}
137
58bc3020 138//______________________________________________________________________
73abe331 139void AliDCSMessage::CreateMultiRequestMessage(RequestType type,
140 UInt_t startTime, UInt_t endTime)
141{
58bc3020 142// Create multi request message
143
73abe331 144 DestroyMessage();
145
146 fType = AliDCSMessage::kMultiRequest;
147 fRequestType = type;
148 fStartTime = startTime;
149 fEndTime = endTime;
150}
151
58bc3020 152//______________________________________________________________________
153void AliDCSMessage::CreateCountMessage(UInt_t count)
154{
155// Create count request message
156
73abe331 157 DestroyMessage();
158
159 fType = AliDCSMessage::kCount;
160 fCount = count;
161}
162
58bc3020 163//______________________________________________________________________
164void AliDCSMessage::CreateResultSetMessage(AliSimpleValue::Type type)
165{
166// Create result set message
167
73abe331 168 DestroyMessage();
169
170 fType = AliDCSMessage::kResultSet;
171 fSimpleValueType = type;
172}
173
58bc3020 174//______________________________________________________________________
73abe331 175void AliDCSMessage::CreateErrorMessage(ErrorCode errorCode,
176 const char* errorString)
177{
58bc3020 178// Create error message
179
73abe331 180 DestroyMessage();
181
182 fType = AliDCSMessage::kError;
183 fErrorCode = errorCode;
184 fErrorString = errorString;
185}
186
187/*
188void AliDCSMessage::CreateNextMessage() {
189 DestroyMessage();
190
191 fType = AliDCSMessage::kNext;
192} */
193
58bc3020 194//______________________________________________________________________
195void AliDCSMessage::DestroyMessage()
196{
197// Destroy message
198
73abe331 199 fType = kInvalid;
200 ClearValues();
201 ClearRequestStrings();
202}
203
58bc3020 204//______________________________________________________________________
205void AliDCSMessage::SetBool(char* buf, Bool_t val)
206{
207// Set bool value to buf
208
73abe331 209 tobuf(buf, val);
210}
211
58bc3020 212//______________________________________________________________________
213void AliDCSMessage::SetByte(char* buf, Char_t val)
214{
215// Set byte value to buf
216
73abe331 217 tobuf(buf, val);
218}
219
58bc3020 220//______________________________________________________________________
221void AliDCSMessage::SetUByte(char* buf, UChar_t val)
222{
223// Set ubyte value to buf
224
73abe331 225 tobuf(buf, val);
226}
227
58bc3020 228//______________________________________________________________________
229void AliDCSMessage::SetInt(char* buf, Int_t val)
230{
231// Set int value to buf
232
73abe331 233 tobuf(buf, val);
234}
235
58bc3020 236//______________________________________________________________________
237void AliDCSMessage::SetUInt(char* buf, UInt_t val)
238{
239// Set uint value to buf
240
73abe331 241 tobuf(buf, val);
242}
243
58bc3020 244//______________________________________________________________________
245void AliDCSMessage::SetFloat(char* buf, Float_t val)
246{
247// Set float value to buf
248
73abe331 249 tobuf(buf, val);
250}
251
58bc3020 252//______________________________________________________________________
253Bool_t AliDCSMessage::GetBool(const char* buf)
254{
255// get bool value from buf
256
73abe331 257 Bool_t val;
258 char* aBuffer = (char*) buf;
259
260 frombuf(aBuffer, &val);
261
262 return val;
263}
264
58bc3020 265//______________________________________________________________________
266Char_t AliDCSMessage::GetByte(const char* buf)
267{
268// get byte value from buf
269
73abe331 270 Char_t val;
271 char* aBuffer = (char*) buf;
272
273 frombuf(aBuffer, &val);
274
275 return val;
276}
277
58bc3020 278//______________________________________________________________________
279UChar_t AliDCSMessage::GetUByte(const char* buf)
280{
281// get ubyte value from buf
282
73abe331 283 UChar_t val;
284 char* aBuffer = (char*) buf;
285
286 frombuf(aBuffer, &val);
287
288 return val;
289}
290
58bc3020 291//______________________________________________________________________
292Int_t AliDCSMessage::GetInt(const char* buf)
293{
294// get int value from buf
295
73abe331 296 Int_t val;
297 char* aBuffer = (char*) buf;
298
299 frombuf(aBuffer, &val);
300
301 return val;
302}
303
58bc3020 304//______________________________________________________________________
305UInt_t AliDCSMessage::GetUInt(const char* buf)
306{
307// get uint value from buf
308
73abe331 309 UInt_t val;
310 char* aBuffer = (char*) buf;
311
312 frombuf(aBuffer, &val);
313
314 return val;
315}
316
58bc3020 317//______________________________________________________________________
318Float_t AliDCSMessage::GetFloat(const char* buf)
319{
320// get float value from buf
321
73abe331 322 Float_t val;
323 char* aBuffer = (char*) buf;
324
325 frombuf(aBuffer, &val);
326
327 return val;
328}
329
58bc3020 330//______________________________________________________________________
331TString AliDCSMessage::GetString(const char* buf, Int_t maxLen)
332{
333// get string from buf
73abe331 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
58bc3020 344//______________________________________________________________________
345void AliDCSMessage::StoreHeader()
346{
347// store header message
73abe331 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
58bc3020 359//______________________________________________________________________
360void AliDCSMessage::StoreRequestMessage()
361{
362// store request message
73abe331 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
58bc3020 377//______________________________________________________________________
378void AliDCSMessage::StoreCountMessage()
379{
380// store count message
73abe331 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
58bc3020 391//______________________________________________________________________
392void AliDCSMessage::StoreResultSetMessage()
393{
394// store result set message
73abe331 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
58bc3020 538//______________________________________________________________________
539void AliDCSMessage::StoreErrorMessage()
540{
541// store error message
73abe331 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
58bc3020 553//______________________________________________________________________
554void AliDCSMessage::StoreMultiRequestMessage()
555{
556// store multi request message
73abe331 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
58bc3020 592//______________________________________________________________________
73abe331 593/*
594void AliDCSMessage::StoreNextMessage() {
595
596 fMessageSize = HEADER_SIZE;
597
598 fMessage = new char[fMessageSize];
599
600 StoreHeader();
601} */
602
58bc3020 603//______________________________________________________________________
604Bool_t AliDCSMessage::ValidateHeader(const char* buf)
605{
606// validate message header
73abe331 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
58bc3020 640//______________________________________________________________________
641void AliDCSMessage::LoadRequestMessage()
642{
643// load request message
73abe331 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
58bc3020 667//______________________________________________________________________
668void AliDCSMessage::LoadCountMessage()
669{
670// load count message
73abe331 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
58bc3020 682//______________________________________________________________________
683void AliDCSMessage::LoadResultSetMessage()
684{
685// load result message
73abe331 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
58bc3020 777//______________________________________________________________________
778void AliDCSMessage::LoadErrorMessage()
779{
780// load error message
73abe331 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
58bc3020 805//______________________________________________________________________
806void AliDCSMessage::LoadMultiRequestMessage()
807{
808// load multi request message
73abe331 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));
d477ad88 843 fRequestStrings.AddLast(anObjString);
73abe331 844
845 cursor += strSize;
846 }
847
848 fType = kMultiRequest;
849}
850
58bc3020 851//______________________________________________________________________
73abe331 852/*
853void AliDCSMessage::LoadNextMessage() {
854
855 fType = kNext;
856} */
857
58bc3020 858//______________________________________________________________________
859void AliDCSMessage::StoreToBuffer()
860{
861 // Creates an underlying message buffer which can be sent to the socket.
73abe331 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
58bc3020 889//______________________________________________________________________
890void AliDCSMessage::LoadFromBuffer()
891{
73abe331 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.
73abe331 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
58bc3020 948//______________________________________________________________________
949AliDCSMessage::RequestType AliDCSMessage::GetRequestType() const
950{
73abe331 951 // Request and MultiRequest.
952 // Returns the request type: alias or dp (Data Point)
73abe331 953
954 if (!(fType == kRequest || fType == kMultiRequest)) {
955 AliError("Invalid AliDCSMessage type!");
956 return kNoneType;
957 }
958
959 return fRequestType;
960}
961
58bc3020 962//______________________________________________________________________
963UInt_t AliDCSMessage::GetStartTime() const
964{
73abe331 965 // Request and MultiRequest.
966 // Returns the request start time. (begining of the time interval).
73abe331 967
968 if (!(fType == kRequest || fType == kMultiRequest)) {
969 AliError("Invalid AliDCSMessage type!");
970 return 0;
971 }
972
973 return fStartTime;
974}
975
58bc3020 976//______________________________________________________________________
977UInt_t AliDCSMessage::GetEndTime() const
978{
73abe331 979 // Request and MultiRequest.
980 // Returns the request start time. (end of the time interval).
73abe331 981
982
983 if (!(fType == kRequest || fType == kMultiRequest)) {
984 AliError("Invalid AliDCSMessage type!");
985 return 0;
986 }
987
988 return fEndTime;
989}
990
58bc3020 991//______________________________________________________________________
992TString AliDCSMessage::GetRequestString() const
993{
73abe331 994 // Request.
995 // Returns the request string. (alias or dp)
73abe331 996
997 if (fType != kRequest) {
998 AliError("Invalid AliDCSMessage type!");
999 return TString("");
1000 }
1001
1002 return fRequestString;
1003}
1004
58bc3020 1005//______________________________________________________________________
1006Bool_t AliDCSMessage::AddRequestString(const char* request)
1007{
73abe331 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.
58bc3020 1012
73abe331 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
d477ad88 1024 fRequestStrings.AddLast(new TObjString(request));
73abe331 1025 return kTRUE;
1026}
1027
58bc3020 1028//______________________________________________________________________
1029void AliDCSMessage::ClearRequestStrings()
1030{
73abe331 1031 // MultRequest.
1032 // Clears the request set.
58bc3020 1033
73abe331 1034 fRequestStrings.Delete();
1035}
1036
58bc3020 1037//______________________________________________________________________
1038void AliDCSMessage::GetRequestStrings(TObjArray& result) const
1039{
73abe331 1040 // MultRequest.
1041 // Returns all request strings in this message.
1042 // result: container where the requests are returned. Collection of
1043 // TObjString.
73abe331 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())) {
d477ad88 1055 result.AddLast(new TObjString(*anObjString));
73abe331 1056 }
1057}
1058
58bc3020 1059//______________________________________________________________________
1060UInt_t AliDCSMessage::GetCount() const
1061{
73abe331 1062 // Count.
1063 // Returns the total number of values.
73abe331 1064
1065
1066 if (fType != kCount) {
1067 AliError("Invalid AliDCSMessage type!");
1068 return 0;
1069 }
1070
1071 return fCount;
1072}
1073
58bc3020 1074//______________________________________________________________________
1075AliSimpleValue::Type AliDCSMessage::GetSimpleValueType() const
1076{
73abe331 1077 // ResultSet.
1078 // Returns simple value type (see AliSimpleValue) for the values
1079 // in this ResultSet.
58bc3020 1080
73abe331 1081
1082 if (fType != kResultSet) {
1083 AliError("Invalid AliDCSMessage type!");
1084 return AliSimpleValue::kInvalid;
1085 }
1086
1087 return fSimpleValueType;
1088}
1089
58bc3020 1090//______________________________________________________________________
1091UInt_t AliDCSMessage::GetValueCount() const
1092{
73abe331 1093 // ResultSet.
1094 // Returns the count of values in this ResultSet.
73abe331 1095
1096
1097 if (fType != kResultSet) {
1098 AliError("Invalid AliDCSMessage type!");
1099 return 0;
1100 }
1101
d477ad88 1102 return fValues.GetEntriesFast();
73abe331 1103}
1104
58bc3020 1105//______________________________________________________________________
1106UInt_t AliDCSMessage::GetValues(TObjArray& result) const
1107{
73abe331 1108 // ResultSet.
1109 // Returns the number of values got from the message.
1110 // result: used to return the values. Collection of AliDCSValue.
73abe331 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())) {
d477ad88 1122 result.AddLast(new AliDCSValue(*aValue));
73abe331 1123 }
1124
d477ad88 1125 return fValues.GetEntriesFast();
73abe331 1126}
1127
58bc3020 1128//______________________________________________________________________
1129Bool_t AliDCSMessage::AddValue(const AliDCSValue& value)
1130{
73abe331 1131 // ResultSet.
1132 // Adds value to the ResultSet value list.
1133 // Returns kFALSE in case of error.
1134 // Otherwise returns kTRUE;
73abe331 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
58bc3020 1153//______________________________________________________________________
1154void AliDCSMessage::ClearValues()
1155{
1156// clear values array
1157
73abe331 1158 fValues.Delete();
1159}
1160
58bc3020 1161//______________________________________________________________________
1162AliDCSMessage::ErrorCode AliDCSMessage::GetErrorCode() const
1163{
73abe331 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
58bc3020 1177//______________________________________________________________________
1178TString AliDCSMessage::GetErrorString() const
1179{
73abe331 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
58bc3020 1195//______________________________________________________________________
1196void AliDCSMessage::Print(Option_t* /*option*/) const
1197{
1198// print message
73abe331 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
58bc3020 1337//______________________________________________________________________
1338Bool_t AliDCSMessage::SetRawHeader(const char* header)
1339{
73abe331 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
58bc3020 1366//______________________________________________________________________
1367void AliDCSMessage::DestroyBuffer()
1368{
73abe331 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
58bc3020 1381//______________________________________________________________________
73abe331 1382void AliDCSMessage::PrintBuffer(const char* buffer, UInt_t size,
1383 TString& output)
1384{
58bc3020 1385// print buffer
73abe331 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}