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