Пример #1
0
        internal static void discardNext(IKernelLink ml)
        {
            switch (ml.GetNextExpressionType())
            {
            case ExpressionType.Integer:
                ml.GetInteger();
                break;

            case ExpressionType.Real:
                ml.GetDouble();
                break;

            case ExpressionType.Boolean:
            case ExpressionType.Symbol:
                ml.GetSymbol();
                break;

            case ExpressionType.String:
                ml.GetString();
                break;

            case ExpressionType.Object:
                ml.GetObject();
                break;

            // We would get an exception if we called GetComplex() and no complex class was set.
            case ExpressionType.Complex:
            case ExpressionType.Function: {
                IMathLink loop = MathLinkFactory.CreateLoopbackLink();
                try {
                    loop.TransferExpression(ml);
                } finally {
                    loop.Close();
                }
                break;
            }

            default:
                System.Diagnostics.Debug.Fail("Unhandled ExpressionType enum value in Utils.discardNext().");
                break;
            }
        }
Пример #2
0
 public override void TransferExpression(IMathLink source)
 {
     impl.TransferExpression(source);
 }
Пример #3
0
        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;
        }