# Release 4.1.1 - August 18, 2026
    - Fixed `framecpp_verify` crashing (SIGBUS on macOS ASan, SEGV on
      Linux x86_64) on real detector frames. Root cause: ZeroSuppress
      `zexpand` read one element past the end of its input buffer on the
      last iteration when the compressed data length happened to align
      with a guard-page boundary. Added a bounds-checking `safe_load`
      helper that returns zero for out-of-range indices and threaded the
      real input length through from the caller (closes #381).
    - Added deterministic guard-page regression test
      (`ZexpandBoundsTest`) that reproduces the crash with a captured
      compressed buffer from an H1 detector frame.
    - Flipped `Verify::m_check_expandability` default from `true` to
      `false`. The full-decompression pass is expensive and CRC + metadata
      checks catch on-disk corruption without exercising every FrVect.
      Callers who need the decompression pass exercised must opt in
      explicitly via `Expandability(true)`; the `framecpp_verify`
      command-line utility gained a matching `--decompress-check`
      option (refs #381).
    - Fixed `FIXTURES_REQUIRES` → `FIXTURES_REQUIRED` typo in the CTest
      fixture wiring so dependent tests actually see the fixture setup
      (closes #363).
    - Raised `LargeFrameTest` CTest timeout from the CMake default
      (1500 s) to 600 s so the test completes reliably on slower macOS
      CI runners (closes #364).
    - Link `Boost::thread` explicitly into `libframecppcmn` — conda-forge
      Boost 1.90.0 build_1 moved `boost::detail::get_tss_data` (used by
      `Boost::log`) out of the log module's transitive-link chain, so
      consumers now have to name `Boost::thread` themselves to resolve
      the tss symbols at link time.
    - Lifted hand-edits from `debian/rules` into `debian/rules.in` and
      stopped tracking the generated `debian/rules` output in the
      repository (was drifting between hand-edits and CMake output).
    - Ship substituted `meta.yaml` in the source tarball so the
      conda-forge feedstock consumes authoritative pins straight from
      the release (closes #276).
    - Bumped `ldas-tools-cmake` floor to 1.5.1.
    - `libframecppcmn` SOVERSION: 16:0:1 → 16:1:1 (implementation change,
      no public API break).

# Release 4.1.0 - June 23, 2026
    - Bumped C++ language standard floor to C++20 (closes #304). On RHEL 8
      this is provided by the gcc-toolset-14 BuildRequires arm added in
      #302; on RHEL 9+, Debian 12+, Fedora, conda-forge, and macOS the
      default compiler suffices.
    - On EL 8, switched the BuildRequires from `boost169` (Boost 1.69)
      to `boost1.78` (Boost 1.78) to support C++20.
    - `framecpp_verify` and `framecpp_checksum` now report both the
      calculated and stored checksum values at `--verbose 2` or higher
      (closes #151). New public API: `Verify::checksum_info_type` struct
      and `Verify::ChecksumInfoQueue()` accessor expose the per-file
      comparison log to client tools.
    - `ClassicIO<T>::operator==(const Object&)` reversed-candidate
      ambiguity under C++20 fixed: typed `operator==` moved to hidden
      friends across the Universal frame types, ClassicIO virtual
      dispatch routed through `FrameCPP::compare` (closes #305). Also
      fixed `FrVect` typed `operator==` doing content comparison
      instead of unconditional `return true`.
    - `framecpp_sample` output-file silent-failure surfaced (closes
      #286): `obuf->close()` return value now checked and the output
      file is `stat()`-ed before reporting success.
    - `framecpp_sample` emits `Z-{description}-{gps}-{duration}.gwf`
      without the previous `_ver{N}` filename rewrite (closes #283).
    - `framecpp_verify` `--verbose` bare-flag form restored — accepts
      `--verbose` without a value as well as `--verbose 2` (closes
      #287).
    - Build-time `framecpp_sample` / `framel_sample` invocations
      guarded against cross-compile-without-emulator (closes #119).
    - Distribution templates relocated from `config/` to `debian/`
      and `rpm/` (closes #307).
    - License files (COPYING, LICENSE.md, debian/copyright) rendered
      from suite-wide templates via the new `cx_install_license`
      helper (closes #267).
    - libframecppcmn SOVERSION: 15:0:0 → 16:0:1 (new public surface
      in `Verify` for #151).
    - libframecppu (Universal) SOVERSION: 1:0:0 → 2:0:1 (additive
      hidden-friend `operator==` declarations across all Universal
      frame types for #305).

# Release 4.0.3 - May 21, 2026
    - Fixed C-API FrameH constructor passing arguments in wrong slot
      (closes #251): the CInterface FrameH ctor wrapper was not updated when
      ULeapS was removed from Universal::FrameH (commit 44bb9385a), so the
      frame duration ended up stored in dataQuality and the leap-seconds
      count ended up stored in dt. FrameCPP-written .gwf files therefore had
      dt = TAI-UTC offset (37 s post-2017) regardless of the requested
      duration, causing LALPulsar testMakefakedata_v5.sh to fail under
      LAL_FRAME_LIBRARY=FrameC. Added a self-contained regression test
      (test_issue_251_duration_walk) that writes a 1800-second fixture via
      the same C-API path and asserts the readback span.
    - Fixed transitive dependency propagation for conda-forge builds by adding
      PUBLIC/PRIVATE keywords to library dependencies in CMakeLists.txt
      - framecpp libraries now properly export Boost.Log as public dependency
      - framecppcmn: Made ldastoolsal, Boost::serialization, debugarchive, and
        jsonarchive PUBLIC (used in headers); Made compression libraries PRIVATE
      - framecppu: Made framecppcmn PUBLIC
      - framecpp: Made framecppu PUBLIC; Made compression libraries PRIVATE
      - Fixes undefined reference errors to boost::log symbols in conda builds
    - Added --data-max-n-bytes=N option to framecpp_dump_objects to truncate
      the dump of an FrVect's data field to the first N bytes followed by a
      truncation marker (closes #243)
    - Improved test output handling for framecpp_dump_objects tests
      - test_file_integrity_dump_objects_<DESC> and framecpp_dump_objects_ver<N>
        tests now redirect output to a per-test file; on success the file is
        removed (CI log stays small), on failure it is preserved and its last
        200 lines are echoed to stderr for diagnostics (closes #243)
    - Redirected CompressionTest output on success via new REDIRECT_OUTPUT
      option on framecpp_target_test helper; same hybrid policy as the dump
      tests (closes #260)
    - Replaced cmake -E cat with cmake -E md5sum in per-(structure, version)
      _verify tests, eliminating ~50k lines of binary fixture dumps from the
      CI build log (closes #261)
    - Marked ldas-tools-framecpp-doc as Architecture: all (Debian) and
      BuildArch: noarch (RPM) since documentation is architecture-independent
      (closes #249)
    - Added libgmock-dev to Debian Build-Depends so framecpp builds on
      Bullseye, where libgtest-dev does not bundle gmock (closes #245)
    - Use cmake_minimum_required range form for CMake 4.x compatibility
      (closes #254)

# Release 4.0.2 - April 13, 2026
    - Extended test timeouts for serialization_advanced_test (closes #244)

# Release 4.0.1 - April 1, 2026
    - Fixed dataValid fields loss in FrVect compression (closes #238): CloneCompressed()
      now preserves dataValid information when creating compressed FrVect
      objects (fixes data loss when OFrameStream::WriteFrame applies compression)
    - Added comprehensive unit tests for dataValid preservation during compression
    - Fixed ZSTD compression support (closes #239):
      - Added MODE_ZSTD enum value to Compression.hh (was missing, only MODE_DIFF_ZSTD existed)
      - Fixed MODE_DIFF_ZSTD typo in FrVectData.hh that mapped to BIGENDIAN_DIFF_GZIP instead of BIGENDIAN_DIFF_ZSTD
      - Added ZSTD and DIFF_ZSTD entries to compress_type_map() forward mapping
      - Added ZSTD and DIFF_ZSTD entries to compress_type_reverse_map()
      - Implemented MODE_ZSTD and MODE_DIFF_ZSTD compression in Compression::Compress()
      - Implemented MODE_ZSTD and MODE_DIFF_ZSTD expansion in Compression::Expand()
      - Added comprehensive unit tests for ZSTD, DIFF_ZSTD, and endianness modes
      - ZSTD compression now works correctly (was failing with "unknown compression mode: 8(0x8)")
    - Fixed Dimension public API linker errors by implementing getter methods (closes #240)
    - Fixed FRAME_SPEC_CURRENT hardcoded value and implement two-variable approach (closes #237)
    - Added Python 3 as build dependency for packaging
    - Documented pre-existing buffer overflow bugs in ZERO_SUPPRESS and DIFF_GZIP
      compression modes (AddressSanitizer heap-buffer-overflow in
      CompressionDifferential.cc:97 and CompressionZeroSuppress.cc:428)

# Release 4.0.0 - February 16, 2026
    - Corrected cmake configure with -DBUILD_TESTING=off (closes #229)
    - Set default frame specification version to 8 (was 9)
    - Fixed ODR violations by moving function-local statics from headers
      to source files
    - Replaced getenv-based debug code with hierarchical logging system
      (framecpp.iostream and framecpp.frtoc channels)
    - Implemented cumulative frame generation in framecpp_sample; refactored
      to use smart pointers eliminating 366KB+ memory leaks
    - Fixed FrTOCAdcData positions_cache sizing bug that could cause buffer
      overruns
    - Fixed incorrect GetFSIId call in ReadPtrStruct debug logging
    - Fixed CMake-configured FrCheck path (was hardcoded macOS path)
    - Suppressed GCC 14.3 false positive in framecpp_inspector.cc
    - Limited parallel RPM build jobs to 4 to prevent OOM during LTO

# Release 3.0.5 - Mon Dec 16 2024
    - Corrected issues revealed by address sanitizer

# Release 3.0.4 - Tue March 26, 2024
    - Corrected initialization order
    - Initialized all option variables for framecpp_verify (closes #209)
    - Restored CRC effecientcy (closes #164)
    - Restore framecpp_compare (closes #165)
    - Corrected handling of composite compression modes
    - Corrected translation of compression mode flags going from version 8
      frame specification to version 9 frame specification
    - Added ability to specify version of frame to write

# Release 3.0.2 - Tue January 17, 2023
    - Corrected handling of ZERO_SUPPRESS_OTHERWISE_GZIP (closes computing/ldastools/LDAS_Tools#159)
    - Added GetNDataValid function and other functions to access/manipulate dataValid vector to FrVect (closes computing/ldastools/LDAS_Tools#160)
    - Modified function signature of FrameCPP::Version9::FrVect::SetDataValid to accept const CHAR_U* as first parameter (closes computing/ldastools/LDAS_Tools#161)
    - Updated library versions:
      - data format version: 9.2
      - libframecpp9 2:0:2
      - libfraemcpp 17:0:1

# Release 3.0.1 - Wed January 04, 2023
    - Corrected framecpp/Types.hh for version 9 frame specification (closes computing/ldastools/LDAS_Tools#158)
    - Build using C++17 standard
    - Improved framecpp_fracfg utility to exit with non-zero exit status for unsupported frame spec versions
    - Updated library versions
      - data format version: 9.1
      - libfraemcpp 16:1:0
      - libframecpp9 1:1:1

# Release 3.0.0 - December 22, 2022
    - Corrected default slope value for version 8 FrAdcData (closes computing/ldastools/LDAS_Tools#114)
    - Removed FrStatData (closes computing/ldastools/LDAS_Tools#127)
    - Remove ULeapS from FrameH structure (closes computing/ldastools/LDAS_Tools#128)
    - Removed the following elements from the FrTOC (closes computing/ldastools/LDAS_Tools#131)
      - ULeapS
      - runs
      - frame
      - nFirstADC
      - nFirstSer
      - nFirstTable
      - nFirstMsg
      - nStatType
      - nameStat
      - detector
      - nStatInstance
      - nTotalStat
      - tStart
      - tEnd
      - version
      - positionStat
    - Have FrTOC::FrStatQuery throw runtime error as this function is depricated (closes computing/ldastools/LDAS_Tools#131) 
    - Remove ULeapS from FrameH structure (closes computing/ldastools/LDAS_Tools#128)
    - Added fileBaseName to FrTOC (closes computing/ldastools/LDAS_Tools#134)
    - Added MIME support to FrProcData (closes computing/ldastools/LDAS_Tools#133)
    - Added Zstd compression modes (closes computing/ldastools/LDAS_Tools#136)
    - Added dataValid to FrVect (closes computing/ldastools/LDAS_Tools#130)
    - Added chkSumTOC to FrEndOfFile (closes computing/ldastools/LDAS_Tools#132)
    - Updated library versions
      - libframecpp 16:0:0
      - libframecppc 4:0:0

# Release 2.9.1 - July 11, 2022
    - Corrected issue with reading Param information for FrEvent, FrSimEvent and FrProcData (closes computing/ldastools/LDAS_Tools#148)
    - Minor changes to the build system to allow for cross compilation (closes computing/ldastools/LDAS_Tools#144 computing/ldastools/LDAS_Tools#145)
    - Updated library versions
      - libframecpp8 11:1:0

# Release 2.9.0 - June 27, 2022
    - Corrected library versioning numbers to indicate API/API incompatibility
      - libframecpp8 11:0:0
      - libframecpp 15:0:0

# Release 2.8.2 - June 14, 2022
    - Corrected default slope value for version 8 FrAdcData (closes #114)
    - Code cleanup for SWIG compilation
    - Corrected type for FrSimEvent::parameters (REAL_4 => REAL_8)
    - Modified FrSimEvent time type to be GPSTime (consitent with FrEvent)
    - Modified FrameCPP::Common::AppendComment to prevent STRING overflow (closes #138)
    - Modified FrameCPP::Common::AppendComment to prevent copying of duplicates to STRING (closes #140)
    - Fixed issue with calculating cksums for files that were larger than 4G (closes #137)

# Release 2.8.1 - September 29, 2021
    - Many corrections to support building on RHEL 8
    - Minor version number bumped to reflect backwards
      incompatibility introduced with previous release.

# Release 2.7.3 - September 21, 2021
  - Removed excessive debugging statements (closes #109)
  - Updated library version numbers
    - libframecmn 12:0:0
    - libframecpp3 8:0:0
    - libframecpp4 10:0:0
    - libframecpp6 10:0:0
    - libframecpp7 6:0:0
    - libframecpp8 9:0:0
    - libframecpp 13:0:0

# Release 2.7.2 - August 13, 2021
  - Corrected macro FRAMECPP_VERSION_NUMBER (closes #87)
  - Corrected Debian package resolution order for boost libaries (closes #107)
  - Addressed type conversion issue that manifested in the Python SWIG bindings (closes #108)

# Release 2.7.1 - March 9, 2021
  - Continuation with Serialization infistructure
  - Updated library version
    - libframecppcmn 11:1:0
    - libframecpp3 7:2:1
    - libframecpp4 9:2:1
    - libframecpp6 9:1:1
    - libframecpp7 5:1:1
    - libframecpp8 8:1:1
    - libframecpp 12:1:0
 
# Release 2.7.0 - August 14, 2019
  - Converted to CMake (closes #33)
  - Converted framecpp_sample to use boost::program_options
  - Converted unit tests to use Boost::Test
  - Added over arching directive to build only FrameCPP library and support packages (closes #63).
  - Reformatted comments for Doxygen (Closes #66)
  - Corrected Portfile to have proper description (Closes #55)
  - Converted FrSimData::data_type from Common::SearchContainer to Common::Container (Closes #71)
  - Updated library version
    - libframecppcmn 11:0:0
    - libframecpp3 7:1:1
    - libframecpp4 9:1:1
    - libframecpp6 9:1:1
    - libframecpp7 5:1:1
    - libframecpp8 8:1:1
    - libframecpp 12:1:0

# Release 2.6.5 - January  8, 2019
  - Have IFrameStream::GetTOC() return shared_ptr to FrTOC to provide better memory protection symantics

# Release 2.6.4 - December 6, 2018
  - Addressed packaging issues

# Release 2.6.3 - November 27, 2018
  - Added requirement of C++ 2011 standard
  - Store in repository a static version of utility generated
    documentation (fixes #11)
  - Standardize source code format by using clang-format
  - Eliminated some warning messages noticed when compiling on Buster
  - Changed FrAdcData.GetUnits to return const STRING& (Fixes #36)
  - Addressed Debian Buster warning messages (Fixes #38)
  - Added checking of run number of FrameStreamPlan (Fixes #14)
  - Corrected problem with C-Interface compression (closes #44)
  - Added FrHistory to FrVect for Sample frames
  - When compressing buffers, only returned compressed buffer
    iff it is greater than zero and less than the input buffer. (closes #48)
  - Updated library version
    - libframecppcmn 10:0:1
    - libframecpp3 7:0:1
    - libframecpp4 9:0:1
    - libframecpp6 9:0:1
    - libframecpp7 5:0:1
    - libframecpp8 8:0:1
    - libframecpp 11:0:1
    - libframecppc 3:5:1

# Release 2.6.1 - June 22, 2018
  - Updated packaging rules to have build time dependency on specific
    versions of LDAS Tools packages

# Release 2.6.0 - June 19, 2018
  - Removed hand rolled smart pointers in favor of boost smart pointers
  - Changed version of framecppcmn library to 9:0:0
  - Changed version of framecpp3 library to 6:0:0
  - Changed version of framecpp4 library to 8:0:0
  - Changed version of framecpp6 library to 8:0:0
  - Changed version of framecpp7 library to 4:0:0
  - Changed version of framecpp8 library to 7:0:0
  - Changed version of framecpp library to 10:0:0
  - Changed version of framecppc library to 3:4:0
  - Added detector definitions for GEO, KAGRA, and TAMA

# Release 2.5.8 - March 21, 2018
  - Extended Python interface to support FrSimEvent

# Release 2.5.7 - August 25, 2017
  - Extended Python interface to read a subset of elements of the FrameH structure.
  - Extended Python interface to read type, user, detectSim, detectProc, history,
	auxData, and auxTable values from FrameH structure.

# Release 2.5.6 - February 13, 2017
  - Needed to incriment library version number to reflect binary incompatibility change

# Release 2.5.5 - January 27, 2017
  - Corrected Verify class's file checksum optimization (#4456)
  - Corrected problem with C-Interface comparession (#4490)

# Release 2.5.5 - January 27, 2017
  - Corrected support for reading FrEvent and FrSimEvent structures from
    frame stream (#4954)

# Release 2.5.4 - October 22, 2016
  - Refactored code to support Python subport for Macports

# Release 2.5.3 - October 10, 2016
  - Updated to support Debian Sketch

# Release 2.5.2 - September 9, 2016
  - Added --disable-warnings-as-errors to allow compilation on systems
    where warning messages have not yet been addressed
  - Added FRAMECPP_VERSION to Common/FrameSpec.hh file (#4279)
  - Added conditional setting of DESTDIR in python.mk to prevent install
    issues.
  - Reformatted extended DATA_INVALID error message to make it more readable.
  - Added 'none' as synonym for 'raw' to framecpp_compressor (#4327)
  - Removed verbose error message.

# Release 2.5.1 - April 21, 2016

The following problems have been resolved in this release:
  - Addressed potential infinite recursive call

# Release 2.5.0 - April 7, 2016
  - Split LDASTools into separate source packages

# Release 2.4.99.1 - March 11, 2016
  - Corrections to spec files.

# Release 2.4.99.0 - March 3, 2016
  - Separated code into independant source distribution
