Compound file storage
lxCompoundFile reads and writes Compound File Binary containers through Pascal streams, nested storage scopes, MiniFAT payloads and chained DIFAT sectors included; the native Classic BIFF8 workbook APIs use this backend on Linux and macOS
For spreadsheet work, use the ordinary workbook Open and SaveAs calls; the lower-level APIs below come in handy for inspecting nested streams, building containers and preserving storage metadata
Read or build a container
TlxCompoundFile.LoadFromStream(AStream, AOwnsStream) loads the directory and allocation metadata; AOwnsStream defaults to False, and the backing stream must stay available whilst its contents are being extracted
CreateNew(AStream, AOwnsStream) readies a new container, AddStorage and AddStream queue its contents, and Save writes out a version-3 container with whatever DIFAT extension sectors are required
| Member | Behaviour |
|---|---|
RootIndex | The root directory entry identity, serving as the parent for top-level storage and streams |
AddStorage(Name, ParentIndex) | Queues a nested storage and gives back its directory identity for adding children |
AddStream(Name, Data) | Queues a root-level byte stream |
AddStream(Name, Data, ParentIndex) | Queues a byte stream within the chosen parent scope and returns its identity |
OpenStream(Name), OpenStream(Name, ParentIndex) | Extract a root or scoped stream into an owned TlxCfbStream; a missing stream gives nil |
OpenEntryStream(Index) | Extracts a directory stream by identity; an invalid or non-stream entry yields nil |
HasStream(Name), HasStream(Name, ParentIndex) | Test for stream presence in the root or chosen parent scope |
FindStorage(Name, ParentIndex) | Returns a storage identity in the chosen parent, or -1 where no matching storage exists |
EntryCount, Entries(Index) | Inspect the loaded directory entries; indexes are zero-based and must be valid |
SetEntryMetadata(Index, Entry) | Copies just the class ID, state bits and timestamps into a valid queued entry or root; structural identities and payloads stay unchanged |
The TlxCfbEntry record exposes Name, EntryType, StartSector, Size, LeftSibling, RightSibling, Child and the derived ParentIndex; directory links are indexes, and -1 marks an absent identity
Its metadata fields are ClassID, StateBits, CreationTime and ModificationTime; timestamps keep raw FILETIME ticks from the 1601 UTC epoch rather than a locale-formatted date
TlxCfbEntryType covers cfbEmpty, cfbStorage, cfbStream and cfbRoot; TlxCfbStream exposes Name, Size, Data, Read, Seek and CopyTo
Extracted streams own detached bytes and must be freed by the caller; corruption, incomplete chains, invalid ownership and cyclic directory or allocation graphs are rejected instead of returning truncated payloads
lxCfbCompareNames(A, B) applies Compound File Binary length-first ordering with a pinned simple BMP uppercase mapping; duplicate names are scoped to their parent, and identical names in separate nested storages stay distinct
Native storage interfaces
On non-Windows targets, lxOLE provides the storage interface implementation that Classic workbook loading and saving require; its IStorage, IStream and IEnumStatStg keep explicit interface ownership and detached native container state
| Factory or helper | Contract |
|---|---|
XlsOpenCompoundStorage(Source, Storage) | Loads a read-only container starting at stream offset zero |
XlsOpenCompoundStorage(Source, Start, Storage) | Loads the container from the explicit nonnegative offset onwards |
XlsCreateCompoundStorage(Storage) | Creates writable native storage complete with nested scopes and streams |
XlsWriteCompoundStorage(Storage, Destination) | Serialises the native root storage to the supplied stream; foreign implementations and non-root storage are rejected |
XlsFreeCompoundStorageName(Name) | Frees native names handed back by storage statistics or enumeration; nil is accepted |
The factories return HResult; test Succeeded(Result) before putting the returned interface to use, and release interface references once finished
Read-only mutation fails, cloned stream cursors hold independent positions, and nested copies preserve parent identity and supported metadata; direct serialisation does not provide the higher-level workbook destination transaction contract
Canonical workbook identifiers
XlsIdentifierKeyText(const A: WideString): WideString in lxStandard returns the UTF-16 text form of the existing pinned Unicode identifier key, letting Classic defined-name storage share canonical equality with the other workbook engines
This key form exists for identity and lookup rather than displayed spelling; authored names stay unchanged, and the CFB directory comparator keeps its separate format-mandated ordering
See Free Pascal support for native build requirements and the verified BIFF8 workbook contract, and Classic encryption for supported encryption and plaintext property-stream behaviour