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