2 /**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * ALICE Experiment at CERN, All rights reserved. *
6 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 * for The ALICE HLT Project. *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
18 /// @file AliHLTCorruptorComponent.cxx
19 /// @author Artur Szostak <artursz@iafrica.com>
21 /// @brief Implementation of the AliHLTCorruptorComponent class.
23 /// The AliHLTCorruptorComponent is used to generate corruption of various kind
24 /// in the input data blocks it sees. The blocks will be copied to the output
25 /// but with various bit flips and garbage inserted.
26 /// This kind of component is used for testing purposes.
28 #include "AliHLTCorruptorComponent.h"
34 ClassImp(AliHLTCorruptorComponent)
37 AliHLTCorruptorComponent::AliHLTCorruptorComponent() :
39 fBufferMultiplier(2.),
41 fCorruptionInfoList(),
44 // Default constructor.
48 AliHLTCorruptorComponent::~AliHLTCorruptorComponent()
50 // Default destructor.
54 const char* AliHLTCorruptorComponent::GetComponentID()
56 // Returns the component ID.
57 return "CorruptorComponent";
61 void AliHLTCorruptorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
63 // Returns the list of input data types that are handled.
64 list.push_back(kAliHLTAnyDataType);
68 AliHLTComponentDataType AliHLTCorruptorComponent::GetOutputDataType()
70 // Returns kAliHLTMultipleDataType.
71 return kAliHLTMultipleDataType;
75 int AliHLTCorruptorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
77 // Returns the list of output data blocks handled.
78 list.push_back(kAliHLTAnyDataType);
79 return int(list.size());
83 void AliHLTCorruptorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
85 // Returns the buffer size requirements.
87 unsigned long total = 0;
88 for (size_t i = 0; i < fCorruptionInfoList.size(); ++i)
90 AliCorruptionInfo& info = fCorruptionInfoList[i];
91 if (info.fType == kInsert)
93 total += (info.fLastPattern - info.fFirstPattern) / sizeof(AliPattern) * sizeof(AliHLTUInt64_t);
95 else if (info.fType == kInsertRandom)
97 total += info.fMaxBits / 8 + 1;
102 inputMultiplier = fBufferMultiplier;
106 AliHLTComponent* AliHLTCorruptorComponent::Spawn()
108 // Creates a new instance of the component.
109 return new AliHLTCorruptorComponent;
113 bool AliHLTCorruptorComponent::ConvertToPositiveInt(const char* value, AliHLTUInt64_t& num, bool printErrors) const
115 // Converts a string value to a positive integer.
119 unsigned long long tmpnum = strtoull(value, &err, 0);
120 if (err == NULL or *err != '\0')
122 if (printErrors) HLTError("Cannot convert '%s' to a positive integer.", value);
127 if (printErrors) HLTError("The specified value '%s' is out of range.", value);
135 bool AliHLTCorruptorComponent::ConvertToBitPosition(
136 const char* value, AliHLTUInt64_t& pos, bool& relative, bool printErrors
139 // Converts a string value to a bit position.
141 if (strcmp(value, "min") == 0)
143 // Special case where the value is the special symbol "min".
148 if (strcmp(value, "max") == 0)
150 // Special case where the value is the special symbol "max".
151 pos = 0xFFFFFFFFFFFFFFFFull;
156 int valuelength = strlen(value);
157 const char* valstr = value;
159 // Check if the position is relative.
160 if (valuelength >= 3 and value[0] == 'm' and value[1] == 'i' and value[2] == 'n')
162 if (valuelength >= 4 and value[3] == '-')
166 HLTError("Cannot use 'min-' in option '%s' since that would be outside the buffer."
167 " Should use 'min+' instead.",
173 else if (valuelength >= 4 and value[3] == '+')
175 // Value starting with min+ does not need anything special because
176 // min is always == 0. Just adjust the value string pointer to
177 // skip this part of the string.
181 else if (valuelength >= 3 and value[0] == 'm' and value[1] == 'a' and value[2] == 'x')
183 if (valuelength >= 4 and value[3] == '+')
187 HLTError("Cannot use 'max+' in option '%s' since that would be outside the buffer."
188 " Should use 'max-' instead.",
194 else if (valuelength >= 4 and value[3] == '-')
196 // Need to mark the result as a relative value and skip the
197 // first part of the string.
203 // Find the location of ':' if any, to mark the start of the byte and bit strings.
204 int bytestrlen = strlen(valstr);
205 const char* bitstr = valstr + bytestrlen;
206 for (int i = 0; valstr[i] != 0x0; ++i)
208 if (valstr[i] == ':')
211 bitstr = valstr + (i+1);
215 TString bytestr(valstr, bytestrlen);
219 unsigned long long bytenum = strtoull(bytestr.Data(), &err, 0);
220 if (err == NULL or *err != '\0')
224 HLTError("Cannot convert '%s' given in option '%s' to a positive integer.",
225 bytestr.Data(), value
230 if (errno == ERANGE or bytenum > 0x1FFFFFFFFFFFFFFFull)
234 HLTError("The specified byte number '%s' given in option '%s' is out of range."
235 " The value should be in the range [0..%lld].",
236 bytestr.Data(), value, 0x1FFFFFFFFFFFFFFFull
242 unsigned long bitnum = strtoul(bitstr, &err, 0);
243 if (err == NULL or *err != '\0')
247 HLTError("Cannot convert '%s' given in option '%s' to a positive integer.",
253 if (errno == ERANGE or bitnum > 7)
257 HLTError("The specified bit number '%s' given in option '%s' is out of range."
258 " The value should be in the range [0..7].",
264 pos = (bytenum << 3) | (bitnum & 0x7);
269 bool AliHLTCorruptorComponent::ConvertToPercentage(const char* value, double& num, bool printErrors) const
271 // Converts a string value as a percentage to a floating point number in the range [0..1].
274 bool percent = false;
275 if (str.Length() > 0 and str[str.Length()-1] == '%')
278 str[str.Length()-1] = '\0';
282 double tmpnum = strtod(str.Data(), &err);
283 if (err == NULL or *err != '\0')
285 if (printErrors) HLTError("Cannot convert '%s' to a valid floating point value.", value);
288 if (errno == ERANGE or tmpnum < 0. or (tmpnum > 100. and percent) or (tmpnum > 1. and not percent))
292 int range = percent ? 100 : 1;
293 HLTError("The specified value '%s' is outside the range [0..%d]", value, range);
297 num = percent ? tmpnum / 100. : tmpnum;
302 bool AliHLTCorruptorComponent::ConvertToPattern(const char* value, AliPattern& pattern, bool printErrors) const
304 // Coverts a string value into a pattern structure.
306 if (strcmp(value, "removed") == 0)
308 // Special case where the pattern is the special symbol to used remove bits.
309 pattern.fPattern = 0;
311 pattern.fUseRemoved = true;
315 // Find the location of '/' if any, to mark the start of the pattern and width fields.
316 int patstrlen = strlen(value);
317 const char* widthstr = value + patstrlen;
318 for (int i = 0; value[i] != 0x0; ++i)
323 widthstr = value + (i+1);
327 TString patstr(value, patstrlen);
331 AliHLTUInt64_t patnum = AliHLTUInt64_t( strtoull(patstr.Data(), &err, 0) );
332 if (err == NULL or *err != '\0')
336 HLTError("Cannot convert '%s' given in pattern '%s' to a positive integer.",
346 HLTError("The specified pattern '%s' is out of range."
347 "Cannot be bigger than a 64 bit integer.",
353 unsigned long widthnum = 1;
354 if (*widthstr != '\0') // check if widthstr string is not empty
357 widthnum = strtoul(widthstr, &err, 0);
358 if (err == NULL or *err != '\0')
362 HLTError("Cannot convert the width '%s' given in pattern '%s'"
363 " to a positive integer.",
369 if (errno == ERANGE or widthnum < 1 or 64 < widthnum)
373 HLTError("The specified width '%s' given in pattern '%s' is out of range."
374 " The value should be in the range [1..64].",
383 // Find the width of the pattern if not explicitly given.
384 // This is done by finding the most significant set bit.
385 for (int i = 63; i >= 0; --i)
387 if (((patnum >> i) & 0x1) == 0x1)
394 pattern.fPattern = patnum;
395 pattern.fWidth = AliHLTUInt8_t(widthnum);
396 pattern.fUseRemoved = false;
401 bool AliHLTCorruptorComponent::AddBlockTypeId(const char* type)
403 // Sets the block type ID to filter on.
405 if (strlen(type) > (unsigned)kAliHLTComponentDataTypefIDsize)
407 HLTError("The specified block type '%s' must not be longer than %d characters.",
408 type, kAliHLTComponentDataTypefIDsize
412 if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fTypeSet)
414 fBlockIdList[fBlockIdList.size()-1].fType =
415 AliHLTComponentDataTypeInitializer(
417 fBlockIdList[fBlockIdList.size()-1].fType.fOrigin
419 fBlockIdList[fBlockIdList.size()-1].fTypeSet = true;
424 id.fType = AliHLTComponentDataTypeInitializer(type, kAliHLTDataOriginAny);
425 id.fSpec = kAliHLTVoidDataSpec;
427 id.fOriginSet = false;
429 fBlockIdList.push_back(id);
435 bool AliHLTCorruptorComponent::AddBlockOrigin(const char* origin)
437 // Sets the block origin to filter on.
439 if (strlen(origin) > (unsigned)kAliHLTComponentDataTypefOriginSize)
441 HLTError("The specified origin '%s' must not be longer than %d characters.",
442 origin, kAliHLTComponentDataTypefOriginSize
446 if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fOriginSet)
448 fBlockIdList[fBlockIdList.size()-1].fType =
449 AliHLTComponentDataTypeInitializer(
450 fBlockIdList[fBlockIdList.size()-1].fType.fID,
453 fBlockIdList[fBlockIdList.size()-1].fOriginSet = true;
458 id.fType = AliHLTComponentDataTypeInitializer(kAliHLTAnyDataTypeID, origin);
459 id.fSpec = kAliHLTVoidDataSpec;
461 id.fOriginSet = true;
463 fBlockIdList.push_back(id);
469 bool AliHLTCorruptorComponent::AddBlockSpec(const char* spec)
471 // Sets the block specification to filter on.
475 unsigned long long num = strtoull(spec, &err, 0);
476 if (err == NULL or *err != '\0')
478 HLTError("Cannot convert '%s' to a specification number.", spec);
481 if (num > 0xFFFFFFFF or errno == ERANGE)
483 HLTError("The specification number is not an unsigned 32-bit value or out of range.");
486 AliHLTUInt32_t specVal = AliHLTUInt32_t(num);
488 if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fSpecSet)
490 fBlockIdList[fBlockIdList.size()-1].fSpec = specVal;
491 fBlockIdList[fBlockIdList.size()-1].fSpecSet = true;
496 id.fType = AliHLTComponentDataTypeInitializer(kAliHLTAnyDataTypeID, kAliHLTDataOriginAny);
499 id.fOriginSet = false;
501 fBlockIdList.push_back(id);
508 void AliHLTCorruptorComponent::AddCorruptionCommand(
509 AliCorruptionType type,
510 AliHLTUInt64_t minrange,
511 AliHLTUInt64_t maxrange,
512 AliHLTUInt64_t alignment,
513 bool minRangeRelative,
514 bool maxRangeRelative,
517 AliHLTUInt64_t minerrors,
518 AliHLTUInt64_t maxerrors,
519 AliHLTUInt64_t burstlength,
520 AliHLTUInt64_t burstcount,
521 AliHLTUInt64_t minbits,
522 AliHLTUInt64_t maxbits,
527 // Adds a new entry into the corruptions list to apply.
529 AliCorruptionInfo info;
530 memset(&info, 0x0, sizeof(info));
532 info.fMinRange = minrange;
533 info.fMaxRange = maxrange;
534 info.fAlignment = alignment;
535 info.fMinRangeRelative = minRangeRelative;
536 info.fMaxRangeRelative = maxRangeRelative;
537 info.fUseRate = userate;
544 info.fMinErrors = minerrors;
545 info.fMaxErrors = maxerrors;
550 info.fBurstErrorLength = burstlength;
551 info.fBurstErrorCount = burstcount;
554 info.fFirstPattern = firstpattern;
555 info.fLastPattern = lastpattern;
558 info.fMinBits = minbits;
559 info.fMaxBits = maxbits;
562 info.fFirstPattern = firstpattern;
563 info.fLastPattern = lastpattern;
566 info.fMinBits = minbits;
567 info.fMaxBits = maxbits;
570 info.fMinBits = minbits;
571 info.fMaxBits = maxbits;
577 fCorruptionInfoList.push_back(info);
581 int AliHLTCorruptorComponent::CheckForCommandWithPatterns(
582 const char* name, AliCorruptionType type,
583 int& i, int argc, const char** argv,
584 AliHLTUInt64_t minrange,
585 AliHLTUInt64_t maxrange,
586 AliHLTUInt64_t alignment,
587 bool minRangeRelative,
588 bool maxRangeRelative,
591 AliHLTUInt64_t minerrors,
592 AliHLTUInt64_t maxerrors
595 // Check for a particular command line option that has pattern parameters.
597 AliPattern pattern = {0, 0, false};
598 if (strcmp(argv[i], name) == 0)
600 // Check for at least 1 pattern.
603 HLTError("At least one pattern must be specified for %s.", name);
606 if (not ConvertToPattern(argv[i+1], pattern)) return -EPROTO;
607 // Mark the pattern found as the first pattern and add it.
608 size_t firstpattern = fPatterns.size();
609 fPatterns.push_back(pattern);
611 // Now check for more patterns. Do not print any error messages,
612 // since here we assume that if the string is not a pattern string
613 // then it might be another command.
614 while (i+1 < argc and ConvertToPattern(argv[i+1], pattern, false))
616 fPatterns.push_back(pattern);
619 // Mark the last pattern and add corruption command.
620 size_t lastpattern = fPatterns.size();
621 AddCorruptionCommand(
622 type, minrange, maxrange, alignment,
623 minRangeRelative, maxRangeRelative, userate,
624 errorrate, minerrors, maxerrors, 0, 0, 0, 0,
625 firstpattern, lastpattern
633 int AliHLTCorruptorComponent::CheckForCommandWithMinMax(
634 const char* name, AliCorruptionType type,
635 int& i, int argc, const char** argv,
636 AliHLTUInt64_t minrange,
637 AliHLTUInt64_t maxrange,
638 AliHLTUInt64_t alignment,
639 bool minRangeRelative,
640 bool maxRangeRelative,
643 AliHLTUInt64_t minerrors,
644 AliHLTUInt64_t maxerrors
647 // Check for a particular command line option that has 2 (min/max) parameters.
649 if (strcmp(argv[i], name) == 0)
653 HLTError("Minimum number of bits to replace not specified for %s.", name);
656 AliHLTUInt64_t minbits = 0;
657 if (strcmp(argv[i+1], "min") == 0)
661 else if (strcmp(argv[i+1], "max") == 0)
663 minbits = 0xFFFFFFFFFFFFFFFFull;
667 if (not ConvertToPositiveInt(argv[i+1], minbits)) return -EPROTO;
671 HLTError("Maximum number of bits to replace not specified for %s.", name);
674 AliHLTUInt64_t maxbits = 0;
675 if (strcmp(argv[i+2], "min") == 0)
679 else if (strcmp(argv[i+2], "max") == 0)
681 maxbits = 0xFFFFFFFFFFFFFFFFull;
685 if (not ConvertToPositiveInt(argv[i+2], maxbits)) return -EPROTO;
687 if (maxbits < minbits)
689 HLTError("Maximum value (%s) is smaller than minimum (%s).", argv[i+2], argv[i+1]);
692 AddCorruptionCommand(
693 type, minrange, maxrange, alignment,
694 minRangeRelative, maxRangeRelative, userate,
695 errorrate, minerrors, maxerrors, 0, 0, minbits, maxbits
704 Int_t AliHLTCorruptorComponent::DoInit(int argc, const char** argv)
706 // Initialises the corruptor component from the command line.
709 fBlockIdList.clear();
710 fCorruptionInfoList.clear();
712 AliHLTUInt64_t minpos = 0;
713 AliHLTUInt64_t maxpos = 0xFFFFFFFFFFFFFFFFull;
714 AliHLTUInt64_t alignment = 1;
715 bool minposrel = false;
716 bool maxposrel = false;
717 bool useErrorRate = true;
718 double errorrate = 0.001;
719 AliHLTUInt64_t minerrors = 1;
720 AliHLTUInt64_t maxerrors = 1;
721 bool seedSet = false;
724 for (int i = 0; i < argc; ++i)
726 if (strcmp(argv[i], "-seed") == 0)
730 HLTError("The option \"-seed\" has already been used with"
731 " the value %u. Can only use this option once",
738 HLTError("The random number generator seed was not specified for -seed.");
741 AliHLTUInt64_t tmpseed = 0;
742 if (not ConvertToPositiveInt(argv[i+1], tmpseed)) return -EPROTO;
743 if (tmpseed > 0xFFFFFFFF)
745 HLTError("The random number generator seed value cannot be larger than %u.", 0xFFFFFFFF);
748 seed = UInt_t(tmpseed);
754 if (strcmp(argv[i], "-datatype") == 0)
758 HLTError("The data type identifier was not specified for -datatype.");
761 if (not AddBlockTypeId(argv[i+1])) return -EPROTO;
764 HLTError("The origin identifier was not specified for -datatype.");
767 if (not AddBlockOrigin(argv[i+2])) return -EPROTO;
772 if (strcmp(argv[i], "-origin") == 0)
776 HLTError("The origin identifier was not specified for -origin.");
779 if (not AddBlockOrigin(argv[i+1])) return -EPROTO;
784 if (strcmp(argv[i], "-typeid") == 0)
788 HLTError("The data type identifier was not specified for -typeid.");
791 if (not AddBlockTypeId(argv[i+1])) return -EPROTO;
796 if (strcmp(argv[i], "-dataspec") == 0)
800 HLTError("The data specification was not specified for -dataspec.");
803 if (not AddBlockSpec(argv[i+1])) return -EPROTO;
808 if (strcmp(argv[i], "-range") == 0)
812 HLTError("Minimum byte/bit position not given for -range.");
815 if (not ConvertToBitPosition(argv[i+1], minpos, minposrel)) return -EPROTO;
818 HLTError("Maximum byte/bit position not given for -range.");
821 if (not ConvertToBitPosition(argv[i+2], maxpos, maxposrel)) return -EPROTO;
822 if (minposrel == maxposrel and maxpos < minpos)
824 HLTError("Maximum position (%s) is smaller than minimum position (%s).",
833 if (strcmp(argv[i], "-alignment") == 0)
837 HLTError("The alignment value was not specified for -errorrate.");
840 if (not ConvertToPositiveInt(argv[i+1], alignment)) return -EPROTO;
843 HLTError("The alignment value cannot be zero.");
850 if (strcmp(argv[i], "-errorrate") == 0)
854 HLTError("The current error rate to use was not specified for -errorrate.");
857 if (not ConvertToPercentage(argv[i+1], errorrate)) return -EPROTO;
863 if (strcmp(argv[i], "-errorcount") == 0)
867 HLTError("Minimum number of errors not specified for -errorcount.");
870 if (not ConvertToPositiveInt(argv[i+1], minerrors)) return -EPROTO;
873 HLTError("Maximum number of errors not specified for -errorcount.");
876 if (not ConvertToPositiveInt(argv[i+2], maxerrors)) return -EPROTO;
877 if (maxerrors < minerrors)
879 HLTError("Maximum error count (%s) is smaller than minimum (%s).",
884 useErrorRate = false;
889 if (strcmp(argv[i], "-singleflips") == 0)
891 AddCorruptionCommand(
892 kSingleFlips, minpos, maxpos, alignment,
893 minposrel, maxposrel, useErrorRate,
894 errorrate, minerrors, maxerrors
899 if (strcmp(argv[i], "-bursterrors") == 0)
903 HLTError("Maximum burst error length not specified for -bursterrors.");
906 AliHLTUInt64_t burstLength;
907 if (not ConvertToPositiveInt(argv[i+1], burstLength)) return -EPROTO;
910 HLTError("Number of bit flips in a burst error not specified for -bursterrors.");
913 AliHLTUInt64_t burstCount;
914 if (not ConvertToPositiveInt(argv[i+2], burstCount)) return -EPROTO;
915 AddCorruptionCommand(
916 kBurstErrors, minpos, maxpos, alignment,
917 minposrel, maxposrel, useErrorRate, errorrate,
918 minerrors, maxerrors, burstLength, burstCount
924 result = CheckForCommandWithPatterns("-replace", kReplace,
925 i, argc, argv, minpos, maxpos, alignment,
926 minposrel, maxposrel, useErrorRate,
927 errorrate, minerrors, maxerrors
929 if (result == 1) continue;
930 if (result < 0) return result;
932 result = CheckForCommandWithPatterns("-insert", kInsert,
933 i, argc, argv, minpos, maxpos, alignment,
934 minposrel, maxposrel, useErrorRate,
935 errorrate, minerrors, maxerrors
937 if (result == 1) continue;
938 if (result < 0) return result;
940 result = CheckForCommandWithMinMax("-replace-random", kReplaceRandom,
941 i, argc, argv, minpos, maxpos, alignment,
942 minposrel, maxposrel, useErrorRate,
943 errorrate, minerrors, maxerrors
945 if (result == 1) continue;
946 if (result < 0) return result;
948 result = CheckForCommandWithMinMax("-insert-random", kInsertRandom,
949 i, argc, argv, minpos, maxpos, alignment,
950 minposrel, maxposrel, useErrorRate,
951 errorrate, minerrors, maxerrors
953 if (result == 1) continue;
954 if (result < 0) return result;
956 result = CheckForCommandWithMinMax("-remove", kRemove,
957 i, argc, argv, minpos, maxpos, alignment,
958 minposrel, maxposrel, useErrorRate,
959 errorrate, minerrors, maxerrors
961 if (result == 1) continue;
962 if (result < 0) return result;
964 HLTError("Unknown option '%s'.", argv[i]);
968 // If no errors were specified then set to 1% single bit corruption.
969 if (fCorruptionInfoList.size() == 0)
972 maxpos = 0xFFFFFFFFFFFFFFFFull;
976 AddCorruptionCommand(
977 kSingleFlips, minpos, maxpos, alignment, useErrorRate, errorrate
981 gRandom->SetSeed(0); // Use current time.
983 HLTInfo("Starting Corruptor Component.");
988 Int_t AliHLTCorruptorComponent::DoDeinit()
990 // Cleans up the corruptor component.
991 fBlockIdList.clear();
996 bool AliHLTCorruptorComponent::ShouldProcess(const AliHLTComponentBlockData* block) const
998 if (fBlockIdList.size() == 0) return true;
999 for (size_t i = 0; i < fBlockIdList.size(); ++i)
1001 AliBlockId id = fBlockIdList[i];
1002 AliHLTComponentDataType type = AliHLTComponentDataTypeInitializer(
1003 id.fTypeSet ? id.fType : kAliHLTAnyDataType,
1004 id.fOriginSet ? id.fType.fOrigin : kAliHLTDataOriginAny
1006 if (type != block->fDataType) continue;
1007 if (id.fSpecSet and id.fSpec != block->fSpecification) continue;
1014 void AliHLTCorruptorComponent::ApplyCorruption(std::vector<bool>& bits) const
1016 // Applies corruption to the bit string.
1018 std::vector<bool> removed;
1019 std::vector<bool> pattern;
1020 for (size_t i = 0; i < fCorruptionInfoList.size(); ++i)
1022 AliCorruptionInfo info = fCorruptionInfoList[i];
1024 const char* cmdtype = NULL;
1027 case kSingleFlips: cmdtype = "kSingleFlips"; break;
1028 case kBurstErrors: cmdtype = "kBurstErrors"; break;
1029 case kReplace: cmdtype = "kReplace"; break;
1030 case kReplaceRandom: cmdtype = "kReplaceRandom"; break;
1031 case kInsert: cmdtype = "kInsert"; break;
1032 case kInsertRandom: cmdtype = "kInsertRandom"; break;
1033 case kRemove: cmdtype = "kRemove"; break;
1034 default: cmdtype = "UNKNOWN"; break;
1036 HLTDebug("Processing corruption command %u of %u, fType = %s,"
1037 " fMinRange = %llu, fMaxRange = %llu, fAlignment = %llu,"
1038 " fUseRate = %s, fRate = %.16f, fMinErrors = %llu, fMaxErrors = %llu"
1039 " fBurstErrorLength = %llu, fBurstErrorCount = %llu,"
1040 " fMinBits = %llu, fMaxBits = %llu, fFirstPattern = %llu, fLastPattern = %llu.",
1041 i, fCorruptionInfoList.size(), cmdtype,
1042 info.fMinRange, info.fMaxRange, info.fAlignment,
1043 (info.fUseRate ? "true" : "false"), info.fRate,
1044 info.fMinErrors, info.fMaxErrors,
1045 info.fBurstErrorLength, info.fBurstErrorCount,
1046 info.fMinBits, info.fMaxBits,
1047 AliHLTUInt64_t(info.fFirstPattern), AliHLTUInt64_t(info.fLastPattern)
1051 // Calculate the range (and adjust for buffer size)
1052 AliHLTUInt64_t minrange = info.fMinRangeRelative ? bits.size() - info.fMinRange : info.fMinRange;
1053 AliHLTUInt64_t maxrange = info.fMaxRangeRelative ? bits.size() - info.fMaxRange : info.fMaxRange;
1054 if (minrange == 0xFFFFFFFFFFFFFFFFull)
1056 if (info.fType == kInsert or info.fType == kInsertRandom or bits.size() == 0)
1058 minrange = bits.size();
1062 minrange = bits.size() - 1;
1065 if (maxrange == 0xFFFFFFFFFFFFFFFFull)
1067 if (info.fType == kInsert or info.fType == kInsertRandom or bits.size() == 0)
1069 maxrange = bits.size();
1073 maxrange = bits.size() - 1;
1076 if (maxrange < minrange) maxrange = minrange;
1078 // Select the correct number of errors to generate.
1079 AliHLTUInt64_t errorcount = 0;
1082 errorcount = AliHLTUInt64_t(bits.size() * info.fRate);
1086 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1087 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1088 errorcount = rnum % (info.fMaxErrors - info.fMinErrors + 1) + info.fMinErrors;
1091 // Build the pattern bits for a replace or insert command.
1092 if (info.fType == kReplace or info.fType == kInsert)
1095 for (size_t k = info.fFirstPattern; k < info.fLastPattern; ++k)
1097 const AliPattern& pat = fPatterns[k];
1098 if (pat.fUseRemoved)
1100 pattern.insert(pattern.end(), removed.begin(), removed.end());
1104 for (AliHLTUInt8_t j = 0; j < pat.fWidth; ++j)
1106 pattern.push_back( ((pat.fPattern >> j) & 0x1) == 0x1 );
1112 // Find a random value for the number of bits to use for the corresponding
1113 // replace-random, insert-random and remove commands.
1114 AliHLTUInt64_t bitcount = 0;
1115 if (info.fType == kReplaceRandom or info.fType == kInsertRandom or info.fType == kRemove)
1117 AliHLTUInt64_t minbits = info.fMinBits;
1118 AliHLTUInt64_t maxbits = info.fMaxBits;
1119 if (minbits == 0xFFFFFFFFFFFFFFFFull) minbits = bits.size();
1120 if (maxbits == 0xFFFFFFFFFFFFFFFFull) maxbits = bits.size();
1121 if (maxbits < minbits) maxbits = minbits;
1122 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1123 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1124 bitcount = rnum % (maxbits - minbits + 1) + minbits;
1130 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1132 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1133 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1134 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1135 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1136 if (not (pos < bits.size())) continue;
1137 bits[pos] = not bits[pos];
1141 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1143 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1144 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1145 AliHLTUInt64_t firstpos = rnum % (maxrange - minrange + 1) + minrange;
1146 firstpos = ((firstpos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1147 AliHLTUInt64_t lastpos = firstpos + info.fBurstErrorLength;
1148 if (lastpos < firstpos)
1150 HLTWarning("Burst error length %llu is too large and caused an overflow.",
1151 info.fBurstErrorLength
1155 if (lastpos == firstpos) continue;
1156 for (AliHLTUInt64_t j = 0; j < info.fBurstErrorCount; ++j)
1158 rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1159 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1160 AliHLTUInt64_t pos = rnum % (lastpos - firstpos) + firstpos;
1161 if (not (pos < bits.size())) continue;
1162 bits[pos] = not bits[pos];
1167 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1169 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1170 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1171 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1172 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1173 for (UInt_t j = pos; j < pos + pattern.size() and j < bits.size(); ++j)
1175 bits[j] = pattern[j-pos];
1179 case kReplaceRandom:
1180 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1182 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1183 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1184 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1185 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1186 for (UInt_t j = pos; j < pos + bitcount and j < bits.size(); ++j)
1188 bits[j] = gRandom->Integer(2) == 1;
1193 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1195 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1196 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1197 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1198 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1199 if (not (pos <= bits.size())) continue;
1200 bits.insert(bits.begin() + pos, pattern.begin(), pattern.end());
1204 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1206 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1207 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1208 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1209 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1210 if (not (pos <= bits.size())) continue;
1211 std::vector<bool> newbits;
1212 for (UInt_t j = 0; j < bitcount; ++j)
1214 newbits.push_back(gRandom->Integer(2) == 1);
1216 bits.insert(bits.begin() + pos, newbits.begin(), newbits.end());
1221 for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
1223 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
1224 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
1225 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
1226 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
1227 if (not (pos < bits.size())) continue;
1228 AliHLTUInt64_t end = pos + bitcount;
1229 if (end > bits.size()) end = bits.size();
1230 removed.insert(removed.begin(), bits.begin() + pos, bits.begin() + end);
1231 bits.erase(bits.begin() + pos, bits.begin() + end);
1235 HLTWarning("Received an unknown corruption type. There must be a program bug!");
1242 int AliHLTCorruptorComponent::DoEvent(
1243 const AliHLTComponentEventData& evtData,
1244 const AliHLTComponentBlockData* blocks,
1245 AliHLTComponentTriggerData& /*trigData*/,
1246 AliHLTUInt8_t* outputPtr,
1247 AliHLTUInt32_t& size,
1248 AliHLTComponentBlockDataList& outputBlocks
1251 // Processes the input data blocks.
1252 // The data blocks will be copied to the output and corrupted in some way.
1254 AliHLTUInt8_t* output = outputPtr;
1255 AliHLTUInt32_t totalSize = 0;
1257 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
1259 HLTDebug("Processing block %d, of type '%s' with specification 0x%8.8X.",
1260 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
1262 if (not ShouldProcess(blocks + n))
1268 // Convert data block buffer to a bit string.
1269 std::vector<bool> bits;
1270 const AliHLTUInt8_t* buffer = reinterpret_cast<const AliHLTUInt8_t*>(blocks[n].fPtr);
1271 for (AliHLTUInt32_t i = 0; i < blocks[n].fSize; ++i)
1273 for (AliHLTUInt8_t j = 0; j < 8; ++j)
1275 bits.push_back( ((buffer[i] >> j) & 0x1) == 0x1 );
1279 ApplyCorruption(bits);
1281 // Convert bit string back to a data buffer.
1282 if (bits.size() > 0xFFFFFFFFull * 8)
1284 HLTWarning("The internal bit string representation is too large for the output buffer. Skipping block.");
1287 AliHLTUInt32_t blockSize = bits.size() / 8;
1288 if (bits.size() % 8 > 0) ++blockSize;
1290 if (totalSize + blockSize > size)
1292 HLTError("Out of buffer space. Require %d bytes but have %d bytes of buffer space.",
1293 totalSize + blockSize, size
1295 fBufferMultiplier *= 8;
1299 memset(output, 0x0, blockSize);
1300 for (size_t i = 0; i < bits.size(); ++i)
1302 AliHLTUInt32_t byte = i / 8;
1303 AliHLTUInt32_t bit = i % 8;
1304 output[byte] = output[byte] | (bits[i] << bit);
1307 AliHLTComponentBlockData bd;
1309 bd.fPtr = outputPtr;
1310 bd.fOffset = totalSize;
1311 bd.fSize = blockSize;
1312 bd.fDataType = blocks[n].fDataType;
1313 bd.fSpecification = blocks[n].fSpecification;
1314 outputBlocks.push_back(bd);
1316 totalSize += blockSize;
1317 output += blockSize;
1320 size = totalSize; // Set the correct output size.