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