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