This is documentation for Mathematica 5, which was
based on an earlier version of the Wolfram Language.
View current documentation (Version 11.1)

Documentation / Mathematica / Add-ons & Links / J/Link / Part 2. Writing Java Programs That Use Mathematica /

2.12 Using Marks

MathLink allows you to set a "mark" in a link, so that you can read more data and then seek back to the mark, restoring the link to the state it was in before you read the data. Thus, marks let you read data off a link and not have the data consumed, so you can read it again later. There are three mark-related methods in the MathLink interface:

// In the MathLink interface:

long createMark() throws MathLinkException;

void seekMark(long mark);

void destroyMark(long mark);

One common reason to use a mark is if you want to examine an incoming expression and branch to different code depending on some property of the expression. You want the code that actually handles the expression to see the entire expression, but you will need to read at least a little bit of the expression to decide how it must be handled (perhaps just calling getFunction() to see the head). Here is a code fragment demonstrating this technique:

String head = null;

long mark = ml.createMark();

try {

    head = ml.getFunction().name;

    ml.seekMark(mark);

} finally {

    ml.destroyMark(mark);

}

if (head.equals("foo"))

    handleFoo(ml);

else if (head.equals("bar"))

    handleBar(ml);

Because we seek back to the mark after calling getFunction(), the link will be reset to the beginning of the expression when the handleFoo() and handleBar() methods are entered. Note the use of a try/finally block to ensure that the mark is always destroyed, whether or not an exception of any kind is thrown after it is created. You should always use marks in this way. Right after calling createMark(), start a try block whose finally clause calls destroyMark(). It is important that no other code intervenes between createMark() and the try block, especially MathLink calls (which can throw MathLinkException). If a mark is created and not destroyed, a memory leak will result because incoming data will pile up on the link, never to be freed.

Another common use for marks is to allow you to read an expression one way, and if a MathLinkException is thrown, go back and try reading it a different way. For example, you might be expecting a list of real numbers to be waiting on the link. You can set a mark and then call getDoubleArray1(). If the data on the link cannot be coerced to a list of reals, getDoubleArray1() will throw a MathLinkException. You can then seek back to the mark and try a different method of reading the data.

double[] data = null;

long mark = ml.createMark();

ty {

    data = ml.getDoubleArray1();

} catch (MathLinkException e) {

    ml.clearError();

    ml.seekMark(mark);

    // Here, try a different way of reading the data:

    switch (ml.getNext()) {

        ...

    }

} finally {

    ml.destroyMark(mark);

}

Much of the functionality of marks is subsumed by the Expr class, described in Section 2.14. Expr objects allow you to easily examine an expression over and over in different ways, and with the peekExpr() method you can look at the upcoming expression without consuming it off the link.