# Binaries

High-performance binary serialization/deserialization. Two-phase processing, multiple wire modes, string interning, source generation. Primary goal: **speed**.

> Implementation details (zero virtual dispatch, buffer management): `../../docs/BINARY/BINARY_IMPLEMENTATION.md`
> Output writers (ArrayBinaryOutput, BufferWriterBinaryOutput, chunk sizing): `../../docs/BINARY/BINARY_WRITERS.md`
> Source generation (SGen architecture, hybrid model, bridge methods): `../../docs/BINARY/BINARY_SGEN.md`

## Architecture

### Two-Phase Serialization

1. **Scan** (`ScanPass.cs`) — walks graph, detects multi-ref objects, builds reference table
2. **Serialize** (`BinarySerializationContext.cs`) — writes binary using reference table

Generic over `TOutput` for strategy selection (`ArrayBinaryOutput` vs `BufferWriterBinaryOutput`).

### Root Dispatch

Two root paths in `AcBinarySerializer.Serialize<T>`:

| Path | Condition | Dispatch depth |
|------|-----------|---------------|
| **SGen fast** | `UseGeneratedCode` + `GeneratedWriter != null` | 3 checks → `WriteObject` directly |
| **Full runtime** | No GeneratedWriter or `UseGeneratedCode=false` | IQueryable → Expression → TryWritePrimitive → WriteValueNonPrimitive → WriteObject |

SGen fast path skips: `is IQueryable`, `IsExpressionType`, `TryWritePrimitive` (GetTypeCode + 15-case switch), `WriteValueNonPrimitive` (4 interface checks). Wire format identical. Details: `../../docs/BINARY/BINARY_SGEN.md`.

### Wire Format

`BinaryTypeCode.cs` — 100+ type markers:

| Range | Purpose |
|---|---|
| 0–63 | **FixObj** — compiled type slot indices |
| 64–71 | **Complex** — Object, ObjectRef, Array, Dictionary, ByteArray |
| 72–75 | **Polymorphic** — ObjectWithTypeName/TypeIndex (±RefFirst) |
| 76–90 | **Primitives** — Null, Bool, Int8–64, Float32–64, Decimal, Char |
| 91–94 | **Strings** — String, StringInterned, StringEmpty, StringInternFirst |
| 95–98 | **Date/Time** — DateTime, DateTimeOffset, TimeSpan, Guid |
| 99–102 | **Other** — Enum, Legacy, PropertySkip |
| 103–134 | **FixStr** — short strings (length in marker) |
| 144+ | **Headers** — Metadata, RefHandling, CacheCount |
| 192–255 | **Tiny ints** — single-byte -16..47 |

Full spec: `docs/BINARY/BINARY_FORMAT.md`

## Key Files

### Serialization
- **`AcBinarySerializer.cs`** — entry point, context pool
- **`...BinarySerializationContext.cs`** — core logic, graph traversal, type writing
- **`...PropertyWriters.cs`** — per-type property write methods
- **`...BinarySerializationResult.cs`** — result wrapper
- **`...BinarySerializeTypeMetadata.cs`** — cached type metadata
- **`...ScanPass.cs`** — reference scanning

### Deserialization
- **`AcBinaryDeserializer.cs`** — entry point
- **`...BinaryDeserializationContext.cs`** — core logic
- **`...BinaryDeserializationContext.Read.cs`** — primitive reads
- **`...BinaryDeserializeTypeMetadata.cs`** — cached type metadata
- **`...CrossType.cs`** — schema evolution
- **`...Populate.cs`** — object population/merge

### I/O
- **`BinaryOutputBase.cs`** — output interface
- **`ArrayBinaryOutput.cs`** — ArrayPool-backed, fastest for `byte[]`
- **`BufferWriterBinaryOutput.cs`** — IBufferWriter-backed, zero-copy streaming. Context mode (serializer) + standalone mode (direct writes, e.g. `AcBinaryHubProtocol`)
- **`ArrayPooledBufferWriter.cs`** — concrete IBufferWriter
- **`IBinaryInputBase.cs`** / **`ArrayBinaryInput.cs`** / **`SequenceBinaryInput.cs`** — input strategies

### Config & Types
- **`AcBinarySerializerOptions.cs`** — options, presets
- **`BinaryTypeCode.cs`** — wire format markers
- **`StringInterningMode.cs`** — None/Attribute/All
- **`AcStringInternAttribute.cs`** — property-level interning
- **`TypeConversionInfo.cs`** — cross-type tracking
- **`BinaryPropertyFilterContext.cs`** — instance-dependent filtering

### Property Handling
- **`BinaryPropertyAccessorBase.cs`** / **`BinaryPropertySetterBase.cs`**

### Source Generation
- **`IGeneratedBinaryWriter.cs`** / **`IGeneratedBinaryReader.cs`**

### Exceptions
- **`AcBinaryDeserializationException.cs`** — rich exception with binary offset

## Config Options

Key wire-format options: `WireMode` (Compact/Fast), `ReferenceHandling` (None/OnlyId/All), `UseMetadata`, `UseStringInterning` (None/Attribute/All), `MaxDepth`, `UseCompression`, `PropertyFilter`.

`ReferenceHandling=None` + `UseStringInterning=None` = no scan pass (single-phase, fastest).

Presets: `Default`, `FastMode`, `FlatCopy`, `WasmOptimized`. Details: `docs/BINARY/BINARY_OPTIONS.md`.

## Dependencies

- Base classes: parent `Serializers/` (`AcSerializerContextBase`, `TypeMetadataBase`, `IdentityMap`)
- `System.Buffers` (ArrayPool, IBufferWriter)
- LZ4 (optional compression)
