LCOV - code coverage report
Current view: top level - frmts/zarr - zarr_v3_codec_crc32c.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 24 38 63.2 %
Date: 2026-02-11 08:43:47 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Zarr driver, "crc32c" codec
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2026, Development Seed
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "zarr_v3_codec.h"
      14             : 
      15             : #include "crc32c.h"
      16             : 
      17             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/crc32c/index.html
      18             : 
      19             : /************************************************************************/
      20             : /*                ZarrV3CodecCRC32C::ZarrV3CodecCRC32C()                */
      21             : /************************************************************************/
      22             : 
      23         773 : ZarrV3CodecCRC32C::ZarrV3CodecCRC32C() : ZarrV3Codec(NAME)
      24             : {
      25         773 : }
      26             : 
      27             : /************************************************************************/
      28             : /*                      ZarrV3CodecCRC32C::Clone()                      */
      29             : /************************************************************************/
      30             : 
      31           0 : std::unique_ptr<ZarrV3Codec> ZarrV3CodecCRC32C::Clone() const
      32             : {
      33           0 :     auto psClone = std::make_unique<ZarrV3CodecCRC32C>();
      34           0 :     ZarrArrayMetadata oOutputArrayMetadata;
      35           0 :     psClone->InitFromConfiguration(m_oConfiguration, m_oInputArrayMetadata,
      36             :                                    oOutputArrayMetadata,
      37             :                                    /* bEmitWarnings = */ false);
      38           0 :     return psClone;
      39             : }
      40             : 
      41             : /************************************************************************/
      42             : /*              ZarrV3CodecCRC32C::InitFromConfiguration()              */
      43             : /************************************************************************/
      44             : 
      45         773 : bool ZarrV3CodecCRC32C::InitFromConfiguration(
      46             :     const CPLJSONObject &configuration,
      47             :     const ZarrArrayMetadata &oInputArrayMetadata,
      48             :     ZarrArrayMetadata &oOutputArrayMetadata, bool /* bEmitWarnings */)
      49             : {
      50         773 :     m_oConfiguration = configuration.Clone();
      51         773 :     m_oInputArrayMetadata = oInputArrayMetadata;
      52         773 :     oOutputArrayMetadata = oInputArrayMetadata;
      53             : 
      54             :     // GDAL extension for tests !!!
      55         773 :     if (!m_oConfiguration.GetBool("check_crc", true))
      56         135 :         m_bCheckCRC = false;
      57             : 
      58         773 :     return true;
      59             : }
      60             : 
      61             : /************************************************************************/
      62             : /*                           ComputeCRC32C()                            */
      63             : /************************************************************************/
      64             : 
      65         168 : static uint32_t ComputeCRC32C(const GByte *pabyIn, size_t nLength)
      66             : {
      67         168 :     crc32c_init();
      68         168 :     return crc32c(0, pabyIn, nLength);
      69             : }
      70             : 
      71             : /************************************************************************/
      72             : /*                     ZarrV3CodecCRC32C::Encode()                      */
      73             : /************************************************************************/
      74             : 
      75           0 : bool ZarrV3CodecCRC32C::Encode(const ZarrByteVectorQuickResize &abySrc,
      76             :                                ZarrByteVectorQuickResize &abyDst) const
      77             : {
      78           0 :     abyDst.clear();
      79           0 :     abyDst.insert(abyDst.end(), abySrc.begin(), abySrc.end());
      80             : 
      81             :     const uint32_t nComputedCRC_le =
      82           0 :         CPL_LSBWORD32(ComputeCRC32C(abySrc.data(), abySrc.size()));
      83           0 :     const GByte *pabyCRC = reinterpret_cast<const GByte *>(&nComputedCRC_le);
      84           0 :     abyDst.insert(abyDst.end(), pabyCRC, pabyCRC + sizeof(uint32_t));
      85             : 
      86           0 :     return true;
      87             : }
      88             : 
      89             : /************************************************************************/
      90             : /*                     ZarrV3CodecCRC32C::Decode()                      */
      91             : /************************************************************************/
      92             : 
      93         303 : bool ZarrV3CodecCRC32C::Decode(const ZarrByteVectorQuickResize &abySrc,
      94             :                                ZarrByteVectorQuickResize &abyDst) const
      95             : {
      96         303 :     if (abySrc.size() < sizeof(uint32_t))
      97             :     {
      98           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      99             :                  "CRC32C decoder: not enough input bytes");
     100           0 :         return false;
     101             :     }
     102             : 
     103         303 :     const size_t nSrcLen = abySrc.size() - sizeof(uint32_t);
     104         303 :     abyDst.clear();
     105         303 :     abyDst.insert(abyDst.end(), abySrc.begin(), abySrc.begin() + nSrcLen);
     106             : 
     107         303 :     if (m_bCheckCRC)
     108             :     {
     109             :         const uint32_t nComputedCRC =
     110         168 :             ComputeCRC32C(abyDst.data(), abyDst.size());
     111         168 :         const uint32_t nExpectedCRC = CPL_LSBUINT32PTR(abySrc.data() + nSrcLen);
     112         168 :         if (nComputedCRC != nExpectedCRC)
     113             :         {
     114          51 :             CPLError(
     115             :                 CE_Failure, CPLE_AppDefined,
     116             :                 "CRC32C decoder: computed CRC value is %08X whereas expected "
     117             :                 "value is %08X",
     118             :                 nComputedCRC, nExpectedCRC);
     119          51 :             return false;
     120             :         }
     121             :     }
     122             : 
     123         252 :     return true;
     124             : }

Generated by: LCOV version 1.14