public byte[] ToByteArray()
            {
                PayloadWriter pw = new PayloadWriter();

                pw.WriteByte((byte)packetId);
                pw.WriteByte(Duplicates);
                pw.WriteBool(plugin != null);
                if (plugin != null)
                {
                    pw.WriteULong(plugin.PluginId);
                }

                pw.WriteBool(channel != null);
                if (channel != null)
                {
                    pw.WriteUInteger(channel.ConnectionId);
                }

                pw.WriteUInteger(MessageId);

                pw.WriteThreeByteInteger(Payload.Length);
                pw.WriteBytes(Payload);
                return(pw.ToByteArray());
            }
        private unsafe void SendQueue()
        {
            lock (packetQueue)
            {
                if (packetQueue.Count == 0)
                {
                    return;
                }

                PayloadWriter   pw            = new PayloadWriter();
                PacketQueueInfo currentData   = null;
                PacketQueueInfo compareBuffer = null;
                Stopwatch       sw            = Stopwatch.StartNew();

                while (packetQueue.Count > 0 && sw.ElapsedMilliseconds < this.MaxProcessingTime)
                {
                    while (packetQueue.Count > 0)
                    {
                        if (currentData == null)
                        {
                            currentData  = packetQueue.Dequeue();
                            sizeCounter -= currentData.Payload.Length;
                            continue;
                        }

                        if (currentData.Duplicates == 255)
                        {
                            break;
                        }

                        compareBuffer = packetQueue.Peek();

                        if (compareBuffer.Payload.Length == currentData.Payload.Length || compareBuffer.MessageId != currentData.MessageId)
                        {
                            fixed(byte *ptr1 = currentData.Payload, ptr2 = compareBuffer.Payload)
                            {
                                if (NativeMethods.memcmp(ptr1, ptr2, (uint)currentData.Payload.Length) == 0)
                                {
                                    currentData.Duplicates++;
                                    sizeCounter -= compareBuffer.Payload.Length;
                                    packetQueue.Dequeue();
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    pw.WriteBytes(currentData.ToByteArray());
                    currentData   = null;
                    compareBuffer = null;

                    if (pw.Length > 65535)
                    {
                        break;
                    }
                }

                conn.SendPayload(new MsgPacketQueue(pw.ToByteArray()), PacketId.PacketQueue);
                pw = null;
                sw.Stop();
            }
        }
        public unsafe byte[] Cache(byte[] data, int offset, int length)
        {
            if (isRam)
            {
                PayloadWriter pw = new PayloadWriter();
                if (IndexWritten == 0)
                {
                    pw.WriteInteger(data.Length);
                    pw.WriteByte((byte)Instruction.MEMCPYEX);
                    pw.WriteBytes(data);
                    WriteToCache(data);
                    return(pw.ToByteArray());
                }

                //lets see if there is a change
                if (length <= RamCache.Length)
                {
                    fixed(byte *ptr1 = &(data[offset]), ptr2 = RamCache)
                    {
                        if (NativeMethods.memcmp(ptr1, ptr2, (uint)(RamCache.Length > length ? length : RamCache.Length)) == 0)
                        {
                            int len = RamCache.Length > length ? length : RamCache.Length;
                            pw.WriteInteger(len);
                            pw.WriteBytes(writeMEMCPY(len, 0));
                            return(pw.ToByteArray());
                        }
                    }
                }

                int DataLength = 0;
                pw.WriteInteger(0); //reserve 4bytes for writing the data length

                FindInCache(data, (SmartCacheInfo inf) =>
                {
                    DataLength += inf.Length;
                    switch (inf.instruction)
                    {
                    case Instruction.NEWDATA:
                        {
                            pw.WriteBytes(WriteNEWDATA(data, inf.DataIndex, inf.Length));
                            break;
                        }

                    case Instruction.MEMCPY:
                        {
                            pw.WriteBytes(writeMEMCPY(inf.Length, inf.CacheIndex));
                            break;
                        }
                    }
                }, mode, offset, length);

                //don't try going above the original data size
                if (pw.Length > length)
                {
                    pw = new PayloadWriter();
                    pw.WriteInteger(DataLength);
                    pw.WriteByte((byte)Instruction.MEMCPYEX);
                    pw.WriteBytes(data);
                    WriteToCache(data);
                    return(pw.ToByteArray());
                }
                WriteToCache(data);

                byte[] temp    = pw.ToByteArray();
                byte[] lenTemp = BitConverter.GetBytes(DataLength);
                for (int i = 0; i < 4; i++)
                {
                    temp[i] = lenTemp[i];
                }
                return(temp);
            }
            return(data);
        }
        public byte[] Serialize(object obj)
        {
            if (obj == null)
            {
                return new byte[] { (byte)ObjectTypes.Null }
            }
            ;

            PayloadWriter pw         = new PayloadWriter();
            Type          ObjectType = obj.GetType();

            if (ObjectType == typeof(byte))
            {
                pw.WriteByte((byte)ObjectTypes.Byte);

                pw.WriteByte((byte)obj);
            }
            else if (ObjectType == typeof(byte[]))
            {
                byte[] data = (byte[])obj;
                pw.WriteByte((byte)ObjectTypes.ByteArray);
                pw.WriteInteger(data.Length);
                pw.WriteBytes(data);
            }
            else if (ObjectType == typeof(short))
            {
                pw.WriteByte((byte)ObjectTypes.Short);
                pw.WriteShort((short)obj);
            }
            else if (ObjectType == typeof(ushort))
            {
                pw.WriteByte((byte)ObjectTypes.UShort);
                pw.WriteUShort((ushort)obj);
            }
            else if (ObjectType == typeof(int))
            {
                pw.WriteByte((byte)ObjectTypes.Int);
                pw.WriteInteger((int)obj);
            }
            else if (ObjectType == typeof(uint))
            {
                pw.WriteByte((byte)ObjectTypes.UINT);
                pw.WriteUInteger((uint)obj);
            }
            else if (ObjectType == typeof(long))
            {
                pw.WriteByte((byte)ObjectTypes.Long);
                pw.WriteLong((long)obj);
            }
            else if (ObjectType == typeof(bool))
            {
                pw.WriteByte((byte)ObjectTypes.Bool);
                pw.WriteByte((bool)obj ? (byte)1 : (byte)0);
            }
            else if (ObjectType == typeof(string))
            {
                pw.WriteByte((byte)ObjectTypes.String);
                pw.WriteString(obj.ToString());
            }
            else if (ObjectType == typeof(SolidBrush))
            {
                pw.WriteByte((byte)ObjectTypes.SolidBrush);
                pw.WriteByte(((SolidBrush)obj).Color.A);
                pw.WriteByte(((SolidBrush)obj).Color.R);
                pw.WriteByte(((SolidBrush)obj).Color.G);
                pw.WriteByte(((SolidBrush)obj).Color.B);
            }
            else if (ObjectType == typeof(Rectangle))
            {
                pw.WriteByte((byte)ObjectTypes.Rectangle);
                pw.WriteInteger(((Rectangle)obj).X);
                pw.WriteInteger(((Rectangle)obj).Y);
                pw.WriteInteger(((Rectangle)obj).Width);
                pw.WriteInteger(((Rectangle)obj).Height);
            }
            else if (ObjectType == typeof(Size))
            {
                pw.WriteByte((byte)ObjectTypes.Size);
                pw.WriteInteger(((Size)obj).Width);
                pw.WriteInteger(((Size)obj).Height);
            }
            else if (ObjectType == typeof(Bitmap) || ObjectType == typeof(Image))
            {
                pw.WriteByte((byte)ObjectTypes.Bitmap);
                lzwCompression.Compress((Bitmap)obj, pw.vStream);
            }
            else
            {
                MemoryStream    ms = new MemoryStream();
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                pw.WriteByte((byte)ObjectTypes.Other);
                pw.WriteBytes(ms.GetBuffer(), 0, (int)ms.Length);
                ms.Close();
            }
            return(pw.ToByteArray());
        }