<Chapter Label="Serialization support">
  <Heading>Serialization support</Heading>

<Section Label="section:Serialization support">
  <Heading>Serialization support</Heading>

HPC-GAP has support to serialize most GAP data. While functions in particular cannot be serialized, it is possible to
serialize all primitive types (booleans, integers, cyclotomics, permutations, floats, etc.) as well as all lists and
records.
<P/>
Custom serialization support can be written for data objects, positional objects, and component objects; serialization
of compressed vectors is already supported by the standard library.

<ManSection>
    <Func Name="SerializeToNativeString"
      Arg='obj'/>

<Description>
<Ref Func="SerializeToNativeString"/> takes the object passed as an argument and turns it into a string, from which a copy of
the original can be extracted using <Ref Func="DeserializeNativeString"/>.
</Description>
</ManSection>

<ManSection>
    <Func Name="DeserializeNativeString"
      Arg='str'/>

<Description>
<Ref Func="DeserializeNativeString"/> reverts the serialization process.
<P/>
Example:

<Example><![CDATA[
gap> DeserializeNativeString(SerializeToNativeString([1,2,3]));
[ 1, 2, 3 ]
]]></Example>
</Description>
</ManSection>

<ManSection>
    <Func Name="InstallTypeSerializationTag"
      Arg='type, tag'/>

<Description>
<Ref Func="InstallTypeSerializationTag"/> allows the serialization of data objects, positional objects, and component objects.
The value of <A>tag</A> must be unique for each type; it can be a string or integer. Non-negative integers are reserved
for use by the standard library; users should use negative integers or strings instead.
<P/>
Objects of such a type are serialized in a straightforward way: During serialization, data objects are converted into
byte streams, positional objects into lists, and component objects into records. These objects are then serialized along
with their tags; deserialization uses the type corresponding to the tag in conjunction with <Ref BookName="ref" Func="Objectify"/> to
reconstruct a copy of the original object.
<P/>
Note that this functionality may be inadequate for objects that have complex data structures attached that are not meant
to be replicated. The following alternative is meant for such objects.
</Description>
</ManSection>

<ManSection>
    <Func Name="InstallSerializer"
      Arg='description, filters, method'/>

<Description>
The more general <Ref Func="InstallSerializer"/> allows for arbitrarily complex serialization code. It installs <A>method</A> as
the method to serialize objects matching <A>filters</A>; <A>description</A> has the same role as for
<Ref BookName="ref" Func="InstallMethod"/>.
<P/>
The method must return a plain list matching a specific format. The first element must be a non-negative integer, the
second must be a string descriptor that is unique to the serializer; these can then be followed by an arbitrary number
of arguments.
<P/>
As many of the arguments (starting with the third element of the list) as specified by the first element of the list
will be converted from their object representation into a serializable representation. Data objects will be converted
into untyped data objects, positional objects will be converted into plain lists, and component objects into records.
Conversion will not modify the objects in place, but work on copies. The remaining arguments will remain untouched.
<P/>
Upon deserialization, these arguments will be passed to a function specified by the second element of the list.
<P/>
Example:

<Example><![CDATA[
InstallSerializer("8-bit vectors", [ Is8BitVectorRep ], function(obj)
  return [1, "Vec8Bit", obj, Q_VEC8BIT(obj), IS_MUTABLE_OBJ(obj)];
end);
]]></Example>

Here, <C>obj</C> will be converted into its underlying representation, while the remaining arguments are left alone.
<C>"Vec8Bit"</C> is the name that is used to look up the deserializer function.
</Description>
</ManSection>

<ManSection>
    <Func Name="InstallDeserializer"
      Arg='descriptor, func'/>

<Description>
The <A>descriptor</A> value must be the same as the second element of the list returned by the serializer; <A>func</A>
must be a function that takes as many arguments as there were arguments after the second element of that list. For
deserialization, this function is invoked and needs to return the deserialized object constructed from the arguments.
<P/>
Example:

<Example><![CDATA[
InstallDeserializer("Vec8Bit", function(obj, q, mut)
  SET_TYPE_OBJ(obj, TYPE_VEC8BIT(q, mut));
  return obj;
end);
]]></Example>

Here, the untyped <C>obj</C> that was passed to the deserializer needs to be given the correct type, which is calculated
from <C>q</C> and <C>mut</C>.
</Description>
</ManSection>
  </Section>
</Chapter>
