public override string GetString() { return(impl.GetString()); }
public virtual void HandlePacket(PacketType pkt) { switch (pkt) { // If you ever change the default behavior on the 4 "answer" packets to read off the link, // you'll need to add a seekMark in NativeKernelLink.waitForAnswer... case PacketType.Return: case PacketType.InputName: case PacketType.ReturnText: case PacketType.ReturnExpression: case PacketType.Menu: case PacketType.Message: break; // From here on, the cases do actual work. case PacketType.Call: { ExpressionType type = GetExpressionType(); if (type == ExpressionType.Integer) { // A normal CallPacket representing a call to .NET via nCall. callPktHandler.handleCallPacket(this); } else { // A CallPacket destined for the FE via MathLink`CallFrontEnd[] and routed through // .NET due to ShareFrontEnd[]. This would only be in a 5.1 FE, as earlier // versions do not use CallPacket and later versions would use the FE's Service Link. IMathLink feServerLink = callPktHandler.FEServerLink; if (feServerLink != null) { feServerLink.PutFunction("CallPacket", 1); feServerLink.TransferExpression(this); // FE will always reply to a CallPacket. Note that it is technically possible for // the FE to send back an EvaluatePacket, which means that we really need to run a // little loop here, not just write the result back to the kernel. But this branch // is only for a 5.1 FE, and I don't think that the 5.1 FE ever does that. TransferExpression(feServerLink); } } break; } case PacketType.Display: case PacketType.DisplayEnd: { IMathLink feServerLink = callPktHandler.FEServerLink; if (feServerLink != null) { if (accumulatingPS == null) { accumulatingPS = new System.Text.StringBuilder(34000); // 34K is large enough to hold an entire packet } accumulatingPS.Append(GetString()); if (pkt == PacketType.DisplayEnd) { // XXXPacket[stuff] ---> Cell[GraphicsData["PostScript", stuff], "Graphics"] feServerLink.PutFunction("FrontEnd`FrontEndExecute", 1); feServerLink.PutFunction("FrontEnd`NotebookWrite", 2); feServerLink.PutFunction("FrontEnd`SelectedNotebook", 0); feServerLink.PutFunction("Cell", 2); feServerLink.PutFunction("GraphicsData", 2); feServerLink.Put("PostScript"); feServerLink.Put(accumulatingPS.ToString()); feServerLink.Put("Graphics"); feServerLink.Flush(); accumulatingPS = null; } } else { Debug.WriteLine("Got PacketType.Display in handlePacket, but no FE link"); } break; } case PacketType.Input: case PacketType.InputString: { IMathLink feServerLink = callPktHandler.FEServerLink; if (feServerLink != null) { feServerLink.PutFunction(pkt == PacketType.InputString ? "InputStringPacket" : "InputPacket", 1); feServerLink.Put(GetString()); feServerLink.Flush(); NewPacket(); Put(feServerLink.GetString()); Flush(); } break; } case PacketType.Text: case PacketType.Expression: { // Print output, or message text. IMathLink feServerLink = callPktHandler.FEServerLink; if (feServerLink != null) { // XXXPacket[stuff] ---> Cell[stuff, "Print"] feServerLink.PutFunction("FrontEnd`FrontEndExecute", 1); feServerLink.PutFunction("FrontEnd`NotebookWrite", 2); feServerLink.PutFunction("FrontEnd`SelectedNotebook", 0); feServerLink.PutFunction("Cell", 2); feServerLink.TransferExpression(this); feServerLink.Put((lastPktWasMsg) ? "Message" : "Print"); feServerLink.Flush(); } else { // For one type of PacketType.Expression, no part of it has been read yet. Thus we must "open" the // packet so that later calls to newPacket() throw it away. if (pkt == PacketType.Expression) { int ignore; GetFunction(out ignore); } } break; } case PacketType.FrontEnd: { // This case is different from the others. At the point of entry, the link is at the point // _before_ the "packet" has been read. As a result, we must at least open the packet. // Note that PacketType.FrontEnd is really just a fall-through for unrecognized packets. We don't have any // checks that it is truly intended for the FE. IMathLink feServerLink = callPktHandler.FEServerLink; if (feServerLink != null) { ILinkMark mark = CreateMark(); try { // Wrap FrontEndExecute around it if not already there. int ignore; string wrapper = GetFunction(out ignore); if (wrapper != "FrontEnd`FrontEndExecute") { feServerLink.PutFunction("FrontEnd`FrontEndExecute", 1); } } finally { SeekMark(mark); DestroyMark(mark); } feServerLink.TransferExpression(this); feServerLink.Flush(); // Wait until either the fe is ready (because what we just sent causes a return value) // or kernel is ready (the computation is continuing because the kernel is not waiting // for a return value). do { System.Threading.Thread.Sleep(50); } while (!feServerLink.Ready && !Ready); if (feServerLink.Ready) { // fe link has something to return to kernel from last PacketType.FrontEnd we sent it. TransferExpression(feServerLink); Flush(); } } else { // It's OK to get here. For example, this happens if you don't share the fe, but have a // button that calls NotebookCreate[]. This isn't a very good example, because that // function expects the fe to return something, so Java will hang. you will get into // trouble if you make calls on the fe that expect a return. Everything is OK for calls // that don't expect a return, though. int ignore; GetFunction(out ignore); // Must at least open the packet, so newPacket (back in caller) will get rid of it. } break; } default: break; } lastPktWasMsg = pkt == PacketType.Message; }