/// <summary>
 /// Create a packet from the stream.
 /// </summary>
 /// <param name="header">The first 11 bytes of the data.</param>
 /// <param name="stream">The stream with the data</param>
 /// <returns>a new Packet</returns>
 /// <exception cref="IOException">If the data in the stream are invalid.</exception>
 internal static Packet Read(byte[] header, Stream stream)
 {
     Packet packet = new Packet();
     packet.data = header;
     int len = packet.ReadInt();
     if (len < 11)
     {
         throw new IOException("protocol error - invalid length");
     }
     packet.id = packet.ReadInt();
     int flags = packet.ReadByte();
     if ((flags & Reply) == 0)
     {
         packet.cmdSet = packet.ReadByte();
         packet.cmd = packet.ReadByte();
     }
     else
     {
         packet.errorCode = packet.ReadShort();
     }
     packet.data = new byte[len - 11];
     DebuggerUtils.ReadFully(stream, packet.data);
     packet.offset = 0;
     return packet;
 }
 /// <summary>
 /// Create a empty packet to send an Event from the target VM (debuggee) to the debugger.
 /// </summary>
 /// <returns>a new packet</returns>
 internal static Packet CreateEventPacket()
 {
     Packet packet = new Packet();
     packet.id = ++packetCounter;
     packet.cmdSet = ikvm.debugger.CommandSet.Event;
     packet.cmd = 100;
     packet.isEvent = true;
     return packet;
 }
 internal void SendPacket(Packet packet)
 {
     lock (writeMonitor)
     {
         packet.Send(stream);
     }
 }
        /// <summary>
        /// http://java.sun.com/javase/6/docs/platform/jpda/jdwp/jdwp-protocol.html#JDWP_VirtualMachine
        /// </summary>
        /// <param name="packet"></param>
        private void CommandSetVirtualMachine(Packet packet)
        {
            switch (packet.Command)
            {
                case VirtualMachine.Version:
                    packet.WriteString("IKVM Debugger");
                    packet.WriteInt(1);
                    packet.WriteInt(6);
                    packet.WriteString("1.6.0");
                    packet.WriteString("IKVM.NET");
                    break;
                case VirtualMachine.ClassesBySignature:
                    String jniClassName = packet.ReadString();
                    IList<TargetType> types = target.FindTypes(jniClassName);
                    packet.WriteInt(types.Count); // count

                    foreach (TargetType type in types)
                    {
                        Console.Error.WriteLine("FindTypes:" + jniClassName + ":" + type.TypeId);
                        packet.WriteByte(TypeTag.CLASS); //TODO can also a interface
                        packet.WriteObjectID(type.TypeId);
                        packet.WriteInt(ClassStatus.INITIALIZED);
                    }

                    break;
                case VirtualMachine.AllThreads:
                    int[] ids = target.GetThreadIDs();
                    packet.WriteInt(ids.Length);
                    for (int i = 0; i < ids.Length; i++)
                    {
                        packet.WriteObjectID(ids[i]);
                    }
                    break;
                case VirtualMachine.IDSizes:
                    int size = 4; //we use a size of 4, a value of 8 is also possible
                    packet.WriteInt(size); // fieldID size in bytes
                    packet.WriteInt(size); // methodID size in bytes
                    packet.WriteInt(size); // objectID size in bytes
                    packet.WriteInt(size); // referenceTypeID size in bytes
                    packet.WriteInt(size); // frameID size in bytes
                    break;
                case VirtualMachine.Suspend:
                    target.Suspend();
                    break;
                case VirtualMachine.Resume:
                    target.Resume();
                    break;
                case VirtualMachine.Exit:
                    target.Exit(packet.ReadInt());
                    break;
                case VirtualMachine.Capabilities:
                    packet.WriteBool(false); // Can the VM watch field modification, and therefore can it send the Modification Watchpoint Event?  
                    packet.WriteBool(false); // Can the VM watch field access, and therefore can it send the Access Watchpoint Event?  
                    packet.WriteBool(false); // Can the VM get the bytecodes of a given method? 
                    packet.WriteBool(false); // Can the VM determine whether a field or method is synthetic? (that is, can the VM determine if the method or the field was invented by the compiler?)  
                    packet.WriteBool(false); // Can the VM get the owned monitors infornation for a thread?
                    packet.WriteBool(false); // Can the VM get the current contended monitor of a thread?  
                    packet.WriteBool(false); // Can the VM get the monitor information for a given object?   
                    break;
                case VirtualMachine.CapabilitiesNew:
                    packet.WriteBool(false); // Can the VM watch field modification, and therefore can it send the Modification Watchpoint Event?  
                    packet.WriteBool(false); // Can the VM watch field access, and therefore can it send the Access Watchpoint Event?  
                    packet.WriteBool(false); // Can the VM get the bytecodes of a given method? 
                    packet.WriteBool(false); // Can the VM determine whether a field or method is synthetic? (that is, can the VM determine if the method or the field was invented by the compiler?)  
                    packet.WriteBool(false); // Can the VM get the owned monitors infornation for a thread?
                    packet.WriteBool(false); // Can the VM get the current contended monitor of a thread?  
                    packet.WriteBool(false); // Can the VM get the monitor information for a given object?   
                    packet.WriteBool(false); // Can the VM redefine classes? 
                    packet.WriteBool(false); // Can the VM add methods when redefining classes? 
                    packet.WriteBool(false); // Can the VM redefine classesin arbitrary ways?  
                    packet.WriteBool(false); // Can the VM pop stack frames?  
                    packet.WriteBool(false); // Can the VM filter events by specific object? 
                    packet.WriteBool(false); // Can the VM get the source debug extension? 
                    packet.WriteBool(false); // Can the VM request VM death events?  
                    packet.WriteBool(false); // Can the VM set a default stratum?  
                    packet.WriteBool(false); // Can the VM return instances, counts of instances of classes and referring objects?  
                    packet.WriteBool(false); // Can the VM request monitor events?  
                    packet.WriteBool(false); // Can the VM get monitors with frame depth info?  
                    packet.WriteBool(false); // Can the VM filter class prepare events by source name?
                    packet.WriteBool(false); // Can the VM return the constant pool information?  
                    packet.WriteBool(false); // Can the VM force early return from a method?  
                    packet.WriteBool(false); // reserved22
                    packet.WriteBool(false); // reserved23
                    packet.WriteBool(false); // reserved24
                    packet.WriteBool(false); // reserved25
                    packet.WriteBool(false); // reserved26
                    packet.WriteBool(false); // reserved27
                    packet.WriteBool(false); // reserved28
                    packet.WriteBool(false); // reserved29
                    packet.WriteBool(false); // reserved30
                    packet.WriteBool(false); // reserved31
                    packet.WriteBool(false); // reserved32
                    break;
                default:
                    NotImplementedPacket(packet); // include a SendPacket
                    break;
            }
        }
 private void NotImplementedPacket(Packet packet)
 {
     Console.Error.WriteLine("================================");
     Console.Error.WriteLine("Not Implemented Packet:" + packet.CommandSet + "-" + packet.Command);
     Console.Error.WriteLine("================================");
     packet.Error = Error.NOT_IMPLEMENTED;
 }
 /// <summary>
 /// http://java.sun.com/javase/6/docs/platform/jpda/jdwp/jdwp-protocol.html#JDWP_EventRequest
 /// </summary>
 /// <param name="packet"></param>
 private void CommandSetEventRequest(Packet packet)
 {
     switch (packet.Command)
     {
         case EventRequest.CmdSet:
             EventRequest eventRequest = EventRequest.create(packet);
             Console.Error.WriteLine(eventRequest);
             if (eventRequest == null)
             {
                 NotImplementedPacket(packet);
             }
             else
             {
                 target.AddEventRequest(eventRequest);
                 packet.WriteInt(eventRequest.RequestId);
             }
             break;
         default:
             NotImplementedPacket(packet);
             break;
     }
 }
 /// <summary>
 /// http://java.sun.com/javase/6/docs/platform/jpda/jdwp/jdwp-protocol.html#JDWP_ReferenceType
 /// </summary>
 /// <param name="packet"></param>
 private void CommandSetReferenceType(Packet packet)
 {
     switch (packet.Command)
     {
         case ReferenceType.Signature:
             int typeID = packet.ReadObjectID();
             TargetType type = target.FindType(typeID);
             Console.Error.WriteLine(typeID + ":" + type.GetJniSignature());
             packet.WriteString(type.GetJniSignature());
             break;
         case ReferenceType.ClassLoader:
             int classLoaderID = packet.ReadObjectID();
             packet.WriteObjectID(0); //TODO 0 - System Classloader, we can use module ID instead
             break;
         case ReferenceType.MethodsWithGeneric:
             typeID = packet.ReadObjectID();
             Console.Error.WriteLine(typeID);
             type = target.FindType(typeID);
             IList<TargetMethod> methods = type.GetMethods();
             packet.WriteInt(methods.Count);
             foreach (TargetMethod method in methods)
             {
                 Console.Error.WriteLine(method.MethodId + ":" + method.Name + ":" + method.JniSignature + ":" + method.GenericSignature+":"+method.AccessFlags);
                 packet.WriteObjectID(method.MethodId);
                 packet.WriteString(method.Name);
                 packet.WriteString(method.JniSignature);
                 packet.WriteString(method.GenericSignature);
                 packet.WriteInt(method.AccessFlags);
             }
             break;
         default:
             NotImplementedPacket(packet);
             break;
     }
 }