/// <summary> /// Decodes the object by PER. /// </summary> /// <param name="buffer">A buffer that contains a PER encoding result.</param> /// <param name="aligned">Indicating whether the PER decoding is aligned.</param> protected override void ValuePerDecode(IAsn1DecodingBuffer buffer, bool aligned = true) { Asn1Integer ai = new Asn1Integer(null, Constraints.Min, Constraints.Max); ai.PerDecode(buffer, aligned); Value = allowedValues[(int)ai.Value]; }
/// <summary> /// Decodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer that contains a PER encoding result.</param> /// <param name="aligned">Indicating whether the PER decoding is aligned.</param> protected override void ValuePerDecode(IAsn1DecodingBuffer buffer, bool aligned = true) { //Decode the index specifying the chosen alternative, Ref: X.691: 22 Asn1Integer ai = new Asn1Integer(null, 0, definedAllowedIndices.Count - 1); ai.PerDecode(buffer); //Decode the chosen alternative Asn1Object[] instances = ChoiceTypeInstances; Asn1Object obj = instances[(int)ai.Value]; obj.PerDecode(buffer); SetData(definedAllowedIndices[(int)ai.Value], obj); }
/// <summary> /// Decodes the object by PER. /// </summary> /// <param name="buffer">A buffer that contains a PER encoding result.</param> /// <param name="aligned">Indicating whether the PER decoding is aligned.</param> public override void PerDecode(IAsn1DecodingBuffer buffer, bool aligned = true) { if (HasExternalObjects) { buffer.ReadBit(); //TODO: if true is read, store the decoding value to external object } Asn1Integer ai = new Asn1Integer(null, Min, Max); ai.PerDecode(buffer, aligned); Debug.Assert(ai.Value != null, "ai.Value != null"); Value = allowedValues[(int)ai.Value]; }
/// <summary> /// Decodes the object by PER. /// </summary> /// <param name="buffer">A buffer that contains a PER encoding result.</param> /// <param name="aligned">Indicating whether the PER decoding is aligned.</param> public override void PerDecode(IAsn1DecodingBuffer buffer, bool aligned = true) { if (aligned == false) { throw new NotImplementedException(ExceptionMessages.UnalignedNotImplemented); } long baseNum = Min ?? 0; //Ref. X.691: 10.5.2 if (Min == null || Max == null) //range is equal to null { byte length = buffer.ReadByte(); if (length == 0) { Value = baseNum; return; } byte[] result = buffer.ReadBytes(length); if (Min == null) { //No base Value = IntegerDecoding(result); } else { Value = baseNum + NonNegativeBinaryIntegerPerDeocde(result); } } else { if (Range == 1) { this.Value = Min; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } bool[] result = buffer.ReadBits(bitFieldSize); byte offset = 0; foreach (var b in result) { offset <<= 1; offset += (byte)(b ? 1 : 0); } Value = baseNum + offset; } else if (Range == 256) //10.5.7: b) { Value = baseNum + buffer.ReadByte(); } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = buffer.ReadBytes(2); Value = baseNum + bytes[0] * 256 + bytes[1]; } else //10.5.7: d) { Asn1Integer len = new Asn1Integer(); len.Min = 1; len.Max = 4; len.PerDecode(buffer); Debug.Assert(len.Value != null, "len.Value != null"); byte[] bytes = buffer.ReadBytes((int)len.Value); Value = baseNum + NonNegativeBinaryIntegerPerDeocde(bytes); } } if (!VerifyConstraints()) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied); } }
/// <summary> /// Decodes an array of objects from a buffer. /// </summary> /// <typeparam name="T">Type of the objects.</typeparam> /// <param name="buffer">A buffer that stores the encoding result of the objects.</param> /// <param name="decoder">A method that provides the functionality of decoding a single object.</param> /// <param name="minSize">Minimal size of the array.</param> /// <param name="maxSize">Maximal size of the array.</param> /// <param name="alignAfterDecodeLength">Indicates whether align when the length is decoded.</param> /// <returns>An array of the objects that are decoded from the buffer.</returns> public static T[] PerDecodeArray <T>(IAsn1DecodingBuffer buffer, PerDecodeSingleObject <T> decoder, long?minSize = null, long?maxSize = null, bool alignAfterDecodeLength = false) { List <T> result = new List <T>(); long decodeNum = 0; if (minSize == null && maxSize == null) { bool end = false; while (!end) { byte lenHead = buffer.ReadByte(); if (lenHead > 196) { throw new Asn1DecodingUnexpectedData(ExceptionMessages.DecodingUnexpectedData + " Length in PER fragment illegal."); } else if (lenHead > 192) { long fraNum = lenHead - 192; decodeNum = fraNum * 16 * 1024; end = false; } else if (lenHead >= 128) { byte lenNext = buffer.ReadByte(); decodeNum = 256L * (lenHead - 128) + lenNext; end = true; } else //lenHead < 128 { decodeNum = lenHead; end = true; } for (long i = 0; i < decodeNum; i++) { T t = decoder(buffer); result.Add(t); } } return(result.ToArray()); } else if (minSize != null && maxSize != null) { if (minSize < 0 || maxSize < minSize) { throw new Asn1UserDefinedTypeInconsistent(ExceptionMessages.UserDefinedTypeInconsistent + " Size constraints illegal."); } long range = (long)(maxSize - minSize + 1); if (range > 256L * 256) { throw new NotImplementedException("Array with big size constraints are not implemented yet."); } //range < 256 * 256 if (maxSize == 0) //Ref. X.691: 16.5 { return(new T[0]); } if (maxSize != minSize) //Ref. X.691: 16.8 { //Decode length Asn1Integer ai = new Asn1Integer(null, minSize, maxSize); ai.PerDecode(buffer); if (alignAfterDecodeLength) { buffer.AlignData(); } decodeNum = (long)ai.Value; } else { decodeNum = minSize.Value; } for (long i = 0; i < decodeNum; i++) { T t = decoder(buffer); result.Add(t); } return(result.ToArray()); } else { throw new NotImplementedException("Array with semi size constraints are not implemented yet."); } }
/// <summary> /// Decodes the object by PER. /// </summary> /// <param name="buffer">A buffer that contains a PER encoding result.</param> /// <param name="aligned">Indicating whether the PER decoding is aligned.</param> protected override void ValuePerDecode(IAsn1DecodingBuffer buffer, bool aligned = true) { long baseNum = (Constraints != null && Constraints.HasMin ? Constraints.Min : 0); //Ref. X.691: 10.5.2 if (Range == null) //range is equal to null { byte length = buffer.ReadByte(); if (length == 0) { Value = baseNum; return; } byte[] result = buffer.ReadBytes(length); if (Constraints == null || !Constraints.HasMin) { //No base Value = IntegerDecoding(result); } else { Value = baseNum + NonNegativeBinaryIntegerPerDeocde(result); } } else { if (Range == 1) { Value = Constraints.Min; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } bool[] result = buffer.ReadBits(bitFieldSize); byte offset = 0; foreach (var b in result) { offset <<= 1; offset += (byte)(b ? 1 : 0); } Value = baseNum + offset; } else if (Range == 256) //10.5.7: b) { Value = baseNum + buffer.ReadByte(); } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = buffer.ReadBytes(2); Value = baseNum + bytes[0] * 256 + bytes[1]; } else //10.5.7: d) { Asn1Integer len = new Asn1Integer { Constraints = new Asn1IntegerBound { Min = 1, Max = 4 } }; len.PerDecode(buffer); byte[] bytes = buffer.ReadBytes((int)len.Value); Value = baseNum + NonNegativeBinaryIntegerPerDeocde(bytes); } } }