/// <summary> /// Encode normally small number /// ITU-T X.691. 10.6 /// NOTE – (Tutorial) This procedure is used when encoding /// a non-negative whole number that is expected to be small, but whose size /// is potentially unlimited due to the presence of an extension marker. /// An example is a choice index. /// </summary> protected virtual int encodeNormallySmallNumber(int val, BitArrayOutputStream stream) { int result = 0; if (val > 0 && val < 64) { /* 10.6.1 If the non-negative whole number, "n", is less than * or equal to 63, then a single-bit bit-field shall be appended * to the field-list with the bit set to 0, and "n" shall be * encoded as a non-negative-binary-integer into a 6-bit bit-field. */ stream.writeBit(0); for (int i = 0; i < 6; i++) { int bitValue = (val >> 6 - i) & 0x1; stream.writeBit(bitValue); } result = 1; } else { /* If "n" is greater than or equal to 64, a single-bit * bit-field with the bit set to 1 shall be appended to the field-list. * The value "n" shall then be encoded as a semi-constrained * whole number with "lb" equal to 0 and the procedures of * 10.9 shall be invoked to add it to the field-list preceded * by a length determinant. */ stream.writeBit(1); result += encodeSemiConstraintNumber(val, 0, stream); } return(result); }
protected override int encodeConstraintNumber(long val, long min, long max, BitArrayOutputStream stream) { int result = 0; long valueRange = max - min; long narrowedVal = val - min; int maxBitLen = PERCoderUtils.getMaxBitLength(valueRange); if (valueRange == 0) { return(result); } //For the UNALIGNED variant the value is always encoded in the minimum // number of bits necessary to represent the range (defined in 10.5.3). int currentBit = maxBitLen; while (currentBit > 8) { currentBit -= 8; result++; stream.WriteByte((byte)(narrowedVal >> currentBit)); } if (currentBit > 0) { for (int i = currentBit - 1; i >= 0; i--) { int bitValue = (int)((narrowedVal >> i) & 0x1); stream.writeBit(bitValue); } result += 1; } return(result); }
public override int encodeBoolean(object obj, Stream stream, ElementInfo elementInfo) { int resultSize = 1; BitArrayOutputStream bitStream = (BitArrayOutputStream)stream; bitStream.writeBit((Boolean)obj); return(resultSize); }
/// <summary> /// Encoding of a constrained whole number /// ITU-T X.691. 10.5. /// NOTE – (Tutorial) This subclause is referenced by other clauses, /// and itself references earlier clauses for the production of /// a nonnegative-binary-integer or a 2's-complement-binary-integer encoding. /// </summary> protected virtual int encodeConstraintNumber(long val, long min, long max, BitArrayOutputStream stream) { int result = 0; long valueRange = max - min; long narrowedVal = val - min; int maxBitLen = PERCoderUtils.getMaxBitLength(valueRange); if (valueRange == 0) { return(result); } // The rest of this Note addresses the ALIGNED variant. if (valueRange > 0 && valueRange < 256) { /* * 1. Where the range is less than or equal to 255, the value encodes * into a bit-field of the minimum size for the range. * 2. Where the range is exactly 256, the value encodes * into a single octet octet-aligned bit-field. */ doAlign(stream); for (int i = maxBitLen - 1; i >= 0; i--) { int bitValue = (int)((narrowedVal >> i) & 0x1); stream.writeBit(bitValue); } result = 1; } else if (valueRange > 0 && valueRange < 65536) { /* * 3. Where the range is 257 to 64K, the value encodes into * a two octet octet-aligned bit-field. */ doAlign(stream); stream.WriteByte((byte)(narrowedVal >> 8)); stream.WriteByte((byte)(narrowedVal & 0xFF)); result = 2; } else { /* * 4. Where the range is greater than 64K, the range is ignored * and the value encodes into an octet-aligned bit-field * which is the minimum number of octets for the value. * In this latter case, later procedures (see 10.9) * also encode a length field (usually a single octet) to indicate * the length of the encoding. For the other cases, the length * of the encoding is independent of the value being encoded, * and is not explicitly encoded. */ result = encodeConstraintLengthDeterminant(CoderUtils.getIntegerLength(narrowedVal), 1, CoderUtils.getPositiveIntegerLength(valueRange), stream); doAlign(stream); result += encodeIntegerValueAsBytes(narrowedVal, stream); } return(result); }
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); }
/// <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) }); }