//BER encoding & decoding are implemented in the base class #region PER /// <summary> /// Encodes the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> public override void PerEncode(IAsn1PerEncodingBuffer buffer) { if (HasExternalObjects) { //TODO: write true to the buffer if external element is used and not within the extension root //Ref: X.691: 13.3 buffer.WriteBit(false); } int i = 0; for (; i < allowedValues.Count; i++) { if (allowedValues[i] == Value) { break; } } if (i == allowedValues.Count) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied + " Invalid enumeration."); } Asn1Integer ai = new Asn1Integer(i, Min, Max); ai.PerEncode(buffer); }
/// <summary> /// Encodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer) { //Encode an index specifying the chosen alternative, Ref: X.691: 22 Asn1Integer ai = new Asn1Integer(choiceIndexInFieldsMemberInfo, 0, definedAllowedIndices.Count - 1); ai.PerEncode(buffer); //Encode the chosen alternative Asn1Object obj = GetData(); obj.PerEncode(buffer); }
//BER encoding & decoding are implemented in the base class #region PER /// <summary> /// Encodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer) { int i = 0; for (; i < allowedValues.Count; i++) { if (allowedValues[i] == Value) { break; } } if (i == allowedValues.Count) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied + " Invalid enumeration."); } Asn1Integer ai = new Asn1Integer(i, Constraints.Min, Constraints.Max); ai.PerEncode(buffer); }
/// <summary> /// Encodes the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> public override void PerEncode(IAsn1PerEncodingBuffer buffer) { if (!VerifyConstraints()) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied); } long offset; if (Min == null) { Debug.Assert(Value != null, "Value != null"); offset = (long)Value; } else { offset = (long)(Value - Min); } //Ref. X.691: 10.5.2 if (Min == null || Max == null) //range is equal to null { if (offset == 0) { buffer.WriteByte(0); return; } //Ref. X.691: 10.3, 10.4 byte[] result; if (Min == null) { result = IntegerEncoding(offset); } else { //lowerBound != null && upperBound == null result = NonNegativeBinaryIntegerPerEncode(offset); } int len = result.Length; buffer.WriteByte((byte)len); buffer.WriteBytes(result); return; } else { //lowerBound != null && upperBound != null, range != null, offset should be non-negative //Ref. X.691: 10.5 if (Range == 1) { //X.691: 10.5.4 return; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } byte[] temp = new byte[] { (byte)offset }; buffer.WriteBits(temp, 8 - bitFieldSize, bitFieldSize); return; } else if (Range == 256) //10.5.7: b) { buffer.WriteByte((byte)offset); return; } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset);//Length is either be 1 or 2 if (bytes.Length == 1) { buffer.WriteByte(0); } buffer.WriteBytes(bytes); return; } else //10.5.7: d) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); Asn1Integer len = new Asn1Integer(bytes.Length, 1, 4); len.PerEncode(buffer); buffer.WriteBytes(bytes); return; } } }
/// <summary> /// Encodes an array of objects by PER. /// </summary> /// <typeparam name="T">The type of the objects.</typeparam> /// <param name="buffer">A buffer that will store the encoding result of the objects.</param> /// <param name="objs">The array of the objects.</param> /// <param name="encoder">A method that provide the functionality of encoding a single object.</param> /// <param name="minSize">Minimal size of the array.</param> /// <param name="maxSize">Maximal size of the array.</param> /// <param name="alignAfterEncodeLength">Indicates whether align after the length is encoded.</param> public static void PerEncodeArray <T>(IAsn1PerEncodingBuffer buffer, T[] objs, PerEncodeSingleObject <T> encoder, long?minSize = null, long?maxSize = null, bool alignAfterEncodeLength = false) { if (minSize == null && maxSize == null) { bool len16KMultiple = false; int len = objs.Length; if (len == 0) { buffer.WriteByte(0); return; } int curIndex = 0; while (curIndex != len) { int writeContentNum = 0; int rest = len - curIndex; if (rest < 128) //X.691: 10.9 a) { buffer.WriteByte((byte)rest); writeContentNum = rest; len16KMultiple = false; } else if (rest < 16 * 1024) //X.691: 10.9 b) 16K { buffer.WriteByte((byte)(128 | (rest >> 8))); buffer.WriteByte((byte)(rest & 255)); writeContentNum = rest; len16KMultiple = false; } else { int fragmentNum = rest / (16 * 1024);//number of 16K items, X.691: 10.9 c) if (fragmentNum > 4) { fragmentNum = 4; } buffer.WriteByte((byte)(192 + fragmentNum)); writeContentNum = fragmentNum * 16 * 1024; len16KMultiple = true; } for (int i = 0; i < writeContentNum; i++, curIndex++) { encoder(buffer, objs[curIndex]); } } if (len16KMultiple) { //throw new Asn1InvalidArgument("Objsys bug"); buffer.WriteByte(0); } } 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; } if (maxSize != minSize) //Ref. X.691: 16.8 { //Encode length Asn1Integer ai = new Asn1Integer(objs.Length, minSize, maxSize); ai.PerEncode(buffer); if (alignAfterEncodeLength) { buffer.AlignData(); } } foreach (T curObj in objs) { encoder(buffer, curObj); } } else { throw new NotImplementedException("Array with semi size constraints are not implemented yet."); } }
/// <summary> /// Encodes the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> public override void PerEncode(IAsn1PerEncodingBuffer buffer) { if (!VerifyConstraints()) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied); } long offset; if (Min == null) { Debug.Assert(Value != null, "Value != null"); offset = (long)Value; } else { offset = (long)(Value - Min); } //Ref. X.691: 10.5.2 if (Min == null || Max == null) //range is equal to null { if (offset == 0) { buffer.WriteByte(0); return; } //Ref. X.691: 10.3, 10.4 byte[] result; if (Min == null) { result = IntegerEncoding(offset); } else { //lowerBound != null && upperBound == null result = NonNegativeBinaryIntegerPerEncode(offset); } int len = result.Length; buffer.WriteByte((byte)len); buffer.WriteBytes(result); return; } else { //lowerBound != null && upperBound != null, range != null, offset should be non-negative //Ref. X.691: 10.5 if (Range == 1) { //X.691: 10.5.4 return; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } byte[] temp = new byte[] { (byte)offset }; buffer.WriteBits(temp, 8 - bitFieldSize, bitFieldSize); return; } else if (Range == 256) //10.5.7: b) { buffer.WriteByte((byte)offset); return; } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); //Length is either be 1 or 2 if (bytes.Length == 1) { buffer.WriteByte(0); } buffer.WriteBytes(bytes); return; } else //10.5.7: d) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); Asn1Integer len = new Asn1Integer(bytes.Length, 1, 4); len.PerEncode(buffer); buffer.WriteBytes(bytes); return; } } }
/// <summary> /// Encodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer) { int i = 0; for (; i < allowedValues.Count; i++) { if (allowedValues[i] == Value) { break; } } if (i == allowedValues.Count) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied + " Invalid enumeration."); } Asn1Integer ai = new Asn1Integer(i, Constraints.Min, Constraints.Max); ai.PerEncode(buffer); }
/// <summary> /// Encodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer) { long offset; if (Constraints == null || !Constraints.HasMin) { offset = (long)Value; } else { offset = (long)(Value - Constraints.Min); } //Ref. X.691: 10.5.2 if (Range == null) { if (offset == 0) { buffer.WriteByte(0); return; } //Ref. X.691: 10.3, 10.4 byte[] result; if (Constraints == null || !Constraints.HasMin) { result = IntegerEncoding(offset); } else { //lowerBound != null && upperBound == null result = NonNegativeBinaryIntegerPerEncode(offset); } int len = result.Length; buffer.WriteByte((byte)len); buffer.WriteBytes(result); return; } else { //lowerBound != null && upperBound != null, range != null, offset should be non-negative //Ref. X.691: 10.5 if (Range == 1) { //X.691: 10.5.4 return; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } byte[] temp = new byte[] { (byte)offset }; buffer.WriteBits(temp, 8 - bitFieldSize, bitFieldSize); return; } else if (Range == 256) //10.5.7: b) { buffer.WriteByte((byte)offset); return; } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset);//Length is either be 1 or 2 if (bytes.Length == 1) { buffer.WriteByte(0); } buffer.WriteBytes(bytes); return; } else //10.5.7: d) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); Asn1Integer len = new Asn1Integer(bytes.Length, 1, 4); len.PerEncode(buffer); buffer.WriteBytes(bytes); return; } } }
/// <summary> /// Encodes the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> public override void PerEncode(IAsn1PerEncodingBuffer buffer) { if (HasExternalObjects) { //TODO: write true to the buffer if external element is used and not within the extension root //Ref: X.691: 13.3 buffer.WriteBit(false); } int i = 0; for (; i < allowedValues.Count; i++) { if (allowedValues[i] == Value) { break; } } if (i == allowedValues.Count) { throw new Asn1ConstraintsNotSatisfied(ExceptionMessages.ConstraintsNotSatisfied + " Invalid enumeration."); } Asn1Integer ai = new Asn1Integer(i, Min, Max); ai.PerEncode(buffer); }
/// <summary> /// Encodes the content of the object by PER. /// </summary> /// <param name="buffer">A buffer to which the encoding result will be written.</param> protected override void ValuePerEncode(IAsn1PerEncodingBuffer buffer) { long offset; if (Constraints == null || !Constraints.HasMin) { offset = (long)Value; } else { offset = (long)(Value - Constraints.Min); } //Ref. X.691: 10.5.2 if (Range == null) { if (offset == 0) { buffer.WriteByte(0); return; } //Ref. X.691: 10.3, 10.4 byte[] result; if (Constraints == null || !Constraints.HasMin) { result = IntegerEncoding(offset); } else { //lowerBound != null && upperBound == null result = NonNegativeBinaryIntegerPerEncode(offset); } int len = result.Length; buffer.WriteByte((byte)len); buffer.WriteBytes(result); return; } else { //lowerBound != null && upperBound != null, range != null, offset should be non-negative //Ref. X.691: 10.5 if (Range == 1) { //X.691: 10.5.4 return; } else if (Range <= 255) //10.5.7: a) { int bitFieldSize = 1; while (Range > (1 << (bitFieldSize))) { bitFieldSize++; } byte[] temp = new byte[] { (byte)offset }; buffer.WriteBits(temp, 8 - bitFieldSize, bitFieldSize); return; } else if (Range == 256) //10.5.7: b) { buffer.WriteByte((byte)offset); return; } else if (Range <= 256 * 256) //10.5.7: c) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); //Length is either be 1 or 2 if (bytes.Length == 1) { buffer.WriteByte(0); } buffer.WriteBytes(bytes); return; } else //10.5.7: d) { byte[] bytes = NonNegativeBinaryIntegerPerEncode(offset); Asn1Integer len = new Asn1Integer(bytes.Length, 1, 4); len.PerEncode(buffer); buffer.WriteBytes(bytes); return; } } }