LCOV - code coverage report
Current view: top level - HLT/BASE/util - AliHLTCorruptorComponent.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 655 1.7 %
Date: 2016-06-14 17:26:59 Functions: 7 27 25.9 %

          Line data    Source code
       1             : // $Id$
       2             : /**************************************************************************
       3             :  * This file is property of and copyright by the ALICE HLT Project        *
       4             :  * ALICE Experiment at CERN, All rights reserved.                         *
       5             :  *                                                                        *
       6             :  * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
       7             :  *                  for The ALICE HLT Project.                            *
       8             :  *                                                                        *
       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             :  **************************************************************************/
      17             : 
      18             : /// @file   AliHLTCorruptorComponent.cxx
      19             : /// @author Artur Szostak <artursz@iafrica.com>
      20             : /// @date   5 Aug 2010
      21             : /// @brief  Implementation of the AliHLTCorruptorComponent class.
      22             : ///
      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.
      27             : 
      28             : #include "AliHLTCorruptorComponent.h"
      29             : #include "TRandom3.h"
      30             : #include <cstdlib>
      31             : #include <cstring>
      32             : #include <cerrno>
      33             : 
      34           8 : ClassImp(AliHLTCorruptorComponent)
      35             : 
      36             : 
      37             : AliHLTCorruptorComponent::AliHLTCorruptorComponent() :
      38           3 :         AliHLTProcessor(),
      39           3 :         fBufferMultiplier(2.),
      40           3 :         fBlockIdList(),
      41           3 :         fCorruptionInfoList(),
      42           3 :         fPatterns()
      43          15 : {
      44             :         // Default constructor.
      45           6 : }
      46             : 
      47             : 
      48             : AliHLTCorruptorComponent::~AliHLTCorruptorComponent()
      49          18 : {
      50             :         // Default destructor.
      51           9 : }
      52             : 
      53             : 
      54             : const char* AliHLTCorruptorComponent::GetComponentID()
      55             : {
      56             :         // Returns the component ID.
      57         582 :         return "CorruptorComponent";
      58             : }
      59             : 
      60             : 
      61             : void AliHLTCorruptorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
      62             : {
      63             :         // Returns the list of input data types that are handled.
      64           0 :         list.push_back(kAliHLTAnyDataType);
      65           0 : }
      66             : 
      67             : 
      68             : AliHLTComponentDataType AliHLTCorruptorComponent::GetOutputDataType()
      69             : {
      70             :         // Returns kAliHLTMultipleDataType.
      71           0 :         return kAliHLTMultipleDataType;
      72             : }
      73             : 
      74             : 
      75             : int AliHLTCorruptorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
      76             : {
      77             :         // Returns the list of output data blocks handled.
      78           0 :         list.push_back(kAliHLTAnyDataType);
      79           0 :         return int(list.size());
      80             : }
      81             : 
      82             : 
      83             : void AliHLTCorruptorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
      84             : {
      85             :         // Returns the buffer size requirements.
      86             :         
      87             :         unsigned long total = 0;
      88           0 :         for (size_t i = 0; i < fCorruptionInfoList.size(); ++i)
      89             :         {
      90           0 :                 AliCorruptionInfo& info = fCorruptionInfoList[i];
      91           0 :                 if (info.fType == kInsert)
      92             :                 {
      93           0 :                         total += (info.fLastPattern - info.fFirstPattern) / sizeof(AliPattern) * sizeof(AliHLTUInt64_t);
      94           0 :                 }
      95           0 :                 else if (info.fType == kInsertRandom)
      96             :                 {
      97           0 :                         total += info.fMaxBits / 8 + 1;
      98           0 :                 }
      99             :         }
     100             :         
     101           0 :         constBase = total;
     102           0 :         inputMultiplier = fBufferMultiplier;
     103           0 : }
     104             : 
     105             : 
     106             : AliHLTComponent* AliHLTCorruptorComponent::Spawn()
     107             : {
     108             :         // Creates a new instance of the component.
     109           0 :         return new AliHLTCorruptorComponent;
     110           0 : }
     111             : 
     112             : 
     113             : bool AliHLTCorruptorComponent::ConvertToPositiveInt(const char* value, AliHLTUInt64_t& num, bool printErrors) const
     114             : {
     115             :         // Converts a string value to a positive integer.
     116             :         
     117           0 :         char* err = NULL;
     118           0 :         errno = 0;
     119           0 :         unsigned long long tmpnum = strtoull(value, &err, 0);
     120           0 :         if (err == NULL or *err != '\0')
     121             :         {
     122           0 :                 if (printErrors) HLTError("Cannot convert '%s' to a positive integer.", value);
     123           0 :                 return false;
     124             :         }
     125           0 :         if (errno == ERANGE)
     126             :         {
     127           0 :                 if (printErrors) HLTError("The specified value '%s' is out of range.", value);
     128           0 :                 return false;
     129             :         }
     130           0 :         num = tmpnum;
     131           0 :         return true;
     132           0 : }
     133             : 
     134             : 
     135             : bool AliHLTCorruptorComponent::ConvertToBitPosition(
     136             :                 const char* value, AliHLTUInt64_t& pos, bool& relative, bool printErrors
     137             :         ) const
     138             : {
     139             :         // Converts a string value to a bit position.
     140             :         
     141           0 :         if (strcmp(value, "min") == 0)
     142             :         {
     143             :                 // Special case where the value is the special symbol "min".
     144           0 :                 pos = 0;
     145           0 :                 relative = false;
     146           0 :                 return true;
     147             :         }
     148           0 :         if (strcmp(value, "max") == 0)
     149             :         {
     150             :                 // Special case where the value is the special symbol "max".
     151           0 :                 pos = 0xFFFFFFFFFFFFFFFFull;
     152           0 :                 relative = false;
     153           0 :                 return true;
     154             :         }
     155             :         
     156           0 :         int valuelength = strlen(value);
     157             :         const char* valstr = value;
     158           0 :         relative = false;
     159             :         // Check if the position is relative.
     160           0 :         if (valuelength >= 3 and value[0] == 'm' and value[1] == 'i' and value[2] == 'n')
     161             :         {
     162           0 :                 if (valuelength >= 4 and value[3] == '-')
     163             :                 {
     164           0 :                         if (printErrors)
     165             :                         {
     166           0 :                                 HLTError("Cannot use 'min-' in option '%s' since that would be outside the buffer."
     167             :                                         " Should use 'min+' instead.",
     168             :                                         value
     169             :                                 );
     170           0 :                                 return false;
     171             :                         }
     172             :                 }
     173           0 :                 else if (valuelength >= 4 and value[3] == '+')
     174             :                 {
     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.
     178           0 :                         valstr = value + 4;
     179           0 :                 }
     180             :         }
     181           0 :         else if (valuelength >= 3 and value[0] == 'm' and value[1] == 'a' and value[2] == 'x')
     182             :         {
     183           0 :                 if (valuelength >= 4 and value[3] == '+')
     184             :                 {
     185           0 :                         if (printErrors)
     186             :                         {
     187           0 :                                 HLTError("Cannot use 'max+' in option '%s' since that would be outside the buffer."
     188             :                                         " Should use 'max-' instead.",
     189             :                                         value
     190             :                                 );
     191           0 :                                 return false;
     192             :                         }
     193             :                 }
     194           0 :                 else if (valuelength >= 4 and value[3] == '-')
     195             :                 {
     196             :                         // Need to mark the result as a relative value and skip the
     197             :                         // first part of the string.
     198           0 :                         relative = true;
     199           0 :                         valstr = value + 4;
     200           0 :                 }
     201             :         }
     202             :         
     203             :         // Find the location of ':' if any, to mark the start of the byte and bit strings.
     204           0 :         int bytestrlen = strlen(valstr);
     205           0 :         const char* bitstr = valstr + bytestrlen;
     206           0 :         for (int i = 0; valstr[i] != 0x0; ++i)
     207             :         {
     208           0 :                 if (valstr[i] == ':')
     209             :                 {
     210             :                         bytestrlen = i;
     211           0 :                         bitstr = valstr + (i+1);
     212           0 :                         break;
     213             :                 }
     214             :         }
     215           0 :         TString bytestr(valstr, bytestrlen);
     216             :         
     217           0 :         char* err = NULL;
     218           0 :         errno = 0;
     219           0 :         unsigned long long bytenum = strtoull(bytestr.Data(), &err, 0);
     220           0 :         if (err == NULL or *err != '\0')
     221             :         {
     222           0 :                 if (printErrors)
     223             :                 {
     224           0 :                         HLTError("Cannot convert '%s' given in option '%s' to a positive integer.",
     225             :                                 bytestr.Data(), value
     226             :                         );
     227             :                 }
     228           0 :                 return false;
     229             :         }
     230           0 :         if (errno == ERANGE or bytenum > 0x1FFFFFFFFFFFFFFFull)
     231             :         {
     232           0 :                 if (printErrors)
     233             :                 {
     234           0 :                         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
     237             :                         );
     238             :                 }
     239           0 :                 return false;
     240             :         }
     241           0 :         err = NULL;
     242           0 :         unsigned long bitnum = strtoul(bitstr, &err, 0);
     243           0 :         if (err == NULL or *err != '\0')
     244             :         {
     245           0 :                 if (printErrors)
     246             :                 {
     247           0 :                         HLTError("Cannot convert '%s' given in option '%s' to a positive integer.",
     248             :                                 bitstr, value
     249             :                         );
     250             :                 }
     251           0 :                 return false;
     252             :         }
     253           0 :         if (errno == ERANGE or bitnum > 7)
     254             :         {
     255           0 :                 if (printErrors)
     256             :                 {
     257           0 :                         HLTError("The specified bit number '%s' given in option '%s' is out of range."
     258             :                                 " The value should be in the range [0..7].",
     259             :                                 bitstr, value
     260             :                         );
     261             :                 }
     262           0 :                 return false;
     263             :         }
     264           0 :         pos = (bytenum << 3) | (bitnum & 0x7);
     265           0 :         return true;
     266           0 : }
     267             : 
     268             : 
     269             : bool AliHLTCorruptorComponent::ConvertToPercentage(const char* value, double& num, bool printErrors) const
     270             : {
     271             :         // Converts a string value as a percentage to a floating point number in the range [0..1].
     272             :         
     273           0 :         TString str = value;
     274             :         bool percent = false;
     275           0 :         if (str.Length() > 0 and str[str.Length()-1] == '%')
     276             :         {
     277             :                 percent = true;
     278           0 :                 str[str.Length()-1] = '\0';
     279           0 :         }
     280           0 :         char* err = NULL;
     281           0 :         errno = 0;
     282           0 :         double tmpnum = strtod(str.Data(), &err);
     283           0 :         if (err == NULL or *err != '\0')
     284             :         {
     285           0 :                 if (printErrors) HLTError("Cannot convert '%s' to a valid floating point value.", value);
     286           0 :                 return false;
     287             :         }
     288           0 :         if (errno == ERANGE or tmpnum < 0. or (tmpnum > 100. and percent) or (tmpnum > 1. and not percent))
     289             :         {
     290           0 :                 if (printErrors)
     291             :                 {
     292           0 :                         int range = percent ? 100 : 1;
     293           0 :                         HLTError("The specified value '%s' is outside the range [0..%d]", value, range);
     294           0 :                 }
     295           0 :                 return false;
     296             :         }
     297           0 :         num = percent ? tmpnum / 100. : tmpnum;
     298           0 :         return true;
     299           0 : }
     300             : 
     301             : 
     302             : bool AliHLTCorruptorComponent::ConvertToPattern(const char* value, AliPattern& pattern, bool printErrors) const
     303             : {
     304             :         // Coverts a string value into a pattern structure.
     305             :         
     306           0 :         if (strcmp(value, "removed") == 0)
     307             :         {
     308             :                 // Special case where the pattern is the special symbol to used remove bits.
     309           0 :                 pattern.fPattern = 0;
     310           0 :                 pattern.fWidth = 0;
     311           0 :                 pattern.fUseRemoved = true;
     312           0 :                 return true;
     313             :         }
     314             :         
     315             :         // Find the location of '/' if any, to mark the start of the pattern and width fields.
     316           0 :         int patstrlen = strlen(value);
     317           0 :         const char* widthstr = value + patstrlen;
     318           0 :         for (int i = 0; value[i] != 0x0; ++i)
     319             :         {
     320           0 :                 if (value[i] == '/')
     321             :                 {
     322             :                         patstrlen = i;
     323           0 :                         widthstr = value + (i+1);
     324           0 :                         break;
     325             :                 }
     326             :         }
     327           0 :         TString patstr(value, patstrlen);
     328             :         
     329           0 :         char* err = NULL;
     330           0 :         errno = 0;
     331           0 :         AliHLTUInt64_t patnum = AliHLTUInt64_t( strtoull(patstr.Data(), &err, 0) );
     332           0 :         if (err == NULL or *err != '\0')
     333             :         {
     334           0 :                 if (printErrors)
     335             :                 {
     336           0 :                         HLTError("Cannot convert '%s' given in pattern '%s' to a positive integer.",
     337             :                                 patstr.Data(), value
     338             :                         );
     339             :                 }
     340           0 :                 return false;
     341             :         }
     342           0 :         if (errno == ERANGE)
     343             :         {
     344           0 :                 if (printErrors)
     345             :                 {
     346           0 :                         HLTError("The specified pattern '%s' is out of range."
     347             :                                 "Cannot be bigger than a 64 bit integer.",
     348             :                                  value
     349             :                         );
     350             :                 }
     351           0 :                 return false;
     352             :         }
     353             :         unsigned long widthnum = 1;
     354           0 :         if (*widthstr != '\0')  // check if widthstr string is not empty
     355             :         {
     356           0 :                 err = NULL;
     357           0 :                 widthnum = strtoul(widthstr, &err, 0);
     358           0 :                 if (err == NULL or *err != '\0')
     359             :                 {
     360           0 :                         if (printErrors)
     361             :                         {
     362           0 :                                 HLTError("Cannot convert the width '%s' given in pattern '%s'"
     363             :                                         " to a positive integer.",
     364             :                                         widthstr, value
     365             :                                 );
     366             :                         }
     367           0 :                         return false;
     368             :                 }
     369           0 :                 if (errno == ERANGE or widthnum < 1 or 64 < widthnum)
     370             :                 {
     371           0 :                         if (printErrors)
     372             :                         {
     373           0 :                                 HLTError("The specified width '%s' given in pattern '%s' is out of range."
     374             :                                         " The value should be in the range [1..64].",
     375             :                                         widthstr, value
     376             :                                 );
     377             :                         }
     378           0 :                         return false;
     379             :                 }
     380             :         }
     381             :         else
     382             :         {
     383             :                 // Find the width of the pattern if not explicitly given.
     384             :                 // This is done by finding the most significant set bit.
     385           0 :                 for (int i = 63; i >= 0; --i)
     386             :                 {
     387           0 :                         if (((patnum >> i) & 0x1) == 0x1)
     388             :                         {
     389           0 :                                 widthnum = i+1;
     390           0 :                                 break;
     391             :                         }
     392             :                 }
     393             :         }
     394           0 :         pattern.fPattern = patnum;
     395           0 :         pattern.fWidth = AliHLTUInt8_t(widthnum);
     396           0 :         pattern.fUseRemoved = false;
     397           0 :         return true;
     398           0 : }
     399             : 
     400             : 
     401             : bool AliHLTCorruptorComponent::AddBlockTypeId(const char* type)
     402             : {
     403             :         // Sets the block type ID to filter on.
     404             :         
     405           0 :         if (strlen(type) > (unsigned)kAliHLTComponentDataTypefIDsize)
     406             :         {
     407           0 :                 HLTError("The specified block type '%s' must not be longer than %d characters.",
     408             :                         type, kAliHLTComponentDataTypefIDsize
     409             :                 );
     410           0 :                 return false;
     411             :         }
     412           0 :         if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fTypeSet)
     413             :         {
     414           0 :                 fBlockIdList[fBlockIdList.size()-1].fType =
     415           0 :                         AliHLTComponentDataTypeInitializer(
     416             :                                         type,
     417           0 :                                         fBlockIdList[fBlockIdList.size()-1].fType.fOrigin
     418             :                                 );
     419           0 :                 fBlockIdList[fBlockIdList.size()-1].fTypeSet = true;
     420           0 :         }
     421             :         else
     422             :         {
     423           0 :                 AliBlockId id;
     424           0 :                 id.fType = AliHLTComponentDataTypeInitializer(type, kAliHLTDataOriginAny);
     425           0 :                 id.fSpec = kAliHLTVoidDataSpec;
     426           0 :                 id.fTypeSet = true;
     427           0 :                 id.fOriginSet = false;
     428           0 :                 id.fSpecSet = false;
     429           0 :                 fBlockIdList.push_back(id);
     430           0 :         }
     431           0 :         return true;
     432           0 : }
     433             : 
     434             : 
     435             : bool AliHLTCorruptorComponent::AddBlockOrigin(const char* origin)
     436             : {
     437             :         // Sets the block origin to filter on.
     438             :         
     439           0 :         if (strlen(origin) > (unsigned)kAliHLTComponentDataTypefOriginSize)
     440             :         {
     441           0 :                 HLTError("The specified origin '%s' must not be longer than %d characters.",
     442             :                         origin, kAliHLTComponentDataTypefOriginSize
     443             :                 );
     444           0 :                 return false;
     445             :         }
     446           0 :         if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fOriginSet)
     447             :         {
     448           0 :                 fBlockIdList[fBlockIdList.size()-1].fType =
     449           0 :                         AliHLTComponentDataTypeInitializer(
     450           0 :                                         fBlockIdList[fBlockIdList.size()-1].fType.fID,
     451             :                                         origin
     452             :                                 );
     453           0 :                 fBlockIdList[fBlockIdList.size()-1].fOriginSet = true;
     454           0 :         }
     455             :         else
     456             :         {
     457           0 :                 AliBlockId id;
     458           0 :                 id.fType = AliHLTComponentDataTypeInitializer(kAliHLTAnyDataTypeID, origin);
     459           0 :                 id.fSpec = kAliHLTVoidDataSpec;
     460           0 :                 id.fTypeSet = false;
     461           0 :                 id.fOriginSet = true;
     462           0 :                 id.fSpecSet = false;
     463           0 :                 fBlockIdList.push_back(id);
     464           0 :         }
     465           0 :         return true;
     466           0 : }
     467             : 
     468             : 
     469             : bool AliHLTCorruptorComponent::AddBlockSpec(const char* spec)
     470             : {
     471             :         // Sets the block specification to filter on.
     472             :         
     473           0 :         char* err = NULL;
     474           0 :         errno = 0;
     475           0 :         unsigned long long num = strtoull(spec, &err, 0);
     476           0 :         if (err == NULL or *err != '\0')
     477             :         {
     478           0 :                 HLTError("Cannot convert '%s' to a specification number.", spec);
     479           0 :                 return false;
     480             :         }
     481           0 :         if (num > 0xFFFFFFFF or errno == ERANGE)
     482             :         {
     483           0 :                 HLTError("The specification number is not an unsigned 32-bit value or out of range.");
     484           0 :                 return false;
     485             :         }
     486           0 :         AliHLTUInt32_t specVal = AliHLTUInt32_t(num);
     487             :         
     488           0 :         if (fBlockIdList.size() > 0 and not fBlockIdList[fBlockIdList.size()-1].fSpecSet)
     489             :         {
     490           0 :                 fBlockIdList[fBlockIdList.size()-1].fSpec = specVal;
     491           0 :                 fBlockIdList[fBlockIdList.size()-1].fSpecSet = true;
     492           0 :         }
     493             :         else
     494             :         {
     495           0 :                 AliBlockId id;
     496           0 :                 id.fType = AliHLTComponentDataTypeInitializer(kAliHLTAnyDataTypeID, kAliHLTDataOriginAny);
     497           0 :                 id.fSpec = specVal;
     498           0 :                 id.fTypeSet = false;
     499           0 :                 id.fOriginSet = false;
     500           0 :                 id.fSpecSet = true;
     501           0 :                 fBlockIdList.push_back(id);
     502           0 :         }
     503             :         
     504             :         return true;
     505           0 : }
     506             : 
     507             : 
     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,
     515             :                 bool userate,
     516             :                 double rate,
     517             :                 AliHLTUInt64_t minerrors,
     518             :                 AliHLTUInt64_t maxerrors,
     519             :                 AliHLTUInt64_t burstlength,
     520             :                 AliHLTUInt64_t burstcount,
     521             :                 AliHLTUInt64_t minbits,
     522             :                 AliHLTUInt64_t maxbits,
     523             :                 size_t firstpattern,
     524             :                 size_t lastpattern
     525             :         )
     526             : {
     527             :         // Adds a new entry into the corruptions list to apply.
     528             :         
     529           0 :         AliCorruptionInfo info;
     530           0 :         memset(&info, 0x0, sizeof(info));
     531           0 :         info.fType = type;
     532           0 :         info.fMinRange = minrange;
     533           0 :         info.fMaxRange = maxrange;
     534           0 :         info.fAlignment = alignment;
     535           0 :         info.fMinRangeRelative = minRangeRelative;
     536           0 :         info.fMaxRangeRelative = maxRangeRelative;
     537           0 :         info.fUseRate = userate;
     538           0 :         if (userate)
     539             :         {
     540           0 :                 info.fRate = rate;
     541           0 :         }
     542             :         else
     543             :         {
     544           0 :                 info.fMinErrors = minerrors;
     545           0 :                 info.fMaxErrors = maxerrors;
     546             :         }
     547           0 :         switch (type)
     548             :         {
     549             :         case kBurstErrors:
     550           0 :                 info.fBurstErrorLength = burstlength;
     551           0 :                 info.fBurstErrorCount = burstcount;
     552           0 :                 break;
     553             :         case kReplace:
     554           0 :                 info.fFirstPattern = firstpattern;
     555           0 :                 info.fLastPattern = lastpattern;
     556           0 :                 break;
     557             :         case kReplaceRandom:
     558           0 :                 info.fMinBits = minbits;
     559           0 :                 info.fMaxBits = maxbits;
     560           0 :                 break;
     561             :         case kInsert:
     562           0 :                 info.fFirstPattern = firstpattern;
     563           0 :                 info.fLastPattern = lastpattern;
     564           0 :                 break;
     565             :         case kInsertRandom:
     566           0 :                 info.fMinBits = minbits;
     567           0 :                 info.fMaxBits = maxbits;
     568           0 :                 break;
     569             :         case kRemove:
     570           0 :                 info.fMinBits = minbits;
     571           0 :                 info.fMaxBits = maxbits;
     572           0 :                 break;
     573             :         default:
     574             :                 // Nothing to do.
     575             :                 break;
     576             :         }
     577           0 :         fCorruptionInfoList.push_back(info);
     578           0 : }
     579             : 
     580             : 
     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,
     589             :                 bool userate,
     590             :                 double errorrate,
     591             :                 AliHLTUInt64_t minerrors,
     592             :                 AliHLTUInt64_t maxerrors
     593             :         )
     594             : {
     595             :         // Check for a particular command line option that has pattern parameters.
     596             :         
     597           0 :         AliPattern pattern = {0, 0, false};
     598           0 :         if (strcmp(argv[i], name) == 0)
     599             :         {
     600             :                 // Check for at least 1 pattern.
     601           0 :                 if (argc <= i+1)
     602             :                 {
     603           0 :                         HLTError("At least one pattern must be specified for %s.", name);
     604           0 :                         return -EINVAL;
     605             :                 }
     606           0 :                 if (not ConvertToPattern(argv[i+1], pattern)) return -EPROTO;
     607             :                 // Mark the pattern found as the first pattern and add it.
     608           0 :                 size_t firstpattern = fPatterns.size();
     609           0 :                 fPatterns.push_back(pattern);
     610           0 :                 ++i;
     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           0 :                 while (i+1 < argc and ConvertToPattern(argv[i+1], pattern, false))
     615             :                 {
     616           0 :                         fPatterns.push_back(pattern);
     617           0 :                         ++i;
     618             :                 }
     619             :                 // Mark the last pattern and add corruption command.
     620           0 :                 size_t lastpattern = fPatterns.size();
     621           0 :                 AddCorruptionCommand(
     622             :                         type, minrange, maxrange, alignment,
     623           0 :                         minRangeRelative, maxRangeRelative, userate,
     624             :                         errorrate, minerrors, maxerrors, 0, 0, 0, 0,
     625             :                         firstpattern, lastpattern
     626             :                 );
     627             :                 return 1;
     628             :         }
     629           0 :         return 0;
     630           0 : }
     631             : 
     632             : 
     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,
     641             :                 bool userate,
     642             :                 double errorrate,
     643             :                 AliHLTUInt64_t minerrors,
     644             :                 AliHLTUInt64_t maxerrors
     645             :         )
     646             : {
     647             :         // Check for a particular command line option that has 2 (min/max) parameters.
     648             :         
     649           0 :         if (strcmp(argv[i], name) == 0)
     650             :         {
     651           0 :                 if (argc <= i+1)
     652             :                 {
     653           0 :                         HLTError("Minimum number of bits to replace not specified for %s.", name);
     654           0 :                         return -EINVAL;
     655             :                 }
     656           0 :                 AliHLTUInt64_t minbits = 0;
     657           0 :                 if (strcmp(argv[i+1], "min") == 0)
     658             :                 {
     659           0 :                         minbits = 0;
     660           0 :                 }
     661           0 :                 else if (strcmp(argv[i+1], "max") == 0)
     662             :                 {
     663           0 :                         minbits = 0xFFFFFFFFFFFFFFFFull;
     664           0 :                 }
     665             :                 else
     666             :                 {
     667           0 :                         if (not ConvertToPositiveInt(argv[i+1], minbits)) return -EPROTO;
     668             :                 }
     669           0 :                 if (argc <= i+2)
     670             :                 {
     671           0 :                         HLTError("Maximum number of bits to replace not specified for %s.", name);
     672           0 :                         return -EINVAL;
     673             :                 }
     674           0 :                 AliHLTUInt64_t maxbits = 0;
     675           0 :                 if (strcmp(argv[i+2], "min") == 0)
     676             :                 {
     677           0 :                         maxbits = 0;
     678           0 :                 }
     679           0 :                 else if (strcmp(argv[i+2], "max") == 0)
     680             :                 {
     681           0 :                         maxbits = 0xFFFFFFFFFFFFFFFFull;
     682           0 :                 }
     683             :                 else
     684             :                 {
     685           0 :                         if (not ConvertToPositiveInt(argv[i+2], maxbits)) return -EPROTO;
     686             :                 }
     687           0 :                 if (maxbits < minbits)
     688             :                 {
     689           0 :                         HLTError("Maximum value (%s) is smaller than minimum (%s).", argv[i+2], argv[i+1]);
     690           0 :                         return -EPROTO;
     691             :                 }
     692           0 :                 AddCorruptionCommand(
     693             :                         type, minrange, maxrange, alignment,
     694           0 :                         minRangeRelative, maxRangeRelative, userate,
     695             :                         errorrate, minerrors, maxerrors, 0, 0, minbits, maxbits
     696             :                 );
     697           0 :                 i += 2;
     698           0 :                 return 1;
     699           0 :         }
     700           0 :         return 0;
     701           0 : }
     702             : 
     703             : 
     704             : Int_t AliHLTCorruptorComponent::DoInit(int argc, const char** argv)
     705             : {
     706             :         // Initialises the corruptor component from the command line.
     707             :         
     708             :         int result = 0;
     709           0 :         fBlockIdList.clear();
     710           0 :         fCorruptionInfoList.clear();
     711           0 :         fPatterns.clear();
     712           0 :         AliHLTUInt64_t minpos = 0;
     713           0 :         AliHLTUInt64_t maxpos = 0xFFFFFFFFFFFFFFFFull;
     714           0 :         AliHLTUInt64_t alignment = 1;
     715           0 :         bool minposrel = false;
     716           0 :         bool maxposrel = false;
     717             :         bool useErrorRate = true;
     718           0 :         double errorrate = 0.001;
     719           0 :         AliHLTUInt64_t minerrors = 1;
     720           0 :         AliHLTUInt64_t maxerrors = 1;
     721             :         bool seedSet = false;
     722             :         UInt_t seed = 0;
     723             :         
     724           0 :         for (int i = 0; i < argc; ++i)
     725             :         {
     726           0 :                 if (strcmp(argv[i], "-seed") == 0)
     727             :                 {
     728           0 :                         if (seedSet)
     729             :                         {
     730           0 :                                 HLTError("The option \"-seed\" has already been used with"
     731             :                                         " the value %u. Can only use this option once",
     732             :                                         seed
     733             :                                 );
     734           0 :                                 return -EINVAL;
     735             :                         }
     736           0 :                         if (argc <= i+1)
     737             :                         {
     738           0 :                                 HLTError("The random number generator seed was not specified for -seed.");
     739           0 :                                 return -EINVAL;
     740             :                         }
     741           0 :                         AliHLTUInt64_t tmpseed = 0;
     742           0 :                         if (not ConvertToPositiveInt(argv[i+1], tmpseed)) return -EPROTO;
     743           0 :                         if (tmpseed > 0xFFFFFFFF)
     744             :                         {
     745           0 :                                 HLTError("The random number generator seed value cannot be larger than %u.", 0xFFFFFFFF);
     746           0 :                                 return -EPROTO;
     747             :                         }
     748           0 :                         seed = UInt_t(tmpseed);
     749             :                         seedSet = true;
     750           0 :                         ++i;
     751           0 :                         continue;
     752           0 :                 }
     753             :                 
     754           0 :                 if (strcmp(argv[i], "-datatype") == 0)
     755             :                 {
     756           0 :                         if (argc <= i+1)
     757             :                         {
     758           0 :                                 HLTError("The data type identifier was not specified for -datatype.");
     759           0 :                                 return -EINVAL;
     760             :                         }
     761           0 :                         if (not AddBlockTypeId(argv[i+1])) return -EPROTO;
     762           0 :                         if (argc <= i+2)
     763             :                         {
     764           0 :                                 HLTError("The origin identifier was not specified for -datatype.");
     765           0 :                                 return -EINVAL;
     766             :                         }
     767           0 :                         if (not AddBlockOrigin(argv[i+2])) return -EPROTO;
     768           0 :                         i += 2;
     769           0 :                         continue;
     770             :                 }
     771             :                 
     772           0 :                 if (strcmp(argv[i], "-origin") == 0)
     773             :                 {
     774           0 :                         if (argc <= i+1)
     775             :                         {
     776           0 :                                 HLTError("The origin identifier was not specified for -origin.");
     777           0 :                                 return -EINVAL;
     778             :                         }
     779           0 :                         if (not AddBlockOrigin(argv[i+1])) return -EPROTO;
     780           0 :                         ++i;
     781           0 :                         continue;
     782             :                 }
     783             :                 
     784           0 :                 if (strcmp(argv[i], "-typeid") == 0)
     785             :                 {
     786           0 :                         if (argc <= i+1)
     787             :                         {
     788           0 :                                 HLTError("The data type identifier was not specified for -typeid.");
     789           0 :                                 return -EINVAL;
     790             :                         }
     791           0 :                         if (not AddBlockTypeId(argv[i+1])) return -EPROTO;
     792           0 :                         ++i;
     793           0 :                         continue;
     794             :                 }
     795             :                 
     796           0 :                 if (strcmp(argv[i], "-dataspec") == 0)
     797             :                 {
     798           0 :                         if (argc <= i+1)
     799             :                         {
     800           0 :                                 HLTError("The data specification was not specified for -dataspec.");
     801           0 :                                 return -EINVAL;
     802             :                         }
     803           0 :                         if (not AddBlockSpec(argv[i+1])) return -EPROTO;
     804           0 :                         ++i;
     805           0 :                         continue;
     806             :                 }
     807             :                 
     808           0 :                 if (strcmp(argv[i], "-range") == 0)
     809             :                 {
     810           0 :                         if (argc <= i+1)
     811             :                         {
     812           0 :                                 HLTError("Minimum byte/bit position not given for -range.");
     813           0 :                                 return -EINVAL;
     814             :                         }
     815           0 :                         if (not ConvertToBitPosition(argv[i+1], minpos, minposrel)) return -EPROTO;
     816           0 :                         if (argc <= i+2)
     817             :                         {
     818           0 :                                 HLTError("Maximum byte/bit position not given for -range.");
     819           0 :                                 return -EINVAL;
     820             :                         }
     821           0 :                         if (not ConvertToBitPosition(argv[i+2], maxpos, maxposrel)) return -EPROTO;
     822           0 :                         if (minposrel == maxposrel and maxpos < minpos)
     823             :                         {
     824           0 :                                 HLTError("Maximum position (%s) is smaller than minimum position (%s).",
     825             :                                         argv[i+2], argv[i+1]
     826             :                                 );
     827           0 :                                 return -EPROTO;
     828             :                         }
     829           0 :                         i += 2;
     830           0 :                         continue;
     831             :                 }
     832             :                 
     833           0 :                 if (strcmp(argv[i], "-alignment") == 0)
     834             :                 {
     835           0 :                         if (argc <= i+1)
     836             :                         {
     837           0 :                                 HLTError("The alignment value was not specified for -errorrate.");
     838           0 :                                 return -EINVAL;
     839             :                         }
     840           0 :                         if (not ConvertToPositiveInt(argv[i+1], alignment)) return -EPROTO;
     841           0 :                         if (alignment == 0)
     842             :                         {
     843           0 :                                 HLTError("The alignment value cannot be zero.");
     844           0 :                                 return -EPROTO;
     845             :                         }
     846           0 :                         ++i;
     847           0 :                         continue;
     848             :                 }
     849             :                 
     850           0 :                 if (strcmp(argv[i], "-errorrate") == 0)
     851             :                 {
     852           0 :                         if (argc <= i+1)
     853             :                         {
     854           0 :                                 HLTError("The current error rate to use was not specified for -errorrate.");
     855           0 :                                 return -EINVAL;
     856             :                         }
     857           0 :                         if (not ConvertToPercentage(argv[i+1], errorrate)) return -EPROTO;
     858             :                         useErrorRate = true;
     859           0 :                         ++i;
     860           0 :                         continue;
     861             :                 }
     862             :                 
     863           0 :                 if (strcmp(argv[i], "-errorcount") == 0)
     864             :                 {
     865           0 :                         if (argc <= i+1)
     866             :                         {
     867           0 :                                 HLTError("Minimum number of errors not specified for -errorcount.");
     868           0 :                                 return -EINVAL;
     869             :                         }
     870           0 :                         if (not ConvertToPositiveInt(argv[i+1], minerrors)) return -EPROTO;
     871           0 :                         if (argc <= i+2)
     872             :                         {
     873           0 :                                 HLTError("Maximum number of errors not specified for -errorcount.");
     874           0 :                                 return -EINVAL;
     875             :                         }
     876           0 :                         if (not ConvertToPositiveInt(argv[i+2], maxerrors)) return -EPROTO;
     877           0 :                         if (maxerrors < minerrors)
     878             :                         {
     879           0 :                                 HLTError("Maximum error count (%s) is smaller than minimum (%s).",
     880             :                                         argv[i+2], argv[i+1]
     881             :                                 );
     882           0 :                                 return -EPROTO;
     883             :                         }
     884             :                         useErrorRate = false;
     885           0 :                         i += 2;
     886           0 :                         continue;
     887             :                 }
     888             :                 
     889           0 :                 if (strcmp(argv[i], "-singleflips") == 0)
     890             :                 {
     891           0 :                         AddCorruptionCommand(
     892           0 :                                 kSingleFlips, minpos, maxpos, alignment,
     893           0 :                                 minposrel, maxposrel, useErrorRate,
     894           0 :                                 errorrate, minerrors, maxerrors
     895             :                         );
     896           0 :                         continue;
     897             :                 }
     898             :                 
     899           0 :                 if (strcmp(argv[i], "-bursterrors") == 0)
     900             :                 {
     901           0 :                         if (argc <= i+1)
     902             :                         {
     903           0 :                                 HLTError("Maximum burst error length not specified for -bursterrors.");
     904           0 :                                 return -EINVAL;
     905             :                         }
     906           0 :                         AliHLTUInt64_t burstLength;
     907           0 :                         if (not ConvertToPositiveInt(argv[i+1], burstLength)) return -EPROTO;
     908           0 :                         if (argc <= i+2)
     909             :                         {
     910           0 :                                 HLTError("Number of bit flips in a burst error not specified for -bursterrors.");
     911           0 :                                 return -EINVAL;
     912             :                         }
     913           0 :                         AliHLTUInt64_t burstCount;
     914           0 :                         if (not ConvertToPositiveInt(argv[i+2], burstCount)) return -EPROTO;
     915           0 :                         AddCorruptionCommand(
     916           0 :                                 kBurstErrors, minpos, maxpos, alignment,
     917           0 :                                 minposrel, maxposrel, useErrorRate, errorrate,
     918           0 :                                 minerrors, maxerrors, burstLength, burstCount
     919             :                         );
     920           0 :                         i += 2;
     921           0 :                         continue;
     922           0 :                 }
     923             :                 
     924           0 :                 result = CheckForCommandWithPatterns("-replace", kReplace,
     925           0 :                                 i, argc, argv, minpos, maxpos, alignment,
     926           0 :                                 minposrel, maxposrel, useErrorRate,
     927           0 :                                 errorrate, minerrors, maxerrors
     928             :                         );
     929           0 :                 if (result == 1) continue;
     930           0 :                 if (result < 0) return result;
     931             :                 
     932           0 :                 result = CheckForCommandWithPatterns("-insert", kInsert,
     933           0 :                                 i, argc, argv, minpos, maxpos, alignment,
     934           0 :                                 minposrel, maxposrel, useErrorRate,
     935           0 :                                 errorrate, minerrors, maxerrors
     936             :                         );
     937           0 :                 if (result == 1) continue;
     938           0 :                 if (result < 0) return result;
     939             :                 
     940           0 :                 result = CheckForCommandWithMinMax("-replace-random", kReplaceRandom,
     941           0 :                                 i, argc, argv, minpos, maxpos, alignment,
     942           0 :                                 minposrel, maxposrel, useErrorRate,
     943           0 :                                 errorrate, minerrors, maxerrors
     944             :                         );
     945           0 :                 if (result == 1) continue;
     946           0 :                 if (result < 0) return result;
     947             :                 
     948           0 :                 result = CheckForCommandWithMinMax("-insert-random", kInsertRandom,
     949           0 :                                 i, argc, argv, minpos, maxpos, alignment,
     950           0 :                                 minposrel, maxposrel, useErrorRate,
     951           0 :                                 errorrate, minerrors, maxerrors
     952             :                         );
     953           0 :                 if (result == 1) continue;
     954           0 :                 if (result < 0) return result;
     955             :                 
     956           0 :                 result = CheckForCommandWithMinMax("-remove", kRemove,
     957           0 :                                 i, argc, argv, minpos, maxpos, alignment,
     958           0 :                                 minposrel, maxposrel, useErrorRate,
     959           0 :                                 errorrate, minerrors, maxerrors
     960             :                         );
     961           0 :                 if (result == 1) continue;
     962           0 :                 if (result < 0) return result;
     963             :                 
     964           0 :                 HLTError("Unknown option '%s'.", argv[i]);
     965           0 :                 return -EINVAL;
     966             :         } // for loop
     967             :         
     968             :         // If no errors were specified then set to 1% single bit corruption.
     969           0 :         if (fCorruptionInfoList.size() == 0)
     970             :         {
     971           0 :                 minpos = 0;
     972           0 :                 maxpos = 0xFFFFFFFFFFFFFFFFull;
     973           0 :                 alignment = 1;
     974             :                 useErrorRate = true;
     975           0 :                 errorrate = 0.001;
     976           0 :                 AddCorruptionCommand(
     977           0 :                         kSingleFlips, minpos, maxpos, alignment, useErrorRate, errorrate
     978             :                 );
     979           0 :         }
     980             :         
     981           0 :         gRandom->SetSeed(0); // Use current time.
     982             :         
     983           0 :         HLTInfo("Starting Corruptor Component.");
     984           0 :         return 0;
     985           0 : }
     986             : 
     987             : 
     988             : Int_t AliHLTCorruptorComponent::DoDeinit()
     989             : {
     990             :         // Cleans up the corruptor component.
     991           0 :         fBlockIdList.clear();
     992           0 :         return 0;
     993             : }
     994             : 
     995             : 
     996             : bool AliHLTCorruptorComponent::ShouldProcess(const AliHLTComponentBlockData* block) const
     997             : {
     998           0 :         if (fBlockIdList.size() == 0) return true;
     999           0 :         for (size_t i = 0; i < fBlockIdList.size(); ++i)
    1000             :         {
    1001           0 :                 AliBlockId id = fBlockIdList[i];
    1002           0 :                 AliHLTComponentDataType type = AliHLTComponentDataTypeInitializer(
    1003           0 :                                 id.fTypeSet ? id.fType : kAliHLTAnyDataType,
    1004           0 :                                 id.fOriginSet ? id.fType.fOrigin : kAliHLTDataOriginAny
    1005             :                         );
    1006           0 :                 if (type != block->fDataType) continue;
    1007           0 :                 if (id.fSpecSet and id.fSpec != block->fSpecification) continue;
    1008           0 :                 return true;
    1009           0 :         }
    1010           0 :         return false;
    1011           0 : }
    1012             : 
    1013             : 
    1014             : void AliHLTCorruptorComponent::ApplyCorruption(std::vector<bool>& bits) const
    1015             : {
    1016             :         // Applies corruption to the bit string.
    1017             :         
    1018           0 :         std::vector<bool> removed;
    1019           0 :         std::vector<bool> pattern;
    1020           0 :         for (size_t i = 0; i < fCorruptionInfoList.size(); ++i)
    1021             :         {
    1022           0 :                 AliCorruptionInfo info = fCorruptionInfoList[i];
    1023             : #ifdef DEBUG
    1024             :                 const char* cmdtype = NULL;
    1025             :                 switch (info.fType)
    1026             :                 {
    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;
    1035             :                 }
    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)
    1048             :                 );
    1049             : #endif // DEBUG
    1050             :                 
    1051             :                 // Calculate the range (and adjust for buffer size)
    1052           0 :                 AliHLTUInt64_t minrange = info.fMinRangeRelative ? bits.size() - info.fMinRange : info.fMinRange;
    1053           0 :                 AliHLTUInt64_t maxrange = info.fMaxRangeRelative ? bits.size() - info.fMaxRange : info.fMaxRange;
    1054           0 :                 if (minrange == 0xFFFFFFFFFFFFFFFFull)
    1055             :                 {
    1056           0 :                         if (info.fType == kInsert or info.fType == kInsertRandom or bits.size() == 0)
    1057             :                         {
    1058           0 :                                 minrange = bits.size();
    1059           0 :                         }
    1060             :                         else
    1061             :                         {
    1062           0 :                                 minrange = bits.size() - 1;
    1063             :                         }
    1064             :                 }
    1065           0 :                 if (maxrange == 0xFFFFFFFFFFFFFFFFull)
    1066             :                 {
    1067           0 :                         if (info.fType == kInsert or info.fType == kInsertRandom or bits.size() == 0)
    1068             :                         {
    1069           0 :                                 maxrange = bits.size();
    1070           0 :                         }
    1071             :                         else
    1072             :                         {
    1073           0 :                                 maxrange = bits.size() - 1;
    1074             :                         }
    1075             :                 }
    1076           0 :                 if (maxrange < minrange) maxrange = minrange;
    1077             :                 
    1078             :                 // Select the correct number of errors to generate.
    1079             :                 AliHLTUInt64_t errorcount = 0;
    1080           0 :                 if (info.fUseRate)
    1081             :                 {
    1082           0 :                         errorcount = AliHLTUInt64_t(bits.size() * info.fRate);
    1083           0 :                 }
    1084             :                 else
    1085             :                 {
    1086           0 :                         AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1087           0 :                                                 | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1088           0 :                         errorcount = rnum % (info.fMaxErrors - info.fMinErrors + 1) + info.fMinErrors;
    1089             :                 }
    1090             :                 
    1091             :                 // Build the pattern bits for a replace or insert command.
    1092           0 :                 if (info.fType == kReplace or info.fType == kInsert)
    1093             :                 {
    1094           0 :                         pattern.clear();
    1095           0 :                         for (size_t k = info.fFirstPattern; k < info.fLastPattern; ++k)
    1096             :                         {
    1097           0 :                                 const AliPattern& pat = fPatterns[k];
    1098           0 :                                 if (pat.fUseRemoved)
    1099             :                                 {
    1100           0 :                                         pattern.insert(pattern.end(), removed.begin(), removed.end());
    1101           0 :                                 }
    1102             :                                 else
    1103             :                                 {
    1104           0 :                                         for (AliHLTUInt8_t j = 0; j < pat.fWidth; ++j)
    1105             :                                         {
    1106           0 :                                                 pattern.push_back( ((pat.fPattern >> j) & 0x1) == 0x1 );
    1107             :                                         }
    1108             :                                 }
    1109             :                         }
    1110           0 :                 }
    1111             :                 
    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           0 :                 if (info.fType == kReplaceRandom or info.fType == kInsertRandom or info.fType == kRemove)
    1116             :                 {
    1117             :                         AliHLTUInt64_t minbits = info.fMinBits;
    1118             :                         AliHLTUInt64_t maxbits = info.fMaxBits;
    1119           0 :                         if (minbits == 0xFFFFFFFFFFFFFFFFull) minbits = bits.size();
    1120           0 :                         if (maxbits == 0xFFFFFFFFFFFFFFFFull) maxbits = bits.size();
    1121           0 :                         if (maxbits < minbits) maxbits = minbits;
    1122           0 :                         AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1123           0 :                                               | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1124           0 :                         bitcount = rnum % (maxbits - minbits + 1) + minbits;
    1125           0 :                 }
    1126             :                 
    1127           0 :                 switch (info.fType)
    1128             :                 {
    1129             :                 case kSingleFlips:
    1130           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1131             :                         {
    1132           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1133           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1134           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1135           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1136           0 :                                 if (not (pos < bits.size())) continue;
    1137           0 :                                 bits[pos] = not bits[pos];
    1138           0 :                         }
    1139           0 :                         break;
    1140             :                 case kBurstErrors:
    1141           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1142             :                         {
    1143           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1144           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1145           0 :                                 AliHLTUInt64_t firstpos = rnum % (maxrange - minrange + 1) + minrange;
    1146           0 :                                 firstpos = ((firstpos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1147           0 :                                 AliHLTUInt64_t lastpos = firstpos + info.fBurstErrorLength;
    1148           0 :                                 if (lastpos < firstpos)
    1149             :                                 {
    1150           0 :                                         HLTWarning("Burst error length %llu is too large and caused an overflow.",
    1151             :                                                 info.fBurstErrorLength
    1152             :                                         );
    1153             :                                         lastpos = firstpos;
    1154           0 :                                 }
    1155           0 :                                 if (lastpos == firstpos) continue;
    1156           0 :                                 for (AliHLTUInt64_t j = 0; j < info.fBurstErrorCount; ++j)
    1157             :                                 {
    1158           0 :                                         rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1159           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1160           0 :                                         AliHLTUInt64_t pos = rnum % (lastpos - firstpos) + firstpos;
    1161           0 :                                         if (not (pos < bits.size())) continue;
    1162           0 :                                         bits[pos] = not bits[pos];
    1163           0 :                                 }
    1164           0 :                         }
    1165           0 :                         break;
    1166             :                 case kReplace:
    1167           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1168             :                         {
    1169           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1170           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1171           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1172           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1173           0 :                                 for (UInt_t j = pos; j < pos + pattern.size() and j < bits.size(); ++j)
    1174             :                                 {
    1175           0 :                                         bits[j] = pattern[j-pos];
    1176             :                                 }
    1177             :                         }
    1178           0 :                         break;
    1179             :                 case kReplaceRandom:
    1180           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1181             :                         {
    1182           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1183           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1184           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1185           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1186           0 :                                 for (UInt_t j = pos; j < pos + bitcount and j < bits.size(); ++j)
    1187             :                                 {
    1188           0 :                                         bits[j] = gRandom->Integer(2) == 1;
    1189             :                                 }
    1190             :                         }
    1191           0 :                         break;
    1192             :                 case kInsert:
    1193           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1194             :                         {
    1195           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1196           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1197           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1198           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1199           0 :                                 if (not (pos <= bits.size())) continue;
    1200           0 :                                 bits.insert(bits.begin() + pos, pattern.begin(), pattern.end());
    1201           0 :                         }
    1202           0 :                         break;
    1203             :                 case kInsertRandom:
    1204           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1205             :                         {
    1206           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1207           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1208           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1209           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1210           0 :                                 if (not (pos <= bits.size())) continue;
    1211           0 :                                 std::vector<bool> newbits;
    1212           0 :                                 for (UInt_t j = 0; j < bitcount; ++j)
    1213             :                                 {
    1214           0 :                                         newbits.push_back(gRandom->Integer(2) == 1);
    1215             :                                 }
    1216           0 :                                 bits.insert(bits.begin() + pos, newbits.begin(), newbits.end());
    1217           0 :                         }
    1218           0 :                         break;
    1219             :                 case kRemove:
    1220           0 :                         removed.clear();
    1221           0 :                         for (AliHLTUInt64_t n = 0; n < errorcount; ++n)
    1222             :                         {
    1223           0 :                                 AliHLTUInt64_t rnum = (AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF)) << 32)
    1224           0 :                                                         | AliHLTUInt64_t(gRandom->Integer(0xFFFFFFFF));
    1225           0 :                                 AliHLTUInt64_t pos = rnum % (maxrange - minrange + 1) + minrange;
    1226           0 :                                 pos = ((pos - minrange) / info.fAlignment) * info.fAlignment + minrange;
    1227           0 :                                 if (not (pos < bits.size())) continue;
    1228           0 :                                 AliHLTUInt64_t end = pos + bitcount;
    1229           0 :                                 if (end > bits.size()) end = bits.size();
    1230           0 :                                 removed.insert(removed.begin(), bits.begin() + pos, bits.begin() + end);
    1231           0 :                                 bits.erase(bits.begin() + pos, bits.begin() + end);
    1232           0 :                         }
    1233           0 :                         break;
    1234             :                 default:
    1235           0 :                         HLTWarning("Received an unknown corruption type. There must be a program bug!");
    1236           0 :                         continue;
    1237             :                 }
    1238           0 :         }
    1239           0 : }
    1240             : 
    1241             : 
    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
    1249             :         )
    1250             : {
    1251             :         // Processes the input data blocks.
    1252             :         // The data blocks will be copied to the output and corrupted in some way.
    1253             :         
    1254             :         AliHLTUInt8_t* output = outputPtr;
    1255             :         AliHLTUInt32_t totalSize = 0;
    1256             :         
    1257           0 :         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
    1258             :         {
    1259             :                 HLTDebug("Processing block %d, of type '%s' with specification 0x%8.8X.",
    1260             :                         n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
    1261             :                 );
    1262           0 :                 if (not ShouldProcess(blocks + n))
    1263             :                 {
    1264           0 :                         Forward();
    1265           0 :                         continue;
    1266             :                 }
    1267             :                 
    1268             :                 // Convert data block buffer to a bit string.
    1269           0 :                 std::vector<bool> bits;
    1270           0 :                 const AliHLTUInt8_t* buffer = reinterpret_cast<const AliHLTUInt8_t*>(blocks[n].fPtr);
    1271           0 :                 for (AliHLTUInt32_t i = 0; i < blocks[n].fSize; ++i)
    1272             :                 {
    1273           0 :                         for (AliHLTUInt8_t j = 0; j < 8; ++j)
    1274             :                         {
    1275           0 :                                 bits.push_back( ((buffer[i] >> j) & 0x1) == 0x1 );
    1276             :                         }
    1277             :                 }
    1278             :                 
    1279           0 :                 ApplyCorruption(bits);
    1280             :                 
    1281             :                 // Convert bit string back to a data buffer.
    1282           0 :                 if (bits.size() > 0xFFFFFFFFull * 8)
    1283             :                 {
    1284           0 :                         HLTWarning("The internal bit string representation is too large for the output buffer. Skipping block.");
    1285           0 :                         continue;
    1286             :                 }
    1287           0 :                 AliHLTUInt32_t blockSize = bits.size() / 8;
    1288           0 :                 if (bits.size() % 8 > 0) ++blockSize;
    1289             :                 
    1290           0 :                 if (totalSize + blockSize > size)
    1291             :                 {
    1292           0 :                         HLTError("Out of buffer space. Require %d bytes but have %d bytes of buffer space.",
    1293             :                                 totalSize + blockSize, size
    1294             :                         );
    1295           0 :                         fBufferMultiplier *= 8;
    1296           0 :                         return -ENOSPC;
    1297             :                 }
    1298             :                 
    1299           0 :                 memset(output, 0x0, blockSize);
    1300           0 :                 for (size_t i = 0; i < bits.size(); ++i)
    1301             :                 {
    1302           0 :                         AliHLTUInt32_t byte = i / 8;
    1303           0 :                         AliHLTUInt32_t bit = i % 8;
    1304           0 :                         output[byte] = output[byte] | (bits[i] << bit);
    1305             :                 }
    1306             :                 
    1307           0 :                 AliHLTComponentBlockData bd;
    1308           0 :                 FillBlockData(bd);
    1309           0 :                 bd.fPtr = outputPtr;
    1310           0 :                 bd.fOffset = totalSize;
    1311           0 :                 bd.fSize = blockSize;
    1312           0 :                 bd.fDataType = blocks[n].fDataType;
    1313           0 :                 bd.fSpecification = blocks[n].fSpecification;
    1314           0 :                 outputBlocks.push_back(bd);
    1315             :                 
    1316             :                 totalSize += blockSize;
    1317           0 :                 output += blockSize;
    1318           0 :         }
    1319             :         
    1320           0 :         size = totalSize; // Set the correct output size.
    1321           0 :         return 0;
    1322           0 : }

Generated by: LCOV version 1.11