* Rewrote the Header class as a struct and optimize for speed. This shouldn't be a breaking change for most apps, but GridProxy and WinGridProxy will need to be tested as thoroughly as possible. Important to note is that Packet.Header.AckList can be null now
* 404 checking in SeedRequestCompleteHandler * A few new big endian conversion methods in Utils git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@2709 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
@@ -389,29 +389,6 @@ namespace mapgenerator
|
||||
}
|
||||
|
||||
writer.WriteLine(" }" + Environment.NewLine);
|
||||
|
||||
// ToString() function
|
||||
/*writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" StringBuilder output = new StringBuilder();");
|
||||
writer.WriteLine(" output.AppendLine(\"-- " + block.Name + " --\");");
|
||||
|
||||
for (int i = 0; i < block.Fields.Count; i++)
|
||||
{
|
||||
MapField field = block.Fields[i];
|
||||
|
||||
if (field.Type == FieldType.Variable || field.Type == FieldType.Fixed)
|
||||
{
|
||||
writer.WriteLine(" Helpers.FieldToString(output, " + field.Name + ", \"" + field.Name + "\");");
|
||||
if (i != block.Fields.Count - 1) writer.WriteLine(" output.Append(Environment.NewLine);");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i != block.Fields.Count - 1) writer.WriteLine(" output.AppendLine(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));");
|
||||
else writer.WriteLine(" output.Append(String.Format(\"" + field.Name + ": {0}\", " + field.Name + "));");
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine(" return output.ToString();" + Environment.NewLine + " }");*/
|
||||
writer.WriteLine(" }" + Environment.NewLine);
|
||||
}
|
||||
|
||||
@@ -429,11 +406,6 @@ namespace mapgenerator
|
||||
WriteBlockClass(writer, block, packet);
|
||||
}
|
||||
|
||||
// Header member
|
||||
writer.WriteLine(" private Header header;");
|
||||
//writer.WriteLine(" /// <summary>The header for this packet</summary>");
|
||||
writer.WriteLine(" public override Header Header { get { return header; } set { header = value; } }");
|
||||
|
||||
// PacketType member
|
||||
//writer.WriteLine(" /// <summary>Will return PacketType." + packet.Name+ "</summary>");
|
||||
writer.WriteLine(" public override PacketType Type { get { return PacketType." +
|
||||
@@ -488,7 +460,8 @@ namespace mapgenerator
|
||||
// Default constructor
|
||||
//writer.WriteLine(" /// <summary>Default constructor</summary>");
|
||||
writer.WriteLine(" public " + packet.Name + "Packet()" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" Header = new " + packet.Frequency.ToString() + "Header();");
|
||||
writer.WriteLine(" Header = new Header();");
|
||||
writer.WriteLine(" Header.Frequency = PacketFrequency." + packet.Frequency + ";");
|
||||
writer.WriteLine(" Header.ID = " + packet.ID + ";");
|
||||
writer.WriteLine(" Header.Reliable = true;"); // Turn the reliable flag on by default
|
||||
if (packet.Encoded) { writer.WriteLine(" Header.Zerocoded = true;"); }
|
||||
@@ -525,8 +498,8 @@ namespace mapgenerator
|
||||
" }" + Environment.NewLine);
|
||||
|
||||
writer.WriteLine(" override public void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" header.FromBytes(bytes, ref i, ref packetEnd);");
|
||||
writer.WriteLine(" if (header.Zerocoded && zeroBuffer != null)");
|
||||
writer.WriteLine(" Header.FromBytes(bytes, ref i, ref packetEnd);");
|
||||
writer.WriteLine(" if (Header.Zerocoded && zeroBuffer != null)");
|
||||
writer.WriteLine(" {");
|
||||
writer.WriteLine(" packetEnd = Helpers.ZeroDecode(bytes, packetEnd + 1, zeroBuffer) - 1;");
|
||||
writer.WriteLine(" bytes = zeroBuffer;");
|
||||
@@ -673,10 +646,10 @@ namespace mapgenerator
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine(" if (header.AckList.Length > 0) { length += header.AckList.Length * 4 + 1; }");
|
||||
writer.WriteLine(" if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; }");
|
||||
writer.WriteLine(" byte[] bytes = new byte[length];");
|
||||
writer.WriteLine(" int i = 0;");
|
||||
writer.WriteLine(" header.ToBytes(bytes, ref i);");
|
||||
writer.WriteLine(" Header.ToBytes(bytes, ref i);");
|
||||
foreach (MapBlock block in packet.Blocks)
|
||||
{
|
||||
if (block.Name == "Header") { sanitizedName = "_" + block.Name; }
|
||||
@@ -701,43 +674,9 @@ namespace mapgenerator
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine(" if (header.AckList.Length > 0) { header.AcksToBytes(bytes, ref i); }");
|
||||
writer.WriteLine(" if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); }");
|
||||
writer.WriteLine(" return bytes;" + Environment.NewLine + " }" + Environment.NewLine);
|
||||
|
||||
// ToString() function
|
||||
//writer.WriteLine(" /// <summary>Serialize this packet to a string</summary><returns>A string containing the serialized packet</returns>");
|
||||
/*writer.WriteLine(" public override string ToString()" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" string output = \"--- " + packet.Name + " ---\" + Environment.NewLine;");
|
||||
|
||||
foreach (MapBlock block in packet.Blocks)
|
||||
{
|
||||
if (block.Name == "Header") { sanitizedName = "_" + block.Name; }
|
||||
else { sanitizedName = block.Name; }
|
||||
|
||||
if (block.Count == -1)
|
||||
{
|
||||
// Variable count block
|
||||
writer.WriteLine(" for (int j = 0; j < " +
|
||||
sanitizedName + ".Length; j++)" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" output += " + sanitizedName +
|
||||
"[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }");
|
||||
}
|
||||
else if (block.Count == 1)
|
||||
{
|
||||
writer.WriteLine(" output += " + sanitizedName + ".ToString() + Environment.NewLine;");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple count block
|
||||
writer.WriteLine(" for (int j = 0; j < " +
|
||||
block.Count + "; j++)" + Environment.NewLine + " {");
|
||||
writer.WriteLine(" output += " + sanitizedName +
|
||||
"[j].ToString() + Environment.NewLine;" + Environment.NewLine + " }");
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine(" return output;" + Environment.NewLine + " }" + Environment.NewLine);*/
|
||||
|
||||
writer.WriteLine(" }" + Environment.NewLine);
|
||||
}
|
||||
|
||||
@@ -821,7 +760,7 @@ namespace mapgenerator
|
||||
// Write the base Packet class
|
||||
writer.WriteLine(
|
||||
" public abstract partial class Packet" + Environment.NewLine + " {" + Environment.NewLine +
|
||||
" public abstract Header Header { get; set; }" + Environment.NewLine +
|
||||
" public Header Header;" + Environment.NewLine +
|
||||
" public abstract PacketType Type { get; }" + Environment.NewLine +
|
||||
" public abstract int Length { get; }" + Environment.NewLine +
|
||||
" public abstract void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer);" + Environment.NewLine +
|
||||
@@ -873,53 +812,60 @@ namespace mapgenerator
|
||||
if (packet != null)
|
||||
writer.WriteLine(" if(type == PacketType." + packet.Name + ") return new " + packet.Name + "Packet();");
|
||||
writer.WriteLine(" return null;" + Environment.NewLine);
|
||||
writer.WriteLine(" }" + Environment.NewLine);
|
||||
writer.WriteLine(" }");
|
||||
|
||||
// Write the Packet.BuildPacket() function
|
||||
writer.WriteLine(
|
||||
" public static Packet BuildPacket(byte[] packetBuffer, ref int packetEnd, byte[] zeroBuffer)" + Environment.NewLine +
|
||||
" {" + Environment.NewLine +
|
||||
" byte[] bytes; ushort id; PacketFrequency freq;" + Environment.NewLine +
|
||||
" int i = 0;" + Environment.NewLine +
|
||||
" Header header = Header.BuildHeader(packetBuffer, ref i, ref packetEnd);" + Environment.NewLine +
|
||||
" if (header.Zerocoded)" + Environment.NewLine +
|
||||
" {" + Environment.NewLine +
|
||||
" packetEnd = Helpers.ZeroDecode(packetBuffer, packetEnd + 1, zeroBuffer) - 1;" + Environment.NewLine +
|
||||
" bytes = zeroBuffer;" + Environment.NewLine +
|
||||
" }" + Environment.NewLine +
|
||||
" else" + Environment.NewLine +
|
||||
" {" + Environment.NewLine +
|
||||
" bytes = packetBuffer;" + Environment.NewLine +
|
||||
" }" + Environment.NewLine +
|
||||
" Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1);" + Environment.NewLine + Environment.NewLine +
|
||||
" if (bytes[6] == 0xFF)" + Environment.NewLine +
|
||||
" {" + Environment.NewLine +
|
||||
" if (bytes[7] == 0xFF)" + Environment.NewLine +
|
||||
" {" + Environment.NewLine +
|
||||
" id = (ushort)((bytes[8] << 8) + bytes[9]); freq = PacketFrequency.Low;" + Environment.NewLine +
|
||||
" switch (id)" + Environment.NewLine +
|
||||
" {");
|
||||
writer.WriteLine(@"
|
||||
public static Packet BuildPacket(byte[] packetBuffer, ref int packetEnd, byte[] zeroBuffer)
|
||||
{
|
||||
byte[] bytes; ushort id; PacketFrequency freq;
|
||||
int i = 0;
|
||||
Header header = Header.BuildHeader(packetBuffer, ref i, ref packetEnd);
|
||||
if (header.Zerocoded)
|
||||
{
|
||||
packetEnd = Helpers.ZeroDecode(packetBuffer, packetEnd + 1, zeroBuffer) - 1;
|
||||
bytes = zeroBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = packetBuffer;
|
||||
}
|
||||
Array.Clear(bytes, packetEnd + 1, bytes.Length - packetEnd - 1);
|
||||
|
||||
switch (header.Frequency)
|
||||
{
|
||||
case PacketFrequency.Low:
|
||||
switch (header.ID)
|
||||
{");
|
||||
foreach (MapPacket packet in protocol.LowMaps)
|
||||
if (packet != null)
|
||||
writer.WriteLine(" case " + packet.ID + ": return new " + packet.Name + "Packet(header, bytes, ref i);");
|
||||
writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine +
|
||||
" else" + Environment.NewLine +
|
||||
" {" + Environment.NewLine + " id = (ushort)bytes[7]; freq = PacketFrequency.Medium;" + Environment.NewLine +
|
||||
" switch (id)" + Environment.NewLine + " {");
|
||||
writer.WriteLine(@"
|
||||
}
|
||||
break;
|
||||
case PacketFrequency.Medium:
|
||||
switch (header.ID)
|
||||
{");
|
||||
foreach (MapPacket packet in protocol.MediumMaps)
|
||||
if (packet != null)
|
||||
writer.WriteLine(" case " + packet.ID + ": return new " + packet.Name + "Packet(header, bytes, ref i);");
|
||||
writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine +
|
||||
" else" + Environment.NewLine + " {" + Environment.NewLine +
|
||||
" id = (ushort)bytes[6]; freq = PacketFrequency.High;" + Environment.NewLine +
|
||||
" switch (id)" + Environment.NewLine + " {");
|
||||
writer.WriteLine(@"
|
||||
}
|
||||
break;
|
||||
case PacketFrequency.High:
|
||||
switch (header.ID)
|
||||
{");
|
||||
foreach (MapPacket packet in protocol.HighMaps)
|
||||
if (packet != null)
|
||||
writer.WriteLine(" case " + packet.ID + ": return new " + packet.Name + "Packet(header, bytes, ref i);");
|
||||
writer.WriteLine(" }" + Environment.NewLine + " }" + Environment.NewLine + Environment.NewLine +
|
||||
" throw new MalformedDataException(\"Unknown packet ID \"+freq+\" \"+id);" + Environment.NewLine +
|
||||
" }" + Environment.NewLine + " }" + Environment.NewLine);
|
||||
writer.WriteLine(@"
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
throw new MalformedDataException(""Unknown packet ID "" + header.Frequency + "" "" + header.ID);
|
||||
}
|
||||
}");
|
||||
|
||||
// Write the packet classes
|
||||
foreach (MapPacket packet in protocol.LowMaps)
|
||||
|
||||
@@ -52,69 +52,65 @@ namespace OpenMetaverse.Packets
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The header of a message template packet. Either 5, 6, or 8 bytes in
|
||||
/// length at the beginning of the packet, and encapsulates any
|
||||
/// appended ACKs at the end of the packet as well
|
||||
/// The header of a message template packet. Holds packet flags, sequence
|
||||
/// number, packet ID, and any ACKs that will be appended at the end of
|
||||
/// the packet
|
||||
/// </summary>
|
||||
public abstract class Header
|
||||
public struct Header
|
||||
{
|
||||
/// <summary>Raw header data, does not include appended ACKs</summary>
|
||||
public byte[] Data;
|
||||
/// <summary>Raw value of the flags byte</summary>
|
||||
public byte Flags
|
||||
{
|
||||
get { return Data[0]; }
|
||||
set { Data[0] = value; }
|
||||
}
|
||||
/// <summary>Reliable flag, whether this packet requires an ACK</summary>
|
||||
public bool Reliable
|
||||
{
|
||||
get { return (Data[0] & Helpers.MSG_RELIABLE) != 0; }
|
||||
set { if (value) { Data[0] |= (byte)Helpers.MSG_RELIABLE; } else { byte mask = (byte)Helpers.MSG_RELIABLE ^ 0xFF; Data[0] &= mask; } }
|
||||
}
|
||||
/// <summary>Resent flag, whether this same packet has already been
|
||||
/// sent</summary>
|
||||
public bool Resent
|
||||
{
|
||||
get { return (Data[0] & Helpers.MSG_RESENT) != 0; }
|
||||
set { if (value) { Data[0] |= (byte)Helpers.MSG_RESENT; } else { byte mask = (byte)Helpers.MSG_RESENT ^ 0xFF; Data[0] &= mask; } }
|
||||
}
|
||||
/// <summary>Zerocoded flag, whether this packet is compressed with
|
||||
/// zerocoding</summary>
|
||||
public bool Zerocoded
|
||||
{
|
||||
get { return (Data[0] & Helpers.MSG_ZEROCODED) != 0; }
|
||||
set { if (value) { Data[0] |= (byte)Helpers.MSG_ZEROCODED; } else { byte mask = (byte)Helpers.MSG_ZEROCODED ^ 0xFF; Data[0] &= mask; } }
|
||||
}
|
||||
/// <summary>Appended ACKs flag, whether this packet has ACKs appended
|
||||
/// to the end</summary>
|
||||
public bool AppendedAcks
|
||||
{
|
||||
get { return (Data[0] & Helpers.MSG_APPENDED_ACKS) != 0; }
|
||||
set { if (value) { Data[0] |= (byte)Helpers.MSG_APPENDED_ACKS; } else { byte mask = (byte)Helpers.MSG_APPENDED_ACKS ^ 0xFF; Data[0] &= mask; } }
|
||||
}
|
||||
/// <summary>Packet sequence number</summary>
|
||||
public uint Sequence
|
||||
{
|
||||
get { return (uint)((Data[1] << 24) + (Data[2] << 16) + (Data[3] << 8) + Data[4]); }
|
||||
set
|
||||
{
|
||||
Data[1] = (byte)(value >> 24); Data[2] = (byte)(value >> 16);
|
||||
Data[3] = (byte)(value >> 8); Data[4] = (byte)(value % 256);
|
||||
}
|
||||
}
|
||||
/// <summary>Numeric ID number of this packet</summary>
|
||||
public abstract ushort ID { get; set; }
|
||||
/// <summary>Frequency classification of this packet, Low Medium or
|
||||
/// High</summary>
|
||||
public abstract PacketFrequency Frequency { get; }
|
||||
/// <summary>Convert this header to a byte array, not including any
|
||||
/// appended ACKs</summary>
|
||||
public abstract void ToBytes(byte[] bytes, ref int i);
|
||||
/// <summary>Array containing all the appended ACKs of this packet</summary>
|
||||
public bool Reliable;
|
||||
public bool Resent;
|
||||
public bool Zerocoded;
|
||||
public bool AppendedAcks;
|
||||
public uint Sequence;
|
||||
public ushort ID;
|
||||
public PacketFrequency Frequency;
|
||||
public uint[] AckList;
|
||||
|
||||
public abstract void FromBytes(byte[] bytes, ref int pos, ref int packetEnd);
|
||||
public void ToBytes(byte[] bytes, ref int i)
|
||||
{
|
||||
byte flags = 0;
|
||||
if (Reliable) flags |= Helpers.MSG_RELIABLE;
|
||||
if (Resent) flags |= Helpers.MSG_RESENT;
|
||||
if (Zerocoded) flags |= Helpers.MSG_ZEROCODED;
|
||||
if (AppendedAcks) flags |= Helpers.MSG_APPENDED_ACKS;
|
||||
|
||||
// Flags
|
||||
bytes[i++] = flags;
|
||||
|
||||
// Sequence number
|
||||
Utils.UIntToBytesBig(Sequence, bytes, i);
|
||||
i += 4;
|
||||
|
||||
// Extra byte
|
||||
bytes[i++] = 0;
|
||||
|
||||
// Packet ID
|
||||
switch (Frequency)
|
||||
{
|
||||
case PacketFrequency.High:
|
||||
// 1 byte ID
|
||||
bytes[i++] = (byte)ID;
|
||||
break;
|
||||
case PacketFrequency.Medium:
|
||||
// 2 byte ID
|
||||
bytes[i++] = 0xFF;
|
||||
bytes[i++] = (byte)ID;
|
||||
break;
|
||||
case PacketFrequency.Low:
|
||||
// 4 byte ID
|
||||
bytes[i++] = 0xFF;
|
||||
bytes[i++] = 0xFF;
|
||||
Utils.UInt16ToBytesBig(ID, bytes, i);
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void FromBytes(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
this = BuildHeader(bytes, ref pos, ref packetEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the AckList to a byte array, used for packet serializing
|
||||
@@ -126,10 +122,8 @@ namespace OpenMetaverse.Packets
|
||||
{
|
||||
foreach (uint ack in AckList)
|
||||
{
|
||||
bytes[i++] = (byte)((ack >> 24) % 256);
|
||||
bytes[i++] = (byte)((ack >> 16) % 256);
|
||||
bytes[i++] = (byte)((ack >> 8) % 256);
|
||||
bytes[i++] = (byte)(ack % 256);
|
||||
Utils.UIntToBytesBig(ack, bytes, i);
|
||||
i += 4;
|
||||
}
|
||||
if (AckList.Length > 0) { bytes[i++] = (byte)AckList.Length; }
|
||||
}
|
||||
@@ -143,21 +137,48 @@ namespace OpenMetaverse.Packets
|
||||
/// <returns></returns>
|
||||
public static Header BuildHeader(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
if (bytes[6] == 0xFF)
|
||||
Header header;
|
||||
byte flags = bytes[pos];
|
||||
|
||||
header.AppendedAcks = (flags & Helpers.MSG_APPENDED_ACKS) != 0;
|
||||
header.Reliable = (flags & Helpers.MSG_RELIABLE) != 0;
|
||||
header.Resent = (flags & Helpers.MSG_RESENT) != 0;
|
||||
header.Zerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
|
||||
header.Sequence = (uint)((bytes[pos + 1] << 24) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 8) + bytes[pos + 4]);
|
||||
|
||||
// Set the frequency and packet ID number
|
||||
if (bytes[pos + 6] == 0xFF)
|
||||
{
|
||||
if (bytes[7] == 0xFF)
|
||||
if (bytes[pos + 7] == 0xFF)
|
||||
{
|
||||
return new LowHeader(bytes, ref pos, ref packetEnd);
|
||||
header.Frequency = PacketFrequency.Low;
|
||||
if (header.Zerocoded && bytes[pos + 8] == 0)
|
||||
header.ID = bytes[pos + 10];
|
||||
else
|
||||
header.ID = (ushort)((bytes[pos + 8] << 8) + bytes[pos + 9]);
|
||||
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MediumHeader(bytes, ref pos, ref packetEnd);
|
||||
header.Frequency = PacketFrequency.Medium;
|
||||
header.ID = bytes[pos + 7];
|
||||
|
||||
pos += 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HighHeader(bytes, ref pos, ref packetEnd);
|
||||
header.Frequency = PacketFrequency.High;
|
||||
header.ID = bytes[pos + 6];
|
||||
|
||||
pos += 7;
|
||||
}
|
||||
|
||||
header.AckList = null;
|
||||
CreateAckList(ref header, bytes, ref packetEnd);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -165,216 +186,24 @@ namespace OpenMetaverse.Packets
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="packetEnd"></param>
|
||||
protected void CreateAckList(byte[] bytes, ref int packetEnd)
|
||||
static void CreateAckList(ref Header header, byte[] bytes, ref int packetEnd)
|
||||
{
|
||||
if (AppendedAcks)
|
||||
if (header.AppendedAcks)
|
||||
{
|
||||
try
|
||||
int count = bytes[packetEnd--];
|
||||
header.AckList = new uint[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int count = bytes[packetEnd--];
|
||||
AckList = new uint[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
AckList[i] = (uint)(
|
||||
(bytes[(packetEnd - i * 4) - 3] << 24) |
|
||||
(bytes[(packetEnd - i * 4) - 2] << 16) |
|
||||
(bytes[(packetEnd - i * 4) - 1] << 8) |
|
||||
(bytes[(packetEnd - i * 4) ]));
|
||||
}
|
||||
header.AckList[i] = (uint)(
|
||||
(bytes[(packetEnd - i * 4) - 3] << 24) |
|
||||
(bytes[(packetEnd - i * 4) - 2] << 16) |
|
||||
(bytes[(packetEnd - i * 4) - 1] << 8) |
|
||||
(bytes[(packetEnd - i * 4) ]));
|
||||
}
|
||||
|
||||
packetEnd -= (count * 4);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
AckList = new uint[0];
|
||||
throw new MalformedDataException();
|
||||
}
|
||||
packetEnd -= (count * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
AckList = new uint[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LowHeader : Header
|
||||
{
|
||||
/// <summary></summary>
|
||||
public override ushort ID
|
||||
{
|
||||
get { return (ushort)((Data[8] << 8) + Data[9]); }
|
||||
set { Data[8] = (byte)(value >> 8); Data[9] = (byte)(value % 256); }
|
||||
}
|
||||
/// <summary></summary>
|
||||
public override PacketFrequency Frequency { get { return PacketFrequency.Low; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public LowHeader()
|
||||
{
|
||||
Data = new byte[10];
|
||||
Data[6] = Data[7] = 0xFF;
|
||||
AckList = new uint[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="packetEnd"></param>
|
||||
public LowHeader(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
FromBytes(bytes, ref pos, ref packetEnd);
|
||||
}
|
||||
|
||||
override public void FromBytes(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
if (bytes.Length < 10) { throw new MalformedDataException(); }
|
||||
Data = new byte[10];
|
||||
Buffer.BlockCopy(bytes, 0, Data, 0, 10);
|
||||
|
||||
if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0 && bytes[8] == 0)
|
||||
{
|
||||
if (bytes[9] == 1)
|
||||
{
|
||||
Data[9] = bytes[10];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MalformedDataException();
|
||||
}
|
||||
}
|
||||
|
||||
pos = 10;
|
||||
CreateAckList(bytes, ref packetEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="i"></param>
|
||||
public override void ToBytes(byte[] bytes, ref int i)
|
||||
{
|
||||
Buffer.BlockCopy(Data, 0, bytes, i, 10);
|
||||
i += 10;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MediumHeader : Header
|
||||
{
|
||||
/// <summary></summary>
|
||||
public override ushort ID
|
||||
{
|
||||
get { return (ushort)Data[7]; }
|
||||
set { Data[7] = (byte)value; }
|
||||
}
|
||||
/// <summary></summary>
|
||||
public override PacketFrequency Frequency { get { return PacketFrequency.Medium; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MediumHeader()
|
||||
{
|
||||
Data = new byte[8];
|
||||
Data[6] = 0xFF;
|
||||
AckList = new uint[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="packetEnd"></param>
|
||||
public MediumHeader(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
FromBytes(bytes, ref pos, ref packetEnd);
|
||||
}
|
||||
|
||||
override public void FromBytes(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
if (bytes.Length < 8) { throw new MalformedDataException(); }
|
||||
Data = new byte[8];
|
||||
Buffer.BlockCopy(bytes, 0, Data, 0, 8);
|
||||
pos = 8;
|
||||
CreateAckList(bytes, ref packetEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="i"></param>
|
||||
public override void ToBytes(byte[] bytes, ref int i)
|
||||
{
|
||||
Buffer.BlockCopy(Data, 0, bytes, i, 8);
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class HighHeader : Header
|
||||
{
|
||||
/// <summary></summary>
|
||||
public override ushort ID
|
||||
{
|
||||
get { return (ushort)Data[6]; }
|
||||
set { Data[6] = (byte)value; }
|
||||
}
|
||||
/// <summary></summary>
|
||||
public override PacketFrequency Frequency { get { return PacketFrequency.High; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HighHeader()
|
||||
{
|
||||
Data = new byte[7];
|
||||
AckList = new uint[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="packetEnd"></param>
|
||||
public HighHeader(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
FromBytes(bytes, ref pos, ref packetEnd);
|
||||
}
|
||||
|
||||
override public void FromBytes(byte[] bytes, ref int pos, ref int packetEnd)
|
||||
{
|
||||
if (bytes.Length < 7) { throw new MalformedDataException(); }
|
||||
Data = new byte[7];
|
||||
Buffer.BlockCopy(bytes, 0, Data, 0, 7);
|
||||
pos = 7;
|
||||
CreateAckList(bytes, ref packetEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="i"></param>
|
||||
public override void ToBytes(byte[] bytes, ref int i)
|
||||
{
|
||||
Buffer.BlockCopy(Data, 0, bytes, i, 7);
|
||||
i += 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user