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