public static int EncodeReal(IBerOutput output, double value) { var size = 0; if (double.IsPositiveInfinity(value)) { output.WriteByte(0x40); // 01000000 Value is PLUS-INFINITY size = 1; } else if (double.IsNegativeInfinity(value)) // negative infinity { output.WriteByte(0x41); // 01000001 Value is MINUS-INFINITY size = 1; } else if (double.IsNaN(value)) { output.WriteByte(0x42); // 01000010 Value is NOT-A-NUMBER size = 1; } else { long longValue = DoubleToInt64Bits(value); if (longValue != 0) { long exponent = ((0x7FF0000000000000L & longValue) >> 52) - 1023; long mantissa = 0x000FFFFFFFFFFFFFL & longValue; mantissa |= 0x0010000000000000L; // set virtual delimeter // normalize mantissa (required by CER and DER) while ((mantissa & 0xFF) == 0) { mantissa >>= 8; } while ((mantissa & 0x01) == 0) { mantissa >>= 1; } int exponentLength = GetLongLength(exponent); Debug.Assert(exponentLength <= 3); byte preamble = 0x80; preamble |= (byte)(exponentLength - 1); if (((ulong)longValue & 0x8000000000000000UL) != 0) { preamble |= 0x40; // Sign } output.WriteByte(preamble); size++; size += EncodeLong(output, exponent, exponentLength); // signed exponent size += EncodeLong(output, mantissa, GetLongLength(mantissa, false)); // unsigned mantissa } } return(size); }
public static int EncodeLength(IBerOutput output, int value) { int size = 1; if (value == BerDefinitions.IndefiniteLength) { output.WriteByte(0x80); } else { if (value <= 0x7F) { output.WriteByte((byte)(value & 0x7F)); } else { int integerLength = GetIntegerLength((int)value); output.WriteByte((byte)(0x80 | integerLength)); size += EncodeInteger(output, (int)value, integerLength); } } return(size); }
public static int EncodeMultiByteInteger(IBerOutput output, uint value) { var size = 1; if ((value & 0xF0000000) != 0) // most significant 4 bits { output.WriteByte((byte)(0x80 | ((value >> 28) & 0x0F))); size++; } if ((value & 0xFFE00000) != 0) // most significant 11 bits { output.WriteByte((byte)(0x80 | ((value >> 21) & 0x7F))); size++; } if ((value & 0xFFFFC000) != 0) // most significant 18 bits { output.WriteByte((byte)(0x80 | ((value >> 14) & 0x7F))); size++; } if ((value & 0xFFFFFF80) != 0) // most significant 25 bits { output.WriteByte((byte)(0x80 | ((value >> 7) & 0x7F))); size++; } output.WriteByte((byte)(0x00 | ((value >> 0) & 0x7F))); return(size); }
// ==================================================================== // // Encode functions // all return the number of bytes in the // encoded result. // // ==================================================================== #region Encode Functions public static int EncodeTag(IBerOutput output, BerTag tag) { var number = tag.Number; var size = 1; tag.Preamble &= 0xE0; if (number < 0x1F) { output.WriteByte((byte)(tag.Preamble | (number & 0x1F))); } else { output.WriteByte((byte)(tag.Preamble | 0x1F)); size += EncodeMultiByteInteger(output, number); } return(size); }
public static int EncodeLong(IBerOutput output, long value, int length) { Debug.Assert(length > 0 && length <= 8); ulong qword = (ulong)value; int bits = length * 8; while (bits > 0) { bits -= 8; output.WriteByte((byte)((qword >> bits) & 0xFF)); } return(length); }
public static int EncodeInteger(IBerOutput output, int value, int length) { Debug.Assert(length > 0 && length <= 4); var dword = (uint)value; var bits = length * 8; while (bits > 0) { bits -= 8; output.WriteByte((byte)((dword >> bits) & 0xFF)); } return(length); }
public static int EncodeBoolean(IBerOutput output, bool value) { output.WriteByte((byte)(value ? 0xFF : 0)); return(1); }
public static int EncodeMultiByteLong(IBerOutput output, ulong value) { var size = 1; if ((value & 0x8000000000000000UL) != 0) // most significant 1 bits { output.WriteByte((byte)(0x80 | 1)); size++; } if ((value & 0xFF00000000000000UL) != 0) // most significant 8 bits { output.WriteByte((byte)(0x80 | ((value >> 56) & 0x7F))); size++; } if ((value & 0xFFFE000000000000UL) != 0) // most significant 15 bits { output.WriteByte((byte)(0x80 | ((value >> 49) & 0x7F))); size++; } if ((value & 0xFFFFFC0000000000UL) != 0) // most significant 22 bits { output.WriteByte((byte)(0x80 | ((value >> 42) & 0x7F))); size++; } if ((value & 0xFFFFFFF800000000UL) != 0) // most significant 29 bits { output.WriteByte((byte)(0x80 | ((value >> 35) & 0x7F))); size++; } if ((value & 0xFFFFFFFFF0000000UL) != 0) // most significant 36 bits { output.WriteByte((byte)(0x80 | ((value >> 28) & 0x7F))); size++; } if ((value & 0xFFFFFFFFFFE00000UL) != 0) // most significant 43 bits { output.WriteByte((byte)(0x80 | ((value >> 21) & 0x7F))); size++; } if ((value & 0xFFFFFFFFFFFFC000UL) != 0) // most significant 50 bits { output.WriteByte((byte)(0x80 | ((value >> 14) & 0x7F))); size++; } if ((value & 0xFFFFFFFFFFFFFF80UL) != 0) // most significant 57 bits { output.WriteByte((byte)(0x80 | ((value >> 7) & 0x7F))); size++; } output.WriteByte((byte)(0x00 | ((value >> 0) & 0x7F))); return(size); }
// ==================================================================== // // Encode functions // all return the number of bytes in the // encoded result. // // ==================================================================== public static int EncodeTag(IBerOutput output, BerTag tag) { var number = tag.Number; var size = 1; tag.Preamble &= 0xE0; if(number < 0x1F) { output.WriteByte((byte)(tag.Preamble | (number & 0x1F))); } else { output.WriteByte((byte)(tag.Preamble | 0x1F)); size += EncodeMultiByteInteger(output, number); } return size; }
public static int EncodeMultiByteLong(IBerOutput output, ulong value) { var size = 1; if((value & 0x8000000000000000UL) != 0) // most significant 1 bits { output.WriteByte((byte)(0x80 | 1)); size++; } if((value & 0xFF00000000000000UL) != 0) // most significant 8 bits { output.WriteByte((byte)(0x80 | ((value >> 56) & 0x7F))); size++; } if((value & 0xFFFE000000000000UL) != 0) // most significant 15 bits { output.WriteByte((byte)(0x80 | ((value >> 49) & 0x7F))); size++; } if((value & 0xFFFFFC0000000000UL) != 0) // most significant 22 bits { output.WriteByte((byte)(0x80 | ((value >> 42) & 0x7F))); size++; } if((value & 0xFFFFFFF800000000UL) != 0) // most significant 29 bits { output.WriteByte((byte)(0x80 | ((value >> 35) & 0x7F))); size++; } if((value & 0xFFFFFFFFF0000000UL) != 0) // most significant 36 bits { output.WriteByte((byte)(0x80 | ((value >> 28) & 0x7F))); size++; } if((value & 0xFFFFFFFFFFE00000UL) != 0) // most significant 43 bits { output.WriteByte((byte)(0x80 | ((value >> 21) & 0x7F))); size++; } if((value & 0xFFFFFFFFFFFFC000UL) != 0) // most significant 50 bits { output.WriteByte((byte)(0x80 | ((value >> 14) & 0x7F))); size++; } if((value & 0xFFFFFFFFFFFFFF80UL) != 0) // most significant 57 bits { output.WriteByte((byte)(0x80 | ((value >> 7) & 0x7F))); size++; } output.WriteByte((byte)(0x00 | ((value >> 0) & 0x7F))); return size; }
public static int EncodeReal(IBerOutput output, double value) { var size = 0; if(double.IsPositiveInfinity(value)) { output.WriteByte(0x40); // 01000000 Value is PLUS-INFINITY size = 1; } else if(double.IsNegativeInfinity(value)) // negative infinity { output.WriteByte(0x41); // 01000001 Value is MINUS-INFINITY size = 1; } else { long longValue = DoubleToInt64Bits(value); if(longValue != 0) { long exponent = ((0x7FF0000000000000L & longValue) >> 52) - 1023; long mantissa = 0x000FFFFFFFFFFFFFL & longValue; mantissa |= 0x0010000000000000L; // set virtual delimeter // normalize mantissa (required by CER and DER) while((mantissa & 0xFF) == 0) mantissa >>= 8; while((mantissa & 0x01) == 0) mantissa >>= 1; int exponentLength = GetLongLength(exponent); Debug.Assert(exponentLength <= 3); byte preamble = 0x80; preamble |= (byte)(exponentLength - 1); if(((ulong)longValue & 0x8000000000000000UL) != 0) preamble |= 0x40; // Sign output.WriteByte(preamble); size++; size += EncodeLong(output, exponent, exponentLength); // signed exponent size += EncodeLong(output, mantissa, GetLongLength(mantissa, false)); // unsigned mantissa } } return size; }
public static int EncodeMultiByteInteger(IBerOutput output, uint value) { var size = 1; if((value & 0xF0000000) != 0) // most significant 4 bits { output.WriteByte((byte)(0x80 | ((value >> 28) & 0x0F))); size++; } if((value & 0xFFE00000) != 0) // most significant 11 bits { output.WriteByte((byte)(0x80 | ((value >> 21) & 0x7F))); size++; } if((value & 0xFFFFC000) != 0) // most significant 18 bits { output.WriteByte((byte)(0x80 | ((value >> 14) & 0x7F))); size++; } if((value & 0xFFFFFF80) != 0) // most significant 25 bits { output.WriteByte((byte)(0x80 | ((value >> 7) & 0x7F))); size++; } output.WriteByte((byte)(0x00 | ((value >> 0) & 0x7F))); return size; }
public static int EncodeLong(IBerOutput output, long value, int length) { Debug.Assert(length > 0 && length <= 8); ulong qword = (ulong)value; int bits = length * 8; while(bits > 0) { bits -= 8; output.WriteByte((byte)((qword >> bits) & 0xFF)); } return length; }
public static int EncodeLength(IBerOutput output, int value) { int size = 1; if(value == BerDefinitions.IndefiniteLength) { output.WriteByte(0x80); } else { if(value <= 0x7F) { output.WriteByte((byte)(value & 0x7F)); } else { int integerLength = GetIntegerLength((int)value); output.WriteByte((byte)(0x80 | integerLength)); size += EncodeInteger(output, (int)value, integerLength); } } return size; }
public static int EncodeInteger(IBerOutput output, int value, int length) { Debug.Assert(length > 0 && length <= 4); var dword = (uint)value; var bits = length * 8; while(bits > 0) { bits -= 8; output.WriteByte((byte)((dword >> bits) & 0xFF)); } return length; }
// value encodings public static int EncodeBoolean(IBerOutput output, bool value) { output.WriteByte((byte)(value ? 0xFF : 0)); return 1; }