Coverage Report

Created: 2025-12-31 08:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/dxf/ogrdxfblockslayer.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  DXF Translator
4
 * Purpose:  Implements OGRDXFBlocksLayer class.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2010, Frank Warmerdam <warmerdam@pobox.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "ogr_dxf.h"
14
#include "cpl_conv.h"
15
16
/************************************************************************/
17
/*                         OGRDXFBlocksLayer()                          */
18
/************************************************************************/
19
20
OGRDXFBlocksLayer::OGRDXFBlocksLayer(OGRDXFDataSource *poDSIn)
21
0
    : poDS(poDSIn), poFeatureDefn(new OGRFeatureDefn("blocks")), iNextFID(0)
22
0
{
23
0
    OGRDXFBlocksLayer::ResetReading();
24
25
0
    poFeatureDefn->Reference();
26
27
0
    int nModes = ODFM_None;
28
0
    if (!poDS->InlineBlocks())
29
0
        nModes |= ODFM_IncludeBlockFields;
30
0
    if (poDS->ShouldIncludeRawCodeValues())
31
0
        nModes |= ODFM_IncludeRawCodeValues;
32
0
    if (poDS->In3DExtensibleMode())
33
0
        nModes |= ODFM_Include3DModeFields;
34
0
    OGRDXFDataSource::AddStandardFields(poFeatureDefn, nModes);
35
0
}
36
37
/************************************************************************/
38
/*                         ~OGRDXFBlocksLayer()                         */
39
/************************************************************************/
40
41
OGRDXFBlocksLayer::~OGRDXFBlocksLayer()
42
43
0
{
44
0
    if (m_nFeaturesRead > 0 && poFeatureDefn != nullptr)
45
0
    {
46
0
        CPLDebug("DXF", "%d features read on layer '%s'.", (int)m_nFeaturesRead,
47
0
                 poFeatureDefn->GetName());
48
0
    }
49
50
0
    if (poFeatureDefn)
51
0
        poFeatureDefn->Release();
52
53
0
    while (!apoPendingFeatures.empty())
54
0
    {
55
0
        delete apoPendingFeatures.front();
56
0
        apoPendingFeatures.pop();
57
0
    }
58
0
}
59
60
/************************************************************************/
61
/*                            ResetReading()                            */
62
/************************************************************************/
63
64
void OGRDXFBlocksLayer::ResetReading()
65
66
0
{
67
0
    iNextFID = 0;
68
0
    while (!apoPendingFeatures.empty())
69
0
    {
70
0
        OGRDXFFeature *poFeature = apoPendingFeatures.front();
71
0
        apoPendingFeatures.pop();
72
0
        delete poFeature;
73
0
    }
74
0
    oIt = poDS->GetBlockMap().begin();
75
0
}
76
77
/************************************************************************/
78
/*                      GetNextUnfilteredFeature()                      */
79
/************************************************************************/
80
81
OGRDXFFeature *OGRDXFBlocksLayer::GetNextUnfilteredFeature()
82
83
0
{
84
0
    OGRDXFFeature *poFeature = nullptr;
85
86
    /* -------------------------------------------------------------------- */
87
    /*      If we have pending features, return one of them.                */
88
    /* -------------------------------------------------------------------- */
89
0
    if (!apoPendingFeatures.empty())
90
0
    {
91
0
        poFeature = apoPendingFeatures.front();
92
0
        apoPendingFeatures.pop();
93
94
0
        poFeature->SetFID(iNextFID++);
95
0
        poFeature->SetField("Block", osBlockName.c_str());
96
0
        if (poFeature->GetAttributeTag() != "")
97
0
        {
98
0
            poFeature->SetField("AttributeTag", poFeature->GetAttributeTag());
99
0
        }
100
101
0
        m_nFeaturesRead++;
102
0
        return poFeature;
103
0
    }
104
105
    /* -------------------------------------------------------------------- */
106
    /*      Are we out of features?                                         */
107
    /* -------------------------------------------------------------------- */
108
0
    while (oIt != poDS->GetBlockMap().end())
109
0
    {
110
0
        poFeature = new OGRDXFFeature(poFeatureDefn);
111
112
        // Let's insert this block at the origin with no rotation and scale.
113
0
        OGRDXFLayer oTempLayer(poDS);
114
0
        poFeature = oTempLayer.InsertBlockInline(
115
0
            CPLGetErrorCounter(), oIt->first, OGRDXFInsertTransformer(),
116
0
            poFeature, apoPendingFeatures, false,
117
0
            poDS->ShouldMergeBlockGeometries());
118
119
0
        osBlockName = oIt->first;
120
0
        ++oIt;
121
122
0
        if (!poFeature)
123
0
        {
124
0
            if (apoPendingFeatures.empty())
125
0
            {
126
                // This block must have been empty. Move onto the next block
127
0
                continue;
128
0
            }
129
0
            else
130
0
            {
131
0
                poFeature = apoPendingFeatures.front();
132
0
                apoPendingFeatures.pop();
133
0
            }
134
0
        }
135
136
0
        poFeature->SetFID(iNextFID++);
137
0
        poFeature->SetField("Block", osBlockName.c_str());
138
0
        if (poFeature->GetAttributeTag() != "")
139
0
        {
140
0
            poFeature->SetField("AttributeTag", poFeature->GetAttributeTag());
141
0
        }
142
143
0
        m_nFeaturesRead++;
144
0
        return poFeature;
145
0
    }
146
147
    // No more blocks left.
148
0
    return nullptr;
149
0
}
150
151
/************************************************************************/
152
/*                           GetNextFeature()                           */
153
/************************************************************************/
154
155
OGRFeature *OGRDXFBlocksLayer::GetNextFeature()
156
157
0
{
158
0
    while (true)
159
0
    {
160
0
        OGRFeature *poFeature = GetNextUnfilteredFeature();
161
162
0
        if (poFeature == nullptr)
163
0
            return nullptr;
164
165
0
        if ((m_poFilterGeom == nullptr ||
166
0
             FilterGeometry(poFeature->GetGeometryRef())) &&
167
0
            (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
168
0
        {
169
0
            return poFeature;
170
0
        }
171
172
0
        delete poFeature;
173
0
    }
174
0
}
175
176
/************************************************************************/
177
/*                           TestCapability()                           */
178
/************************************************************************/
179
180
int OGRDXFBlocksLayer::TestCapability(const char *pszCap) const
181
182
0
{
183
0
    return EQUAL(pszCap, OLCStringsAsUTF8);
184
0
}