LCOV - code coverage report
Current view: top level - frmts/nitf - offsetpatcher.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 12 12 100.0 %
Date: 2026-03-05 10:33:42 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  NITF Read/Write Library
       4             :  * Purpose:  Manages writing offsets to file locations
       5             :  * Author:   Even Rouault, even dot rouault at spatialys dot com
       6             :  *
       7             :  **********************************************************************
       8             :  * Copyright (c) 2026, T-Kartor
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef OFFSET_PATCHER_INCLUDED
      14             : #define OFFSET_PATCHER_INCLUDED
      15             : 
      16             : #include "cpl_vsi_virtual.h"
      17             : 
      18             : #include <cstdint>
      19             : 
      20             : #include <map>
      21             : #include <memory>
      22             : #include <string>
      23             : #include <vector>
      24             : 
      25             : namespace GDALOffsetPatcher
      26             : {
      27             : 
      28             : class OffsetPatcher;
      29             : class OffsetPatcherBuffer;
      30             : 
      31             : constexpr vsi_l_offset INVALID_OFFSET = static_cast<vsi_l_offset>(-1);
      32             : 
      33             : /************************************************************************/
      34             : /*                         OffsetOrSizeLocation                         */
      35             : /************************************************************************/
      36             : 
      37             : /** Location of an offset or size */
      38             : struct OffsetOrSizeLocation
      39             : {
      40             :     OffsetPatcherBuffer *buffer = nullptr;
      41             :     size_t offsetInBuffer = 0;
      42             : };
      43             : 
      44             : /************************************************************************/
      45             : /*                        OffsetOrSizeReference                         */
      46             : /************************************************************************/
      47             : 
      48             : /** Reference to an offset or size */
      49             : struct OffsetOrSizeReference
      50             : {
      51             :     OffsetPatcherBuffer *buffer = nullptr;
      52             :     size_t offsetInBuffer = 0;
      53             :     int objectSizeBytes = 0;
      54             :     bool bEndiannessIsLittle = true;
      55             : };
      56             : 
      57             : /************************************************************************/
      58             : /*                       OffsetOrSizeDeclaration                        */
      59             : /************************************************************************/
      60             : 
      61             : /** Declaration of a to-be-resolved offset location or size. */
      62             : class OffsetOrSizeDeclaration
      63             : {
      64             :   public:
      65        1177 :     explicit OffsetOrSizeDeclaration(const std::string &osName,
      66             :                                      bool bRelativeToStartOfBuffer = false)
      67        1177 :         : m_osName(osName), m_bRelativeToStartOfBuffer(bRelativeToStartOfBuffer)
      68             :     {
      69        1177 :     }
      70             : 
      71             :     bool HasAlreadyRegisteredLocation() const
      72             :     {
      73             :         return m_location.buffer != nullptr;
      74             :     }
      75             : 
      76             :     const OffsetOrSizeLocation &GetLocation() const
      77             :     {
      78             :         return m_location;
      79             :     }
      80             : 
      81             :     bool SetLocation(OffsetPatcherBuffer *buffer, size_t offsetInBuffer);
      82             :     void SetReference(OffsetPatcherBuffer *buffer, size_t offsetInBuffer,
      83             :                       int objectSizeBytes, bool bEndiannessIsLittle);
      84             : 
      85             :   private:
      86             :     friend class OffsetPatcher;
      87             : 
      88             :     const std::string m_osName;
      89             :     const bool m_bRelativeToStartOfBuffer;
      90             :     OffsetOrSizeLocation m_location{};
      91             :     std::vector<OffsetOrSizeReference> m_references{};
      92             : };
      93             : 
      94             : /************************************************************************/
      95             : /*                         OffsetPatcherBuffer                          */
      96             : /************************************************************************/
      97             : 
      98             : /** Buffer that can contain unresolved references to an offset in another
      99             :  * buffer or the size of another buffer.
     100             :  */
     101             : class OffsetPatcherBuffer
     102             : {
     103             :   public:
     104         570 :     explicit OffsetPatcherBuffer(const std::string &osName,
     105             :                                  OffsetPatcher &offsetPatcher,
     106             :                                  bool bEndiannessIsLittle)
     107         570 :         : m_osName(osName), m_offsetPatcher(offsetPatcher),
     108         570 :           m_bEndiannessIsLittle(bEndiannessIsLittle)
     109             :     {
     110         570 :     }
     111             : 
     112             :     void AppendUInt32RefForOffset(const std::string &osName,
     113             :                                   bool bRelativeToStartOfBuffer = false);
     114             :     void AppendUInt16RefForSizeOfBuffer(const std::string &osBufferName);
     115             :     void AppendUInt32RefForSizeOfBuffer(const std::string &osBufferName);
     116             :     void AppendByte(uint8_t byVal);
     117             :     void AppendUInt16(uint16_t nVal);
     118             :     void AppendUInt32(uint32_t nVal);
     119             :     void AppendFloat64(double dfVal);
     120             :     void AppendString(const std::string &s);
     121             : 
     122             :     bool DeclareOffsetAtCurrentPosition(const std::string &osName);
     123             : 
     124             :     void DeclareBufferWrittenAtPosition(vsi_l_offset nFileOffset);
     125             : 
     126        3046 :     const std::vector<uint8_t> &GetBuffer() const
     127             :     {
     128        3046 :         return m_abyBuffer;
     129             :     }
     130             : 
     131             :     vsi_l_offset GetFileLocation() const
     132             :     {
     133             :         return m_nOffset;
     134             :     }
     135             : 
     136             :   private:
     137             :     friend class OffsetPatcher;
     138             : 
     139             :     const std::string m_osName;
     140             :     OffsetPatcher &m_offsetPatcher;
     141             :     const bool m_bEndiannessIsLittle;
     142             :     std::vector<uint8_t> m_abyBuffer{};
     143             :     vsi_l_offset m_nOffset = INVALID_OFFSET;
     144             : 
     145       28967 :     bool NeedByteSwap() const
     146             :     {
     147             : #if CPL_IS_LSB
     148       28967 :         return !m_bEndiannessIsLittle;
     149             : #else
     150             :         return m_bEndiannessIsLittle;
     151             : #endif
     152             :     }
     153             : };
     154             : 
     155             : /************************************************************************/
     156             : /*                            OffsetPatcher                             */
     157             : /************************************************************************/
     158             : 
     159             : /** Higher level class managing buffers, offset and sizes declarations */
     160             : class OffsetPatcher
     161             : {
     162             :   public:
     163         161 :     OffsetPatcher() = default;
     164             : 
     165             :     OffsetPatcherBuffer *CreateBuffer(const std::string &osName,
     166             :                                       bool bEndiannessIsLittle);
     167             : 
     168             :     OffsetPatcherBuffer *GetBufferFromName(const std::string &osName) const;
     169             :     OffsetOrSizeDeclaration *
     170             :     GetOffsetDeclaration(const std::string &osName) const;
     171             : 
     172             :     bool Finalize(VSILFILE *fp);
     173             : 
     174             :   private:
     175             :     friend class OffsetPatcherBuffer;
     176             : 
     177             :     std::map<std::string, std::unique_ptr<OffsetPatcherBuffer>> m_buffers{};
     178             :     std::map<std::string, std::unique_ptr<OffsetOrSizeDeclaration>> m_offsets{};
     179             :     std::map<std::string, std::unique_ptr<OffsetOrSizeDeclaration>> m_sizes{};
     180             : 
     181             :     OffsetPatcher(const OffsetPatcher &) = delete;
     182             :     OffsetPatcher &operator=(const OffsetPatcher &) = delete;
     183             : };
     184             : 
     185             : }  // namespace GDALOffsetPatcher
     186             : 
     187             : #endif  // OFFSET_PATCHER_INCLUDED

Generated by: LCOV version 1.14