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