1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  Defines OGRLayerPool and OGRProxiedLayer class
5  * Author:   Even Rouault, even dot rouault at spatialys.com
6  *
7  ******************************************************************************
8  * Copyright (c) 2012-2013, Even Rouault <even dot rouault at spatialys.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #ifndef DOXYGEN_SKIP
30 
31 #include "ogrlayerpool.h"
32 
33 CPL_CVSID("$Id: ogrlayerpool.cpp 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $")
34 
35 /************************************************************************/
36 /*                      OGRAbstractProxiedLayer()                       */
37 /************************************************************************/
38 
OGRAbstractProxiedLayer(OGRLayerPool * poPoolIn)39 OGRAbstractProxiedLayer::OGRAbstractProxiedLayer( OGRLayerPool* poPoolIn ) :
40     poPrevLayer(nullptr),
41     poNextLayer(nullptr),
42     poPool(poPoolIn)
43 {
44     CPLAssert(poPoolIn != nullptr);
45 }
46 
47 /************************************************************************/
48 /*                     ~OGRAbstractProxiedLayer()                       */
49 /************************************************************************/
50 
~OGRAbstractProxiedLayer()51 OGRAbstractProxiedLayer::~OGRAbstractProxiedLayer()
52 {
53     /* Remove us from the list of LRU layers if necessary */
54     poPool->UnchainLayer(this);
55 }
56 
57 /************************************************************************/
58 /*                            OGRLayerPool()                            */
59 /************************************************************************/
60 
OGRLayerPool(int nMaxSimultaneouslyOpenedIn)61 OGRLayerPool::OGRLayerPool(int nMaxSimultaneouslyOpenedIn) :
62     poMRULayer(nullptr),
63     poLRULayer(nullptr),
64     nMRUListSize(0),
65     nMaxSimultaneouslyOpened(nMaxSimultaneouslyOpenedIn)
66 {}
67 
68 /************************************************************************/
69 /*                           ~OGRLayerPool()                            */
70 /************************************************************************/
71 
~OGRLayerPool()72 OGRLayerPool::~OGRLayerPool()
73 {
74     CPLAssert( poMRULayer == nullptr );
75     CPLAssert( poLRULayer == nullptr );
76     CPLAssert( nMRUListSize == 0 );
77 }
78 
79 /************************************************************************/
80 /*                          SetLastUsedLayer()                          */
81 /************************************************************************/
82 
SetLastUsedLayer(OGRAbstractProxiedLayer * poLayer)83 void OGRLayerPool::SetLastUsedLayer(OGRAbstractProxiedLayer* poLayer)
84 {
85     /* If we are already the MRU layer, nothing to do */
86     if (poLayer == poMRULayer)
87         return;
88 
89     //CPLDebug("OGR", "SetLastUsedLayer(%s)", poLayer->GetName());
90 
91     if (poLayer->poPrevLayer != nullptr || poLayer->poNextLayer != nullptr)
92     {
93         /* Remove current layer from its current place in the list */
94         UnchainLayer(poLayer);
95     }
96     else if (nMRUListSize == nMaxSimultaneouslyOpened)
97     {
98         /* If we have reached the maximum allowed number of layers */
99         /* simultaneously opened, then close the LRU one that */
100         /* was still active until now */
101         CPLAssert(poLRULayer != nullptr);
102 
103         poLRULayer->CloseUnderlyingLayer();
104         UnchainLayer(poLRULayer);
105     }
106 
107     /* Put current layer on top of MRU list */
108     CPLAssert(poLayer->poPrevLayer == nullptr);
109     CPLAssert(poLayer->poNextLayer == nullptr);
110     poLayer->poNextLayer = poMRULayer;
111     if (poMRULayer != nullptr)
112     {
113         CPLAssert(poMRULayer->poPrevLayer == nullptr);
114         poMRULayer->poPrevLayer = poLayer;
115     }
116     poMRULayer = poLayer;
117     if (poLRULayer == nullptr)
118         poLRULayer = poLayer;
119     nMRUListSize ++;
120 }
121 
122 /************************************************************************/
123 /*                           UnchainLayer()                             */
124 /************************************************************************/
125 
UnchainLayer(OGRAbstractProxiedLayer * poLayer)126 void OGRLayerPool::UnchainLayer(OGRAbstractProxiedLayer* poLayer)
127 {
128     OGRAbstractProxiedLayer* poPrevLayer = poLayer->poPrevLayer;
129     OGRAbstractProxiedLayer* poNextLayer = poLayer->poNextLayer;
130 
131     CPLAssert(poPrevLayer == nullptr || poPrevLayer->poNextLayer == poLayer);
132     CPLAssert(poNextLayer == nullptr || poNextLayer->poPrevLayer == poLayer);
133 
134     if (poPrevLayer != nullptr || poNextLayer != nullptr || poLayer == poMRULayer)
135         nMRUListSize --;
136 
137     if (poLayer == poMRULayer)
138         poMRULayer = poNextLayer;
139     if (poLayer == poLRULayer)
140         poLRULayer = poPrevLayer;
141     if (poPrevLayer != nullptr)
142         poPrevLayer->poNextLayer = poNextLayer;
143     if (poNextLayer != nullptr)
144         poNextLayer->poPrevLayer = poPrevLayer;
145     poLayer->poPrevLayer = nullptr;
146     poLayer->poNextLayer = nullptr;
147 }
148 
149 /************************************************************************/
150 /*                          OGRProxiedLayer()                           */
151 /************************************************************************/
152 
OGRProxiedLayer(OGRLayerPool * poPoolIn,OpenLayerFunc pfnOpenLayerIn,FreeUserDataFunc pfnFreeUserDataIn,void * pUserDataIn)153 OGRProxiedLayer::OGRProxiedLayer( OGRLayerPool* poPoolIn,
154                                   OpenLayerFunc pfnOpenLayerIn,
155                                   FreeUserDataFunc pfnFreeUserDataIn,
156                                   void* pUserDataIn ) :
157     OGRAbstractProxiedLayer(poPoolIn),
158     pfnOpenLayer(pfnOpenLayerIn),
159     pfnFreeUserData(pfnFreeUserDataIn),
160     pUserData(pUserDataIn),
161     poUnderlyingLayer(nullptr),
162     poFeatureDefn(nullptr),
163     poSRS(nullptr)
164 {
165     CPLAssert(pfnOpenLayerIn != nullptr);
166 }
167 
168 /************************************************************************/
169 /*                         ~OGRProxiedLayer()                           */
170 /************************************************************************/
171 
~OGRProxiedLayer()172 OGRProxiedLayer::~OGRProxiedLayer()
173 {
174     delete poUnderlyingLayer;
175 
176     if( poSRS )
177         poSRS->Release();
178 
179     if( poFeatureDefn )
180         poFeatureDefn->Release();
181 
182     if( pfnFreeUserData != nullptr )
183         pfnFreeUserData(pUserData);
184 }
185 
186 /************************************************************************/
187 /*                       OpenUnderlyingLayer()                          */
188 /************************************************************************/
189 
OpenUnderlyingLayer()190 int OGRProxiedLayer::OpenUnderlyingLayer()
191 {
192     CPLDebug("OGR", "OpenUnderlyingLayer(%p)", this);
193     CPLAssert(poUnderlyingLayer == nullptr);
194     poPool->SetLastUsedLayer(this);
195     poUnderlyingLayer = pfnOpenLayer(pUserData);
196     if( poUnderlyingLayer == nullptr )
197     {
198         CPLError(CE_Failure, CPLE_FileIO,
199                  "Cannot open underlying layer");
200     }
201     return poUnderlyingLayer != nullptr;
202 }
203 
204 /************************************************************************/
205 /*                         CloseUnderlyingLayer()                       */
206 /************************************************************************/
207 
CloseUnderlyingLayer()208 void OGRProxiedLayer::CloseUnderlyingLayer()
209 {
210     CPLDebug("OGR", "CloseUnderlyingLayer(%p)", this);
211     delete poUnderlyingLayer;
212     poUnderlyingLayer = nullptr;
213 }
214 
215 /************************************************************************/
216 /*                          GetUnderlyingLayer()                        */
217 /************************************************************************/
218 
GetUnderlyingLayer()219 OGRLayer* OGRProxiedLayer::GetUnderlyingLayer()
220 {
221     if( poUnderlyingLayer == nullptr )
222     {
223         //  If the open fails, poUnderlyingLayer will still be a nullptr
224         // and the user will be warned by the open call.
225         // coverity[check_return]
226         OpenUnderlyingLayer();
227     }
228     return poUnderlyingLayer;
229 }
230 
231 /************************************************************************/
232 /*                          GetSpatialFilter()                          */
233 /************************************************************************/
234 
GetSpatialFilter()235 OGRGeometry *OGRProxiedLayer::GetSpatialFilter()
236 {
237     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return nullptr;
238     return poUnderlyingLayer->GetSpatialFilter();
239 }
240 
241 /************************************************************************/
242 /*                          SetSpatialFilter()                          */
243 /************************************************************************/
244 
SetSpatialFilter(OGRGeometry * poGeom)245 void        OGRProxiedLayer::SetSpatialFilter( OGRGeometry * poGeom )
246 {
247     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return;
248     poUnderlyingLayer->SetSpatialFilter(poGeom);
249 }
250 
251 /************************************************************************/
252 /*                          SetSpatialFilter()                          */
253 /************************************************************************/
254 
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)255 void        OGRProxiedLayer::SetSpatialFilter( int iGeomField, OGRGeometry * poGeom )
256 {
257     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return;
258     poUnderlyingLayer->SetSpatialFilter(iGeomField, poGeom);
259 }
260 /************************************************************************/
261 /*                          SetAttributeFilter()                        */
262 /************************************************************************/
263 
SetAttributeFilter(const char * poAttrFilter)264 OGRErr      OGRProxiedLayer::SetAttributeFilter( const char * poAttrFilter )
265 {
266     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
267     return poUnderlyingLayer->SetAttributeFilter(poAttrFilter);
268 }
269 
270 /************************************************************************/
271 /*                            ResetReading()                            */
272 /************************************************************************/
273 
ResetReading()274 void        OGRProxiedLayer::ResetReading()
275 {
276     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return;
277     poUnderlyingLayer->ResetReading();
278 }
279 
280 /************************************************************************/
281 /*                           GetNextFeature()                           */
282 /************************************************************************/
283 
GetNextFeature()284 OGRFeature *OGRProxiedLayer::GetNextFeature()
285 {
286     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return nullptr;
287     return poUnderlyingLayer->GetNextFeature();
288 }
289 
290 /************************************************************************/
291 /*                           SetNextByIndex()                           */
292 /************************************************************************/
293 
SetNextByIndex(GIntBig nIndex)294 OGRErr      OGRProxiedLayer::SetNextByIndex( GIntBig nIndex )
295 {
296     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
297     return poUnderlyingLayer->SetNextByIndex(nIndex);
298 }
299 
300 /************************************************************************/
301 /*                             GetFeature()                             */
302 /************************************************************************/
303 
GetFeature(GIntBig nFID)304 OGRFeature *OGRProxiedLayer::GetFeature( GIntBig nFID )
305 {
306     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return nullptr;
307     return poUnderlyingLayer->GetFeature(nFID);
308 }
309 
310 /************************************************************************/
311 /*                             ISetFeature()                             */
312 /************************************************************************/
313 
ISetFeature(OGRFeature * poFeature)314 OGRErr      OGRProxiedLayer::ISetFeature( OGRFeature *poFeature )
315 {
316     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
317     return poUnderlyingLayer->SetFeature(poFeature);
318 }
319 
320 /************************************************************************/
321 /*                            ICreateFeature()                           */
322 /************************************************************************/
323 
ICreateFeature(OGRFeature * poFeature)324 OGRErr      OGRProxiedLayer::ICreateFeature( OGRFeature *poFeature )
325 {
326     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
327     return poUnderlyingLayer->CreateFeature(poFeature);
328 }
329 
330 /************************************************************************/
331 /*                           DeleteFeature()                            */
332 /************************************************************************/
333 
DeleteFeature(GIntBig nFID)334 OGRErr      OGRProxiedLayer::DeleteFeature( GIntBig nFID )
335 {
336     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
337     return poUnderlyingLayer->DeleteFeature(nFID);
338 }
339 
340 /************************************************************************/
341 /*                             GetName()                                */
342 /************************************************************************/
343 
GetName()344 const char *OGRProxiedLayer::GetName()
345 {
346     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return "";
347     return poUnderlyingLayer->GetName();
348 }
349 
350 /************************************************************************/
351 /*                            GetGeomType()                             */
352 /************************************************************************/
353 
GetGeomType()354 OGRwkbGeometryType OGRProxiedLayer::GetGeomType()
355 {
356     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return wkbUnknown;
357     return poUnderlyingLayer->GetGeomType();
358 }
359 
360 /************************************************************************/
361 /*                            GetLayerDefn()                            */
362 /************************************************************************/
363 
GetLayerDefn()364 OGRFeatureDefn *OGRProxiedLayer::GetLayerDefn()
365 {
366     if( poFeatureDefn != nullptr )
367         return poFeatureDefn;
368 
369     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() )
370     {
371         poFeatureDefn = new OGRFeatureDefn("");
372     }
373     else
374     {
375         poFeatureDefn = poUnderlyingLayer->GetLayerDefn();
376     }
377 
378     poFeatureDefn->Reference();
379 
380     return poFeatureDefn;
381 }
382 
383 /************************************************************************/
384 /*                            GetSpatialRef()                           */
385 /************************************************************************/
386 
GetSpatialRef()387 OGRSpatialReference *OGRProxiedLayer::GetSpatialRef()
388 {
389     if( poSRS != nullptr )
390         return poSRS;
391     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return nullptr;
392     OGRSpatialReference* poRet = poUnderlyingLayer->GetSpatialRef();
393     if( poRet != nullptr )
394     {
395         poSRS = poRet;
396         poSRS->Reference();
397     }
398     return poRet;
399 }
400 
401 /************************************************************************/
402 /*                          GetFeatureCount()                           */
403 /************************************************************************/
404 
GetFeatureCount(int bForce)405 GIntBig         OGRProxiedLayer::GetFeatureCount( int bForce )
406 {
407     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return 0;
408     return poUnderlyingLayer->GetFeatureCount(bForce);
409 }
410 
411 /************************************************************************/
412 /*                             GetExtent()                              */
413 /************************************************************************/
414 
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)415 OGRErr      OGRProxiedLayer::GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce)
416 {
417     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
418     return poUnderlyingLayer->GetExtent(iGeomField, psExtent, bForce);
419 }
420 
421 /************************************************************************/
422 /*                             GetExtent()                              */
423 /************************************************************************/
424 
GetExtent(OGREnvelope * psExtent,int bForce)425 OGRErr      OGRProxiedLayer::GetExtent(OGREnvelope *psExtent, int bForce)
426 {
427     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
428     return poUnderlyingLayer->GetExtent(psExtent, bForce);
429 }
430 
431 /************************************************************************/
432 /*                           TestCapability()                           */
433 /************************************************************************/
434 
TestCapability(const char * pszCapability)435 int         OGRProxiedLayer::TestCapability( const char * pszCapability )
436 {
437     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return FALSE;
438     return poUnderlyingLayer->TestCapability(pszCapability);
439 }
440 
441 /************************************************************************/
442 /*                            CreateField()                             */
443 /************************************************************************/
444 
CreateField(OGRFieldDefn * poField,int bApproxOK)445 OGRErr      OGRProxiedLayer::CreateField( OGRFieldDefn *poField,
446                                             int bApproxOK )
447 {
448     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
449     return poUnderlyingLayer->CreateField(poField, bApproxOK);
450 }
451 
452 /************************************************************************/
453 /*                            DeleteField()                             */
454 /************************************************************************/
455 
DeleteField(int iField)456 OGRErr      OGRProxiedLayer::DeleteField( int iField )
457 {
458     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
459     return poUnderlyingLayer->DeleteField(iField);
460 }
461 
462 /************************************************************************/
463 /*                            ReorderFields()                           */
464 /************************************************************************/
465 
ReorderFields(int * panMap)466 OGRErr      OGRProxiedLayer::ReorderFields( int* panMap )
467 {
468     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
469     return poUnderlyingLayer->ReorderFields(panMap);
470 }
471 
472 /************************************************************************/
473 /*                           AlterFieldDefn()                           */
474 /************************************************************************/
475 
AlterFieldDefn(int iField,OGRFieldDefn * poNewFieldDefn,int nFlagsIn)476 OGRErr      OGRProxiedLayer::AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlagsIn )
477 {
478     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
479     return poUnderlyingLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
480 }
481 
482 /************************************************************************/
483 /*                            SyncToDisk()                              */
484 /************************************************************************/
485 
SyncToDisk()486 OGRErr      OGRProxiedLayer::SyncToDisk()
487 {
488     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
489     return poUnderlyingLayer->SyncToDisk();
490 }
491 
492 /************************************************************************/
493 /*                           GetStyleTable()                            */
494 /************************************************************************/
495 
GetStyleTable()496 OGRStyleTable *OGRProxiedLayer::GetStyleTable()
497 {
498     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return nullptr;
499     return poUnderlyingLayer->GetStyleTable();
500 }
501 
502 /************************************************************************/
503 /*                       SetStyleTableDirectly()                        */
504 /************************************************************************/
505 
SetStyleTableDirectly(OGRStyleTable * poStyleTable)506 void        OGRProxiedLayer::SetStyleTableDirectly( OGRStyleTable *poStyleTable )
507 {
508     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return;
509     return poUnderlyingLayer->SetStyleTableDirectly(poStyleTable);
510 }
511 
512 /************************************************************************/
513 /*                           SetStyleTable()                            */
514 /************************************************************************/
515 
SetStyleTable(OGRStyleTable * poStyleTable)516 void        OGRProxiedLayer::SetStyleTable(OGRStyleTable *poStyleTable)
517 {
518     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return;
519     return poUnderlyingLayer->SetStyleTable(poStyleTable);
520 }
521 
522 /************************************************************************/
523 /*                          StartTransaction()                          */
524 /************************************************************************/
525 
StartTransaction()526 OGRErr      OGRProxiedLayer::StartTransaction()
527 {
528     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
529     return poUnderlyingLayer->StartTransaction();
530 }
531 
532 /************************************************************************/
533 /*                          CommitTransaction()                         */
534 /************************************************************************/
535 
CommitTransaction()536 OGRErr      OGRProxiedLayer::CommitTransaction()
537 {
538     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
539     return poUnderlyingLayer->CommitTransaction();
540 }
541 
542 /************************************************************************/
543 /*                        RollbackTransaction()                         */
544 /************************************************************************/
545 
RollbackTransaction()546 OGRErr      OGRProxiedLayer::RollbackTransaction()
547 {
548     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
549     return poUnderlyingLayer->RollbackTransaction();
550 }
551 
552 /************************************************************************/
553 /*                            GetFIDColumn()                            */
554 /************************************************************************/
555 
GetFIDColumn()556 const char *OGRProxiedLayer::GetFIDColumn()
557 {
558     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return "";
559     return poUnderlyingLayer->GetFIDColumn();
560 }
561 
562 /************************************************************************/
563 /*                          GetGeometryColumn()                         */
564 /************************************************************************/
565 
GetGeometryColumn()566 const char *OGRProxiedLayer::GetGeometryColumn()
567 {
568     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return "";
569     return poUnderlyingLayer->GetGeometryColumn();
570 }
571 
572 /************************************************************************/
573 /*                          SetIgnoredFields()                          */
574 /************************************************************************/
575 
SetIgnoredFields(const char ** papszFields)576 OGRErr      OGRProxiedLayer::SetIgnoredFields( const char **papszFields )
577 {
578     if( poUnderlyingLayer == nullptr && !OpenUnderlyingLayer() ) return OGRERR_FAILURE;
579     return poUnderlyingLayer->SetIgnoredFields(papszFields);
580 }
581 
582 #endif /* #ifndef DOXYGEN_SKIP */
583