In the next release of Jep.Net you will be able to serialize parsed expressions, the main JepInstance class, and its sub-components. This allows persistent storage and transfer between applications.
NOTE: Serialization is incomplete in Jep.Net version 1.0 and requires extensive testing. We expect to have this included and fully functional in version 1.1, which should be available within a few months. (It will be a free update for all Jep.Net v1.0 license holders).
Depending on your needs you may choose from three different serialization options:
The Node class itself is not serializable. Instead, a wrapper class
SingularSys.Jep.Walkers.SerializableExpression
is used to provide a compact serializable representation of a node. The class is constructed
using new SerializedExpression(Node n)
and the Node ToNode(JepInstance j)
method is used to extract the node in the context
of a given Jep instance.
To serialize use:
// Set-up jep JepInstance j = new JepInstance(); // create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); // parse an expression Node n = j.Parse("1+cos(2 th)"); // Create a SerializableExpression SerializableExpression se = new SerializableExpression(n); // Serialize the expression bf1.Serialize(ms, o); // extract the bytes byte[] bytes = ms.ToArray();
To deserialize the expression use:
// Set-up jep JepInstance j2 = new JepInstance(); // Create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(theByteArray); BinaryFormatter bf1 = new BinaryFormatter(); ms.Position = 0; // Deserialize the SerializableExpression SerializableExpression se2 = (SerializableExpression) bf1.Deserialize(ms); // Create a node Node n2 = se2.ToNode(j2);
Alternatively, the serialized expression could be written to a file
.... // Set-up file stream and BinaryFormatter Stream myStream ; myStream = File.OpenWrite(filename); BinaryFormatter bf1 = new BinaryFormatter(); // Serialize and Write object bf1.Serialize(myStream, se); myStream.Close();
.... Stream myStream = File.OpenRead(filename); BinaryFormatter bf1 = new BinaryFormatter(); mySteam.Position = 0; // Deserialize the SerializableExpression SerializableExpression se2 = (SerializableExpression) bf1.Deserialize(myStream); // Create a node Node n2 = se2.ToNode(j2); // Close file myStream.Close();
If you wish to serialize the values of variables for later use, then the VariableTable can be serialized. Again this methods assumes the same version and configuration of the Jep instances.
// Set-up jep JepInstance j = new JepInstance(); // create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); // Serialize the expression bf1.Serialize(ms, j.VarTab); // Serialize the expression Node n = j.Parse("1+cos(2 th)"); SerializableExpression se = new SerializableExpression(n); bf1.Serialize(ms, o); // extract the bytes byte[] bytes = ms.ToArray();
To deserialize
// Set up JepInstance JepInstance j2 = new JepInstance // Create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); ms.Position = 0; // Deserialize the SerializableExpression VariableTable vt2 = (VariableTable) bf1.Deserialize(ms); // Set the SymbolTable as that used by the jep instance j2.VarTab = vt2; // Deserialize the SerializableExpression SerializableExpression se2 = (SerializableExpression) bf1.Deserialize(ms); // Create a node Node n2 = se2.ToNode(j2);
The Jep class and all its components are serializable, meaning that the configuration of the Jep instance can be stored. This includes the full set of variables, functions, operators, and various settings. If the ConfigurableParser is used, then its configuration is also stored. Note that changes made to the standard JavaCC parser are not recorded.
A typical setup will take 7KB with the standard parser and 12KB with the configurable parser.
// Set-up jep JepInstance j = new JepInstance(); // create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); // Serialize the expression bf1.Serialize(ms, j); // Serialize the expression Node n = j.Parse("1+cos(2 th)"); SerializableExpression se = new SerializableExpression(n); bf1.Serialize(ms, o); // extract the bytes byte[] bytes = ms.ToArray();
To deserialize
// Create a MemoryStream and BinaryFormatter MemoryStream ms = new MemoryStream(); BinaryFormatter bf1 = new BinaryFormatter(); ms.Position = 0; // Deserialize the SerializableExpression JepInstance j2 = (JepInstance) bf1.Deserialize(ms); // Deserialize the SerializableExpression SerializableExpression se2 = (SerializableExpression) bf1.Deserialize(ms); Node n2 = se2.ToNode(j2);
The SerializedExpression class can also be used to produce copies of a node without having to serialize and deserialize.
// Create first instance JepInstance j = new JepInstance(); // Parse equation using first instance Node n = j.Parse("a+cos(2 th)"); // Create a SerializableExpression SerializableExpression se = new SerializableExpression(n); // Create second instance JepInstance j2 = new JepInstance(); // Import expression into second instance Node n2 = se.ToNode(j2);