# Serialization and Archives Internals This document explains the internal design of the `uLib` serialization system, which is built on top of **Boost.Serialization**. It provides custom archive implementations for various formats (XML, Text, Logging) and introduces **Human Readable Pairs (HRP)** for metadata-rich serialization. --- ## Architecture Overview The `uLib` archive system extends the standard `boost::archive` templates to add domain-specific features. The main components are: 1. **Custom Interface Layer**: Extends the default Boost archive API with additional operators and utilities. 2. **Specialized Archive Implementations**: Specialized classes for XML, Text, and Logging. 3. **HRP Support**: First-class support for `hrp` (Human Readable Pair) wrappers, which carry units, ranges, and descriptions. 4. **Static Registration System**: Macros and explicit instantiations to handle polymorphic types and compilation isolation. --- ## Custom Interface Layer All `uLib` archives use a custom interface defined in `Archives.h` via `uLib_interface_iarchive` and `uLib_interface_oarchive`. These templates add several key features: | Feature | Operator/Method | Description | |---|---|---| | **Mapping Operator** | `operator==` | Aliased to `operator&` (Boost's standard mapping operator). | | **Trace Operator** | `operator!=` | Used for trace/debug output of strings during serialization. | | **Type Registration** | `register_type()` | Registers a class type with the archive's internal serializer map. | | **Standard IO** | `operator<<` / `operator>>` | Standard redirect for saving and loading. | These interfaces are applied to the archives using template specialization of `boost::archive::detail::interface_iarchive` and `interface_oarchive`. --- ## Archive Variants ### XML Archives (`xml_iarchive`, `xml_oarchive`) These inherit from `boost::archive::xml_iarchive_impl` and `xml_oarchive_impl`. - **Internals**: They override `load_override` and `save_override` to handle `boost::serialization::hrp` specifically. - **XML Mapping**: When saving an `hrp`, it uses `save_start(name)` and `save_end(name)` to wrap the value in a named XML tag. ### Text Archives (`text_iarchive`, `text_oarchive`) Standard text-based archives used for compact serialization. They use `StringReader` to consume decorative text markers during loading. ### Human Readable Text (`hrt_iarchive`, `hrt_oarchive`) These are "naked" text archives that suppress most of Boost's internal metadata (object IDs, class IDs, versions). - **Goal**: Produce text output that is easy for humans to read and edit. - **Internals**: All overrides for Boost internal types (like `object_id_type`, `version_type`, etc.) are implemented as no-ops. ### Log Archive (`log_archive`) An XML-based output archive specifically for debug logging. - **Internals**: It forces every object into a Name-Value Pair (NVP) even if not provided by the user, and strips all technical metadata to keep the logs clean. --- ## HRP (Human Readable Pair) Integration `hrp` is a core `uLib` wrapper (defined in `Serializable.h`) that extends Boost's `nvp`: ```cpp // Example of HRP usage ar & HRP2("Energy", m_energy, "MeV").range(0, 100); ``` ### Internal Handling in Archives Archives in `Archives.h` provide specific `save_override`/`load_override` for `hrp`: - **XML**: Maps the `name()` to an XML tag. - **HRT**: Formats as `name: value [units]\n`. - **Log**: Converts it to a standard Boost `nvp` for consistent XML logging. --- ## Registration and Polymorphism ### Registration Macro The `ULIB_SERIALIZATION_REGISTER_ARCHIVE(Archive)` macro is crucial for polymorphic serialization. It instantiates the necessary template machinery to link the custom `Archive` type with any `Serializable` class exported via `BOOST_CLASS_EXPORT`. ### Explicit Instantiation To reduce compilation times and provide a single point of failure for link-time issues, `uLib` uses explicit instantiations in `src/Core/Archives.cpp`. This file includes the `.ipp` implementation files from Boost and instantiates the `archive_serializer_map` and implementation classes for all `uLib` archive types. --- ## Utility: StringReader The `StringReader` utility is used internally by text-based archives to parse and skip literals. For example: - When loading a string literal from a text archive, `StringReader` consumes whitespace and ensures the stream matches the expected string, failing if there is a mismatch. - This is vital for maintaining the structure of human-readable formats.