CURL.IO.SERIALIZE (package)

Allow values to be converted to byte streams and back again.

Description

Serialization refers to the process of writing values to a SerializeOutputStream, which will convert each value into a stream of bytes representing the value, and/or reading them from a SerializeInputStream, which will recreate each value from a stream of bytes representing the value. The underlying stream of bytes can belong to an array, a file, a socket, etc.

Many values are serializable, including most primitives (uint8, int8, uint16, int16, int, int64, float, double, bool, char8, char16, char), quantities, enums, null, most procs, Strings, Urls, Packages, most Types, and all serializable classes (including DateTimeZone, DateTimeData, DateTime, Arguments, FastArray-of, Array-of, HashTable-of, and Set-of).

A class can be declared using the serializable adjective, enabling the serialization and deserialization of instances of the class, using the object-serialize method and the object-deserialize constructor, respectively.

The object-serialize method should first call SerializeOutputStream.write-class-version (normally with an argument of zero). Then, it should call super.object-serialize for each serializable superclass. And finally, it should write its serialized state (normally using SerializeOutputStream.write-one for each field).

The object-deserialize constructor should first call SerializeInputStream.verify-class-version (normally with an argument of zero). Note that, if it needs to handle changes to the class that are incompatible with already serialized data from an older version of the class, then it can instead use SerializeInputStream.read-class-version. Then, it should call construct-super.object-deserialize for each serializable superclass. And finally, it should read its serialized state (normally using the deserialize macro to read each field).

Note that if a class is declared using the serializable adjective, an appropriate object-serialize method and an appropriate object-deserialize constructor will be automatically generated, if they are needed, taking account of serializable superclasses and non-transient fields.

For example, the declaration:

{define-class public serializable Class
  {inherits ClassA, ClassB, ClassC}

  field a:int
  field transient b:#String
  field c:#DateTime
}


where ClassA and ClassC are serializable, will generate:

{constructor public {object-deserialize in:SerializeInputStream}
    {in.verify-class-version 0}
    {construct-super.ClassA.object-deserialize in}
    {construct-super.ClassB.default}
    {construct-super.ClassC.object-deserialize in}
    set self.a = {deserialize in, int}
    set self.c = {deserialize in, #DateTime}
}


{method public open {object-serialize out:SerializeOutputStream}:void
    {out.write-class-version 0}
    {super.ClassA.object-serialize out}
    {super.ClassC.object-serialize out}
    {out.write-one self.a}
    {out.write-one self.c}
}


Note that pointer equality is preserved when an object is serialized and then deserialized.
Package Members:
SerializeCode
SerializeException
SerializeInputStream
SerializeOutputStream
SerializeProtocol
standard-serialization-values