/// <summary> Encoding of a unconstrained whole number /// ITU-T X.691. 10.8. /// NOTE – (Tutorial) This case only arises in the encoding of the /// value of an integer type with no lower bound. The procedure /// encodes the value as a 2's-complement-binary-integer into /// the minimum number of octets required to accommodate the encoding, /// and requires an explicit length encoding (typically a single octet) /// as specified in later procedures. /// </summary> protected virtual int encodeUnconstraintNumber(long val, BitArrayOutputStream stream) { int result = 0; int intLen = CoderUtils.getIntegerLength(val); result += encodeLengthDeterminant(intLen, stream); doAlign(stream); result += encodeIntegerValueAsBytes(val, stream); return(result); }
/// <summary> /// Encoding of a semi-constrained whole number /// ITU-T X.691. 10.7. /// NOTE – (Tutorial) This procedure is used when a lower bound can be /// identified but not an upper bound. The encoding procedure places /// the offset from the lower bound into the minimum number of octets /// as a non-negative-binary-integer, and requires an explicit length /// encoding (typically a single octet) as specified in later procedures. /// </summary> protected virtual int encodeSemiConstraintNumber(int val, int min, BitArrayOutputStream stream) { int result = 0; int narrowedVal = val - min; int intLen = CoderUtils.getIntegerLength(narrowedVal); result += encodeLengthDeterminant(intLen, stream); doAlign(stream); result += encodeIntegerValueAsBytes(narrowedVal, stream); return(result); }
public override int encodeInteger(object obj, System.IO.Stream stream, ElementInfo elementInfo) { int result = 0; bool hasConstraint = false; long min = 0, max = 0; if (elementInfo.hasPreparedInfo()) { if (elementInfo.PreparedInfo.hasConstraint() && elementInfo.PreparedInfo.Constraint is ASN1ValueRangeConstraintMetadata) { IASN1ConstraintMetadata constraint = elementInfo.PreparedInfo.Constraint; hasConstraint = true; min = ((ASN1ValueRangeConstraintMetadata)constraint).Min; max = ((ASN1ValueRangeConstraintMetadata)constraint).Max; } } else if (elementInfo.isAttributePresent <ASN1ValueRangeConstraint>()) { hasConstraint = true; ASN1ValueRangeConstraint constraint = elementInfo.getAttribute <ASN1ValueRangeConstraint>(); min = constraint.Min; max = constraint.Max; } if (obj.GetType().Equals(typeof(int))) { int val = (int)obj; BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; if (hasConstraint) { result += encodeConstraintNumber(val, min, max, bitStream); } else { result += encodeUnconstraintNumber(val, bitStream); } } else { long val = (long)obj; BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; if (hasConstraint) { result += encodeConstraintNumber(val, min, max, bitStream); } else { result += encodeUnconstraintNumber(val, bitStream); } } return(result); }
protected int encodeLength(int val, ElementInfo elementInfo, System.IO.Stream stream) { CoderUtils.checkConstraints(val, elementInfo); int resultSize = 0; BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; if (elementInfo.hasPreparedInfo()) { if (elementInfo.PreparedInfo.hasConstraint()) { IASN1ConstraintMetadata constraint = elementInfo.PreparedInfo.Constraint; if (constraint is ASN1ValueRangeConstraintMetadata) { resultSize += encodeConstraintLengthDeterminant( val, (int)((ASN1ValueRangeConstraintMetadata)constraint).Min, (int)((ASN1ValueRangeConstraintMetadata)constraint).Max, bitStream ); } else if (constraint is ASN1SizeConstraintMetadata) { } } else { resultSize += encodeLengthDeterminant(val, bitStream); } } else { if (elementInfo.isAttributePresent <ASN1ValueRangeConstraint>()) { ASN1ValueRangeConstraint constraint = elementInfo.getAttribute <ASN1ValueRangeConstraint>(); resultSize += encodeConstraintLengthDeterminant(val, (int)constraint.Min, (int)constraint.Max, bitStream); } else if (elementInfo.isAttributePresent <ASN1SizeConstraint>()) { ASN1SizeConstraint constraint = elementInfo.getAttribute <ASN1SizeConstraint>(); } else { resultSize += encodeLengthDeterminant(val, bitStream); } } return(resultSize); }
/// <seealso cref="BitArrayOutputStream.write(int)"> /// </seealso> public virtual void testWrite() { BitArrayOutputStream stream = new BitArrayOutputStream(); stream.WriteByte(0xFF); stream.writeBit(true); stream.writeBit(false); stream.writeBit(true); stream.writeBit(false); stream.WriteByte(0xFF); stream.WriteByte(0x0F); stream.writeBit(true); stream.writeBit(true); stream.writeBit(true); stream.writeBit(true); System.Console.Out.WriteLine("Write " + ByteTools.byteArrayToHexString(stream.ToArray())); ByteTools.checkBuffers(stream.ToArray(), new byte[] { 0xFF, 0xAF, 0xF0, 0xFF }); stream.writeBit(true); stream.writeBit(false); stream.writeBit(true); stream.writeBit(false); byte[] temp_byteArray; temp_byteArray = new byte[] { (0xCC), (0xFF), (0xFF), (0xBB) }; stream.Write(temp_byteArray, 0, temp_byteArray.Length); System.Console.Out.WriteLine("After buf write " + ByteTools.byteArrayToHexString(stream.ToArray())); ByteTools.checkBuffers(stream.ToArray(), new byte[] { (0xFF), (0xAF), (0xF0), (0xFF), (0xAC), (0xCF), (0xFF), (0xFB), (0xB0) }); stream.align(); stream.writeBit(true); stream.writeBit(true); stream.align(); stream.WriteByte(0xFF); System.Console.Out.WriteLine("After align " + ByteTools.byteArrayToHexString(stream.ToArray())); ByteTools.checkBuffers(stream.ToArray(), new byte[] { (0xFF), (0xAF), (0xF0), (0xFF), (0xAC), (0xCF), (0xFF), (0xFB), (0xB0), (0xC0), (0xFF) }); }
public override int encodeBitString(Object obj, Stream stream, ElementInfo elementInfo) { /*NOTE – (Tutorial) Bitstrings constrained to a fixed length less than or equal to 16 bits do not cause octet alignment. Larger * bitstrings are octet-aligned in the ALIGNED variant. If the length is fixed by constraints and the upper bound is less than 64K, * there is no explicit length encoding, otherwise a length encoding is included which can take any of the forms specified earlier for * length encodings, including fragmentation for large bit strings.*/ int resultSize = 0, sizeOfString = 0; BitString str = (BitString)obj; byte[] buffer = str.Value; sizeOfString = str.getLengthInBits(); // buffer.Length*8 - str.TrailBitsCnt; resultSize += encodeLength(sizeOfString, elementInfo, stream); doAlign(stream); BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; if (sizeOfString > 0) { //doAlign(stream); if (str.TrailBitsCnt == 0) { stream.Write(buffer, 0, buffer.Length); } else { bitStream.Write(buffer, 0, buffer.Length - 1); for (int i = 0; i < str.TrailBitsCnt; i++) { int bitValue = (buffer[buffer.Length - 1] >> (7 - i)) & 0x1; bitStream.writeBit(bitValue); } } } return(resultSize); }
/// <summary> /// Encoding constraint length determinant procedure. /// ITU-T X.691. 10.9. General rules for encoding a length determinant /// </summary> protected virtual int encodeConstraintLengthDeterminant(int length, int min, int max, BitArrayOutputStream stream) { if (max <= 0xFFFF) { // 10.9. NOTE 2 – (Tutorial) In the case of the ALIGNED variant // if the length count is bounded above by an upper bound that is // less than 64K, then the constrained whole number encoding // is used for the length. return(encodeConstraintNumber(length, min, max, stream)); // encoding as constraint integer } else { return(encodeLengthDeterminant(length, stream)); } }
public override int encodeReal(object obj, Stream stream, ElementInfo elementInfo) { int result = 0; BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; Double value = (Double)obj; //CoderUtils.checkConstraints(value,elementInfo); #if PocketPC byte[] dblValAsBytes = System.BitConverter.GetBytes(value); long asLong = System.BitConverter.ToInt64(dblValAsBytes, 0); #else long asLong = BitConverter.DoubleToInt64Bits(value); #endif if (value == Double.PositiveInfinity) { // positive infinity result += encodeLengthDeterminant(1, bitStream); doAlign(stream); stream.WriteByte(0x40); // 01000000 Value is PLUS-INFINITY result += 1; } else if (value == Double.NegativeInfinity) { // negative infinity result += encodeLengthDeterminant(1, bitStream); doAlign(stream); stream.WriteByte(0x41); // 01000001 Value is MINUS-INFINITY result += 1; } else if (asLong != 0x0) { long exponent = ((0x7ff0000000000000L & asLong) >> 52) - 1023 - 52; long mantissa = 0x000fffffffffffffL & asLong; mantissa |= 0x10000000000000L; // set virtual delimiter // pack mantissa for base 2 while ((mantissa & 0xFFL) == 0x0) { mantissa >>= 8; exponent += 8; //increment exponent to 8 (base 2) } while ((mantissa & 0x01L) == 0x0) { mantissa >>= 1; exponent += 1; //increment exponent to 1 } int szOfExp = CoderUtils.getIntegerLength(exponent); encodeLengthDeterminant(CoderUtils.getIntegerLength(mantissa) + szOfExp + 1, bitStream); doAlign(stream); byte realPreamble = 0x80; realPreamble |= (byte)(szOfExp - 1); if ((((ulong)asLong) & 0x8000000000000000L) == 1) { realPreamble |= 0x40; // Sign } stream.WriteByte(realPreamble); result += 1; result += encodeIntegerValueAsBytes(exponent, stream); result += encodeIntegerValueAsBytes(mantissa, stream); } return(result); }