mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
109 lines
4.1 KiB
C#
109 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Threading;
|
|
using Cosmos.IL2CPU.Debug;
|
|
|
|
namespace Cosmos.Build.Windows {
|
|
public abstract class DebugConnectorStream : DebugConnector {
|
|
private Stream mStream;
|
|
|
|
protected delegate void PacketReceivedDelegate(byte[] aBytes);
|
|
|
|
protected class Incoming {
|
|
public Stream Stream;
|
|
// Buffer to hold incoming message
|
|
public byte[] Packet = new byte[5];
|
|
// Current # of bytes in mPacket
|
|
public int CurrentPos = 0;
|
|
public PacketReceivedDelegate Completed;
|
|
}
|
|
|
|
public override void SendCommand(byte aCmd) {
|
|
var xData = new byte[1];
|
|
xData[0] = aCmd;
|
|
mStream.Write(xData, 0, xData.Length);
|
|
}
|
|
|
|
protected void Start(Stream aStream) {
|
|
mStream = aStream;
|
|
var xIncoming = new Incoming() {
|
|
Stream = aStream
|
|
};
|
|
// Request first command
|
|
Next(1, PacketReceived);
|
|
}
|
|
|
|
private UInt32 GetUInt32(byte[] aBytes, int aOffset) {
|
|
return (UInt32)((aBytes[aOffset + 3] << 24) | (aBytes[aOffset + 2] << 16)
|
|
| (aBytes[aOffset + 1] << 8) | aBytes[aOffset + 0]);
|
|
}
|
|
|
|
private UInt16 GetUInt16(byte[] aBytes, int aOffset) {
|
|
return (UInt16)((aBytes[aOffset + 1] << 8) | aBytes[aOffset + 0]);
|
|
}
|
|
|
|
private void PacketTracePoint(byte[] aPacket) {
|
|
Dispatcher.BeginInvoke(DispatcherPriority.Background, CmdTrace, GetUInt32(aPacket, 0));
|
|
Next(1, PacketReceived);
|
|
}
|
|
|
|
private void PacketTextSize(byte[] aPacket) {
|
|
Next(GetUInt16(aPacket, 0), PacketText);
|
|
}
|
|
|
|
private void PacketText(byte[] aPacket) {
|
|
Dispatcher.BeginInvoke(DispatcherPriority.Background, CmdText
|
|
, ASCIIEncoding.ASCII.GetString(aPacket));
|
|
Next(1, PacketReceived);
|
|
}
|
|
|
|
private void PacketReceived(byte[] aPacket) {
|
|
// Could change to an array, but really not much benefit
|
|
switch ((MsgType)aPacket[0]) {
|
|
case MsgType.TracePoint:
|
|
Next(4, PacketTracePoint);
|
|
break;
|
|
case MsgType.Text:
|
|
Next(2, PacketTextSize);
|
|
break;
|
|
default:
|
|
throw new Exception("Unknown debug command");
|
|
}
|
|
}
|
|
|
|
private void Next(int aPacketSize, PacketReceivedDelegate aCompleted) {
|
|
var xIncoming = new Incoming() {
|
|
Packet = new byte[aPacketSize]
|
|
, Stream = mStream
|
|
, Completed = aCompleted
|
|
};
|
|
mStream.BeginRead(xIncoming.Packet, 0, aPacketSize, new AsyncCallback(DoRead), xIncoming);
|
|
}
|
|
|
|
private void DoRead(IAsyncResult aResult) {
|
|
try {
|
|
var xIncoming = (Incoming)aResult.AsyncState;
|
|
int xCount = xIncoming.Stream.EndRead(aResult);
|
|
xIncoming.CurrentPos += xCount;
|
|
// If 0, end of stream then just exit without calling BeginRead again
|
|
if (xCount == 0) {
|
|
return;
|
|
// Packet is not full yet, read more data
|
|
} else if (xIncoming.CurrentPos < xIncoming.Packet.Length) {
|
|
xIncoming.Stream.BeginRead(xIncoming.Packet, xIncoming.CurrentPos
|
|
, xIncoming.Packet.Length - xIncoming.CurrentPos
|
|
, new AsyncCallback(DoRead), xIncoming);
|
|
// Full packet received, process it
|
|
} else {
|
|
xIncoming.Completed(xIncoming.Packet);
|
|
}
|
|
} catch (System.IO.IOException ex) {
|
|
Dispatcher.BeginInvoke(DispatcherPriority.Background, ConnectionLost, ex);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|