/// <summary> /// Parses <see cref="RadiusPacket"/> object by parsing the specified <paramref name="buffer"/> containing a binary image. /// </summary> /// <param name="buffer">Buffer containing binary image to parse.</param> /// <param name="startIndex">0-based starting index in the <paramref name="buffer"/> to start parsing.</param> /// <param name="length">Valid number of bytes within <paramref name="buffer"/> from <paramref name="startIndex"/>.</param> /// <returns>The number of bytes used for initialization in the <paramref name="buffer"/> (i.e., the number of bytes parsed), or 0 if not enough data.</returns> /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception> public int ParseBinaryImage(byte[] buffer, int startIndex, int length) { if ((object)buffer == null) { throw new ArgumentNullException("buffer"); } int imageLength = BinaryLength; if (length >= imageLength) { // Binary image has sufficient data. UInt16 size; m_type = (PacketType)(buffer[startIndex]); m_identifier = buffer[startIndex + 1]; size = EndianOrder.ToUInt16(buffer, startIndex + 2); Buffer.BlockCopy(buffer, startIndex + 4, m_authenticator, 0, m_authenticator.Length); // Parse all attributes in the packet. int cursor = 20; while (cursor < size) { RadiusPacketAttribute attribute = new RadiusPacketAttribute(buffer, startIndex + cursor, length); m_attributes.Add(attribute); cursor += attribute.BinaryLength; } return(imageLength); } // Binary image does not have sufficient data. return(0); }
/// <summary> /// Initializes a new instance of the <see cref="TcpSimpleClient"/> class. /// </summary> /// <param name="connectString">Connect string of the <see cref="TcpSimpleClient"/>. See <see cref="DefaultConnectionString"/> for format.</param> public TcpSimpleClient(string connectString) : base(TransportProtocol.Tcp, connectString) { m_tcpClient = new TcpClientProvider(); PayloadAware = DefaultPayloadAware; m_payloadMarker = Payload.DefaultMarker; m_payloadEndianOrder = EndianOrder.LittleEndian; NoDelay = DefaultNoDelay; }
public static byte[] InternalToByteArray(this ushort value, EndianOrder order) { var bytes = BitConverter.GetBytes(value); if (!order.IsHostOrder()) { Array.Reverse(bytes); } return(bytes); }
/// <summary> /// Determines the length of a payload in a "Payload-Aware" transmission from the payload header information. /// </summary> /// <param name="buffer">The buffer containing payload header information starting at index zero.</param> /// <param name="length">The length of valid data within in <paramref name="buffer"/>.</param> /// <param name="marker">The byte sequence used to mark the beginning of the payload in a "Payload-Aware" transmissions.</param> /// <param name="endianOrder">The endian order to apply to payload size decoding.</param> /// <returns>Length of the payload.</returns> public static int ExtractLength(byte[] buffer, int length, byte[] marker, EndianOrder endianOrder) { // Check to see if buffer is at least as big as the payload header if (length < marker.Length + LengthSegment) { return(-1); } // Check to see if buffer has the payload marker return(!HasHeader(buffer, marker) ? 0 : endianOrder.ToInt32(buffer, marker.Length)); }
/// <summary> /// Generates a binary representation of this <see cref="RadiusPacket"/> object and copies it into the given buffer. /// </summary> /// <param name="buffer">Buffer used to hold generated binary image of the source object.</param> /// <param name="startIndex">0-based starting index in the <paramref name="buffer"/> to start writing.</param> /// <returns>The number of bytes written to the <paramref name="buffer"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> or <see cref="ISupportBinaryImage.BinaryLength"/> is less than 0 -or- /// <paramref name="startIndex"/> and <see cref="ISupportBinaryImage.BinaryLength"/> will exceed <paramref name="buffer"/> length. /// </exception> public int GenerateBinaryImage(byte[] buffer, int startIndex) { int length = BinaryLength; buffer.ValidateParameters(startIndex, length); // Populate the buffer buffer[startIndex] = Convert.ToByte(m_type); buffer[startIndex + 1] = m_identifier; Buffer.BlockCopy(EndianOrder.GetBytes((ushort)BinaryLength), 0, buffer, startIndex + 2, 2); Buffer.BlockCopy(m_authenticator, 0, buffer, startIndex + 4, m_authenticator.Length); startIndex += 20; foreach (RadiusPacketAttribute attribute in m_attributes) { if (attribute != null) { startIndex += attribute.GenerateBinaryImage(buffer, startIndex); } } return(length); }
public EndianAttribute(EndianOrder byteOrder) { this.ByteOrder = byteOrder; }
/// <summary> /// 判断大小端 /// </summary> /// <param name="order"></param> /// <returns></returns> public static bool IsHostOrder(this EndianOrder order) { return(!(BitConverter.IsLittleEndian ^ (order == EndianOrder.Little))); }
static EndianOrder() { BigEndian = new EndianOrder(Endianness.BigEndian); LittleEndian = new EndianOrder(Endianness.LittleEndian); }
/// <summary> /// Adds header containing the <paramref name="marker"/> to the payload in the <paramref name="buffer"/> for "Payload-Aware" transmission. /// </summary> /// <param name="buffer">The buffer containing the payload.</param> /// <param name="offset">The offset in the <paramref name="buffer"/> at which the payload starts.</param> /// <param name="length">The length of the payload in the <paramref name="buffer"/> starting at the <paramref name="offset"/>.</param> /// <param name="marker">The byte sequence used to mark the beginning of the payload in a "Payload-Aware" transmissions.</param> /// <param name="endianOrder">The endian order to apply to payload size encoding.</param> public static void AddHeader(ref byte[] buffer, ref int offset, ref int length, byte[] marker, EndianOrder endianOrder) { // Note that the resulting buffer will be at least 4 bytes bigger than the payload // Resulting buffer = x bytes for payload marker + 4 bytes for the payload size + The payload byte[] result = new byte[length + marker.Length + LengthSegment]; // First, copy the payload marker to the buffer, if any if (marker.Length > 0) { Buffer.BlockCopy(marker, 0, result, 0, marker.Length); } // Then, copy the payload's size to the buffer after the payload marker Buffer.BlockCopy(endianOrder.GetBytes(length), 0, result, marker.Length, LengthSegment); // At last, copy the payload after the payload marker and payload size Buffer.BlockCopy(buffer, offset, result, marker.Length + LengthSegment, length); buffer = result; offset = 0; length = buffer.Length; }