/****************************************************************************** * Project: PROJ.4 * Purpose: Memory management for proj.4. * This version includes an implementation of generic destructors, * for memory deallocation for the large majority of PJ-objects * that do not allocate anything else than the PJ-object itself, * and its associated opaque object - i.e. no additional malloc'ed * memory inside the opaque object. * * Author: Gerald I. Evenden (Original proj.4 author), * Frank Warmerdam (2000) pj_malloc? * Thomas Knudsen (2016) - freeup/dealloc parts * ****************************************************************************** * Copyright (c) 2000, Frank Warmerdam * Copyright (c) 2016, Thomas Knudsen / SDFE * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef FROM_PROJ_CPP #define FROM_PROJ_CPP #endif /* allocate and deallocate memory */ /* These routines are used so that applications can readily replace ** projection system memory allocation/deallocation call with custom ** application procedures. */ #include #include #include #include #include #include "proj/internal/io_internal.hpp" #include "proj.h" #include "proj_internal.h" #include "grids.hpp" #include "filemanager.hpp" using namespace NS_PROJ; /**********************************************************************/ char *pj_strdup(const char *str) /**********************************************************************/ { size_t len = strlen(str) + 1; char *dup = static_cast(malloc(len)); if (dup) memcpy(dup, str, len); return dup; } /*****************************************************************************/ void *free_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { /***************************************************************************** Companion to pj_default_destructor (below). Deallocates a linked list of "+proj=xxx" initialization parameters. Also called from pj_init_ctx when encountering errors before the PJ proper is allocated. ******************************************************************************/ paralist *t, *n; for (t = start; t; t = n) { n = t->next; free(t); } proj_context_errno_set (ctx, errlev); return (void *) nullptr; } /************************************************************************/ /* proj_destroy() */ /* */ /* This is the application callable entry point for destroying */ /* a projection definition. It does work generic to all */ /* projection types, and then calls the projection specific */ /* free function, P->destructor(), to do local work. */ /* In most cases P->destructor()==pj_default_destructor. */ /************************************************************************/ PJ *proj_destroy(PJ *P) { if (nullptr==P || !P->destructor) return nullptr; /* free projection parameters - all the hard work is done by */ /* pj_default_destructor, which is supposed */ /* to be called as the last step of the local destructor */ /* pointed to by P->destructor. In most cases, */ /* pj_default_destructor actually *is* what is pointed to */ P->destructor (P, proj_errno(P)); return nullptr; } /*****************************************************************************/ // cppcheck-suppress uninitMemberVar PJconsts::PJconsts(): destructor(pj_default_destructor) {} /*****************************************************************************/ /*****************************************************************************/ PJ *pj_new() { /*****************************************************************************/ return new(std::nothrow) PJ(); } /*****************************************************************************/ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ /***************************************************************************** Does memory deallocation for "plain" PJ objects, i.e. that vast majority of PJs where the opaque object does not contain any additionally allocated memory below the P->opaque level. ******************************************************************************/ /* Even if P==0, we set the errlev on pj_error and the default context */ /* Note that both, in the multithreaded case, may then contain undefined */ /* values. This is expected behavior. For MT have one ctx per thread */ if (0!=errlev) proj_context_errno_set (pj_get_ctx(P), errlev); if (nullptr==P) return nullptr; free(P->def_size); free(P->def_shape); free(P->def_spherification); free(P->def_ellps); delete static_cast(P->hgrids_legacy); delete static_cast(P->vgrids_legacy); /* We used to call free( P->catalog ), but this will leak */ /* memory. The safe way to clear catalog and grid is to call */ /* pj_gc_unloadall(pj_get_default_ctx()); and freeate_grids(); */ /* TODO: we should probably have a public pj_cleanup() method to do all */ /* that */ /* free the interface to Charles Karney's geodesic library */ free( P->geod ); /* free parameter list elements */ free_params (pj_get_ctx(P), P->params, errlev); free (P->def_full); /* free the cs2cs emulation elements */ proj_destroy (P->axisswap); proj_destroy (P->helmert); proj_destroy (P->cart); proj_destroy (P->cart_wgs84); proj_destroy (P->hgridshift); proj_destroy (P->vgridshift); free (static_cast(P->opaque)); delete P; return nullptr; } /*****************************************************************************/ void proj_cleanup() { /*****************************************************************************/ // Close the database context of the default PJ_CONTEXT auto cpp_context = pj_get_default_ctx()->cpp_context; if( cpp_context ) { cpp_context->closeDb(); } pj_clear_initcache(); FileManager::clearMemoryCache(); pj_clear_hgridshift_knowngrids_cache(); pj_clear_vgridshift_knowngrids_cache(); pj_clear_sqlite_cache(); }