public void ProcessByte(byte p) { // Compare the new byte with the remainder's higher bits to // get the new bits, shift out the remainder's current higher // bits, and update the remainder with the polynominal division // of the new bits. byte byte_index = helper_type.index(Remainder, p); Remainder = Operator <T> .Xor(helper_type.shift(Remainder), crc_table_type.Table[byte_index]); if (bIsBigIntegerType) { // это не обязательно для обычных целых типов. И просто кровь из носу требуется выполнять для BigInteger. // иначе регистр будет расти в размере // регистр может расшириться на 8 бит после обработки одного байта // нужен разумный компромисс между размером регистра и частотой сброса старших бит BIByteProcessCount--; if (BIByteProcessCount <= 0) { Remainder = Operator <T> .And(Remainder, masking_type.SigBits); BIByteProcessCount = BIByteProcessThresold; } } }
// Compare a byte to the remainder's highest byte public byte index(T rem, byte x) { if (!DoReflect) { if (Bits > Limits.CHAR_BIT) { rem = Operator <T> .RightShift(rem, Bits - Limits.CHAR_BIT); } else { rem = Operator <T> .LeftShift(rem, Limits.CHAR_BIT - Bits); } } rem = Operator <T> .Xor(rem, Operator <byte, T> .Convert(x)); if (bIsBigIntegerType) { // следующая строчка важна для класса BigInteger, но не требуется для встроенных численных типов. // BigInteger может кидать исключение при преобразовании к byte. Мы должны дать гарантию приведения к byte без // швыряния исключения. rem = Operator <T> .And(rem, MaskUint <T> .Value0xFF); // гарантия того что число не превышает значения байта } return(Operator <T, byte> .Convert(rem)); }
/// <summary> /// инициализирует таблицу для быстрого расчёта /// </summary> public void InitTable() { CRChelper <byte> charRefl = new CRChelper <byte>(Limits.CHAR_BIT, Reflect); CRChelper <T> BitsRefl = new CRChelper <T>(Bits, Reflect); // factor-out constants to avoid recalculation T fast_hi_bit = masking_type.HighBitMask; const byte byte_hi_bit = MaskUint <T> .ByteHighBitMask; // loop over every possible dividend value byte dividend = 0; do { T remainder = new T(); // go through all the dividend's bits for (byte mask = byte_hi_bit; mask > 0; mask >>= 1) { // check if divisor fits if ((dividend & mask) != 0) { remainder = Operator <T> .Xor(remainder, fast_hi_bit); } // do polynominal division bool bNotEqual = Operator <T> .NotEqual(Operator <T> .And(remainder, fast_hi_bit), Operator <T> .Zero); if (bNotEqual) { remainder = Operator <T> .LeftShift(remainder, 1); remainder = Operator <T> .Xor(remainder, TruncPoly); } else { remainder = Operator <T> .LeftShift(remainder, 1); } } T tmp = BitsRefl.reflect(remainder); // следующее выражение необязательно. Просто можно обнулить старшие(неиспользуемые) биты в регистре //tmp = Operator<T>.And(tmp, masking_type.SigBits); Table_[charRefl.reflect(dividend)] = tmp; ++dividend; }while (dividend != 0); }
public T Calculate(byte[] buffer, int offset, int size, T initial_remainder) { /// число обработанных байт в режиме работы с BigInteger int BIByteProcessCount = BIByteProcessThresold; T rem = initial_remainder; for (int x = 0; x < size; x++) { byte p = buffer[offset + x]; // Use the current top byte as the table index to the next // "partial product." Shift out that top byte, shifting in // the next augmented-message byte. Complete the division. T TopByte = Operator <T> .RightShift(rem, Bits - Limits.CHAR_BIT); if (bIsBigIntegerType) { // это не обязательно для обычных целых типов. И просто кровь из носу требуется выполнять для BigInteger. // тут есть шанс словить эксепшен. защита от этого TopByte = Operator <T> .And(TopByte, MaskUint <T> .Value0xFF); // регистр растёт в размере на 8 бит после обработки одного байта // нужен разумный компромисс между размером регистра и частотой сброса старших бит BIByteProcessCount--; if (BIByteProcessCount <= 0) { rem = Operator <T> .And(rem, masking_type.SigBits); BIByteProcessCount = BIByteProcessThresold; } } byte byte_index = Operator <T, byte> .Convert(TopByte); rem = Operator <T> .LeftShift(rem, Limits.CHAR_BIT); rem = Operator <T> .Or(rem, Operator <byte, T> .Convert(p)); rem = Operator <T> .Xor(rem, crc_table_type.Table[byte_index]); } return(Operator <T> .And((T)rem, masking_type.SigBits)); }
bool Fold(LogicalBinaryExpression n) { bool vleft = n.left.Value.Val <bool>(); bool vright = n.right.Value.Val <bool>(); switch (n.op) { case LogicalBinaryOp.AND: return(Operator.And(vleft, vright)); case LogicalBinaryOp.OR: return(Operator.Or(vleft, vright)); case LogicalBinaryOp.XOR: return(Operator.Xor(vleft, vright)); default: throw new SemanticException("Invalid operator " + n.op + " in logical binary expr"); } }
/// <summary> /// обращение бит в целом числе /// </summary> /// <param name="x"></param> /// <returns></returns> public static T reflect(T x, int Bits) { T reflection = Operator <T> .Zero; for (int i = 0; i < Bits; ++i, x = Operator <T> .RightShift(x, 1)) { T TestedBit = Operator <T> .And(x, MaskUint <T> .One); if (Operator <T> .Equal(TestedBit, MaskUint <T> .One)) { int index = Bits - 1 - i; T TmpVal = Operator <T> .LeftShift(MaskUint <T> .One, index); reflection = Operator <T> .Or(reflection, TmpVal); } } return(reflection); }
/// <summary> /// обработка бита /// </summary> /// <param name="bit"></param> public void ProcessBit(bool bit) { // compare the new bit with the remainder's highest if (bit) { Remainder = Operator <T> .Xor(Remainder, masking_type.HighBitMask); } // a full polynominal division step is done when the highest bit is one bool DoPolyDiv = Operator <T> .NotEqual( Operator <T> .And(Remainder, masking_type.HighBitMask), Operator <T> .Zero ); // shift out the highest bit Remainder = Operator <T> .LeftShift(Remainder, 1); // carry out the division, if needed if (DoPolyDiv) { Remainder = Operator <T> .Xor(Remainder, TruncPoly); } }
/// <summary> /// Evaluates bitwise and (&) for the given type; this will throw /// an InvalidOperationException if the type T does not provide this operator, or for /// Nullable<TInner> if TInner does not provide this operator. /// </summary> public static T And <T>(T value1, T value2) { return(Operator <T> .And(value1, value2)); }
protected virtual Operator BuildTreeNode(int intKey, string captureData, IReadOnlyList <Operator> parameters) { var key = (CaptureType)intKey; switch (key) { case CaptureType.And: return(Operator.And(parameters[0])); case CaptureType.Any: return(new Any()); case CaptureType.CharacterClass: var rangeParams = parameters.OfType <CharacterClass>(); return(new CharacterClass(rangeParams.SelectMany(p => p.Ranges))); case CaptureType.CharacterClassRange: if (parameters.Count == 1) { return(parameters[0]); } else { var min = (CharacterClass)parameters[0]; var max = (CharacterClass)parameters[1]; if (min.NumChars > 1 || max.NumChars > 1) { throw new PegParsingException($"Cannot create range from {min} and {max}"); } return(CharacterClass.Range(min.Value.First(), max.Value.Last())); } case CaptureType.Definition: var identifier = parameters[0] as Pattern; identifier.Data = parameters[1]; return(identifier); case CaptureType.Empty: return(new Empty()); case CaptureType.Identifier: return(new UnresolvedPatternReference(captureData)); case CaptureType.Character: if (captureData.Length == 1) { return(new CharacterClass(captureData[0])); } else { return(new CharacterClass(TranslateEscapeCharacter(captureData))); } case CaptureType.Literal: if (parameters.Count <= 0) { return(new Empty()); } else if (parameters.Count == 1) { return(parameters[0]); } else { return(new Sequence(parameters)); } case CaptureType.Not: return(new Not(parameters[0])); case CaptureType.OneOrMore: return(Operator.OneOrMore(parameters[0])); case CaptureType.Optional: return(Operator.Optional(parameters[0])); case CaptureType.ZeroOrMore: return(new ZeroOrMore(parameters[0])); case CaptureType.PrioritizedChoice: if (parameters.Count <= 1) { return(parameters[0]); } if (parameters.All(item => item is CharacterClass)) { return(new CharacterClass(parameters.Cast <CharacterClass>().SelectMany(item => item.Ranges))); } return(new PrioritizedChoice(parameters)); case CaptureType.Sequence: if (parameters.Count <= 1) { return(parameters[0]); } return(new Sequence(parameters)); default: throw new ArgumentOutOfRangeException($"Unrecognised CaptureType {key}"); } }
public void AndInt32() { Assert.AreEqual(270 & 54, Operator.And(270, 54)); }