Changeset 816

Show
Ignore:
Timestamp:
07/30/08 20:04:36 (5 months ago)
Author:
mloskot
Message:

Fixed number of memory leaks (Ticket #63). Added detail::raii_wrapper class and used it to fix memory leaks in RAII way.

Location:
trunk
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/include/liblas/detail/utility.hpp

    r814 r816  
    6767namespace liblas { namespace detail { 
    6868 
     69/// Simple RAII wrapper. 
     70/// It's dedicated to use with types associated with custom deleter, 
     71/// opaque pointers and C API objects. 
     72template <typename T> 
     73class raii_wrapper 
     74{ 
     75    typedef void(*deleter_type)(T* p); 
     76 
     77public: 
     78 
     79    raii_wrapper(T* p, deleter_type d) 
     80        : p_(p), del_(d) 
     81    { 
     82        assert(0 != p_); 
     83        assert(0 != del_); 
     84    } 
     85 
     86    ~raii_wrapper() 
     87    { 
     88        do_delete(p_); 
     89    } 
     90 
     91    void reset(T* p) 
     92    { 
     93        do_delete(p_); 
     94        p_= p; 
     95    } 
     96 
     97    T* get() const 
     98    { 
     99        return p_; 
     100    } 
     101 
     102    void swap(raii_wrapper& other) 
     103    { 
     104        std::swap(p_, other.p_); 
     105    } 
     106 
     107private: 
     108 
     109    raii_wrapper(raii_wrapper const& other); 
     110    raii_wrapper& operator=(raii_wrapper const& rhs); 
     111 
     112    void do_delete(T* p) 
     113    { 
     114        assert(del_); 
     115        if (0 != p) 
     116            del_(p); 
     117    } 
     118 
     119    T* p_; 
     120    deleter_type del_; 
     121}; 
     122 
     123 
     124/// Definition of variable-length record header. 
    69125struct VLRHeader 
    70126{ 
  • trunk/include/liblas/lasrecordheader.hpp

    r813 r816  
    154154 
    155155#endif // LIBLAS_LASRECORDHEADER_HPP_INCLUDED 
     156 
  • trunk/src/detail/reader10.cpp

    r813 r816  
    4646#include <liblas/lasheader.hpp> 
    4747#include <liblas/laspoint.hpp> 
    48  
     48// GeoTIFF 
    4949#ifdef HAVE_LIBGEOTIFF 
    5050#include <geotiff.h> 
     
    5353#include "geo_simpletags.h" 
    5454#include "geovalues.h" 
    55 #endif /* HAVE_LIBGEOTIFF */ 
    56  
     55#endif // HAVE_LIBGEOTIFF 
    5756// std 
    5857#include <fstream> 
    5958#include <iostream> 
    60 #include <cstdlib> // std::size_t 
     59#include <stdexcept> 
     60#include <cstdlib> // std::size_t, std::free 
    6161#include <cassert> 
    62 #include <stdexcept> 
    6362 
    6463namespace liblas { namespace detail { namespace v10 { 
     
    214213} 
    215214 
    216 bool ReaderImpl::ReadVLR(LASHeader& header) { 
    217      
     215bool ReaderImpl::ReadVLR(LASHeader& header) 
     216{ 
    218217    VLRHeader vlrh = { 0 }; 
    219218 
     
    250249#ifndef HAVE_LIBGEOTIFF 
    251250    UNREFERENCED_PARAMETER(header); 
    252     return false; 
    253251#else 
    254     // TODO: Under construction 
    255252 
    256253    std::string const uid("LASF_Projection"); 
    257     ST_TIFF *st = ST_Create(); 
     254 
     255    detail::raii_wrapper<ST_TIFF> st(ST_Create(), ST_Destroy); 
    258256 
    259257    for (uint16_t i = 0; i < header.GetRecordsCount(); ++i) 
     
    264262        { 
    265263            int16_t count = data.size()/sizeof(int16_t); 
    266             ST_SetKey( st, record.GetRecordId(), count, STT_SHORT,  
    267                        &(data[0]) ); 
     264            ST_SetKey(st.get(), record.GetRecordId(), count, STT_SHORT, &(data[0])); 
    268265        } 
    269266 
     
    271268        { 
    272269            int count = data.size() / sizeof(double); 
    273             ST_SetKey( st, record.GetRecordId(), count, STT_DOUBLE,  
    274                        &(data[0]) ); 
     270            ST_SetKey(st.get(), record.GetRecordId(), count, STT_DOUBLE, &(data[0])); 
    275271        }         
    276272 
     
    278274        { 
    279275            uint8_t count = data.size()/sizeof(uint8_t); 
    280             ST_SetKey( st, record.GetRecordId(), count, STT_ASCII,  
    281                        &(data[0]) ); 
    282         } 
    283     } 
    284  
    285     if (st->key_count) { 
    286         GTIF *gtif = GTIFNewSimpleTags( st ); 
     276            ST_SetKey(st.get(), record.GetRecordId(), count, STT_ASCII, &(data[0])); 
     277        } 
     278    } 
     279 
     280    if (st.get()->key_count) 
     281    { 
     282        raii_wrapper<GTIF> gtif(GTIFNewSimpleTags(st.get()), GTIFFree); 
     283 
    287284        GTIFDefn defn; 
    288         if (GTIFGetDefn(gtif, &defn))  
    289         { 
    290             header.SetProj4(std::string(GTIFGetProj4Defn(&defn))); 
    291         } 
    292  
    293 // #ifdef DEBUG 
    294 //         printf("Geotiff from reader...\n"); 
    295 //         GTIFPrint(gtif, 0, 0); 
    296 // #endif 
    297 //  
    298         GTIFFree( gtif ); 
    299         ST_Destroy( st ); 
     285        if (GTIFGetDefn(gtif.get(), &defn))  
     286        { 
     287            char* proj4def = GTIFGetProj4Defn(&defn); 
     288            std::string tmp(proj4def); 
     289            std::free(proj4def); 
     290 
     291            header.SetProj4(tmp); 
     292        } 
     293 
    300294        return true; 
    301     } else { 
    302         return false; 
    303     } 
     295    } 
     296 
    304297#endif /* def HAVE_LIBGEOTIFF */ 
     298 
     299    return false; 
    305300} 
    306301 
     
    394389 
    395390}}} // namespace liblas::detail::v10 
     391 
  • trunk/src/detail/reader11.cpp

    r813 r816  
    4646#include <liblas/laspoint.hpp> 
    4747#include <liblas/lasrecordheader.hpp> 
    48  
    49  
     48// GeoTIFF 
    5049#ifdef HAVE_LIBGEOTIFF 
    5150#include <geotiff.h> 
     
    5453#include "geo_simpletags.h" 
    5554#include "geovalues.h" 
    56 #endif /* HAVE_LIBGEOTIFF */ 
    57  
     55#endif //  HAVE_LIBGEOTIFF 
    5856// std 
    5957#include <fstream> 
     58#include <stdexcept> 
    6059#include <cstdlib> // std::size_t 
    6160#include <cassert> 
    62 #include <stdexcept> 
    6361 
    6462namespace liblas { namespace detail { namespace v11 { 
     
    306304} 
    307305 
    308 bool ReaderImpl::ReadVLR(LASHeader& header) { 
    309      
     306bool ReaderImpl::ReadVLR(LASHeader& header) 
     307{ 
    310308    VLRHeader vlrh = { 0 }; 
    311309 
     
    341339#ifndef HAVE_LIBGEOTIFF 
    342340    UNREFERENCED_PARAMETER(header); 
    343     return false; 
    344341#else 
    345     // TODO: Under construction 
    346342 
    347343    std::string const uid("LASF_Projection"); 
    348     ST_TIFF *st = ST_Create(); 
     344 
     345    detail::raii_wrapper<ST_TIFF> st(ST_Create(), ST_Destroy); 
    349346 
    350347    for (uint16_t i = 0; i < header.GetRecordsCount(); ++i) 
     
    355352        { 
    356353            int16_t count = data.size()/sizeof(int16_t); 
    357             ST_SetKey( st, record.GetRecordId(), count, STT_SHORT,  
    358                        &(data[0]) ); 
     354            ST_SetKey(st.get(), record.GetRecordId(), count, STT_SHORT, &(data[0])); 
    359355        } 
    360356 
     
    362358        { 
    363359            int count = data.size() / sizeof(double); 
    364             ST_SetKey( st, record.GetRecordId(), count, STT_DOUBLE,  
    365                        &(data[0]) ); 
     360            ST_SetKey(st.get(), record.GetRecordId(), count, STT_DOUBLE, &(data[0])); 
    366361        }         
    367362 
     
    369364        { 
    370365            uint8_t count = data.size()/sizeof(uint8_t); 
    371             ST_SetKey( st, record.GetRecordId(), count, STT_ASCII,  
    372                        &(data[0]) ); 
     366            ST_SetKey(st.get(), record.GetRecordId(), count, STT_ASCII, &(data[0])); 
    373367        } 
    374368    } 
    375369 
    376     if (st->key_count) { 
    377         GTIF *gtif = GTIFNewSimpleTags( st ); 
     370    if (st.get()->key_count) 
     371    { 
     372        raii_wrapper<GTIF> gtif(GTIFNewSimpleTags(st.get()), GTIFFree); 
     373 
    378374        GTIFDefn defn; 
    379         if (GTIFGetDefn(gtif, &defn))  
    380         { 
    381             header.SetProj4(std::string(GTIFGetProj4Defn(&defn))); 
     375        if (GTIFGetDefn(gtif.get(), &defn))  
     376        { 
     377            char* proj4def = GTIFGetProj4Defn(&defn); 
     378            std::string tmp(proj4def); 
     379            std::free(proj4def); 
     380 
     381            header.SetProj4(tmp); 
    382382        } 
    383         GTIFFree( gtif ); 
    384         ST_Destroy( st ); 
     383         
    385384        return true; 
    386     } else { 
    387         return false; 
    388     } 
     385    } 
     386 
    389387#endif /* def HAVE_LIBGEOTIFF */ 
     388 
     389    return false; 
    390390} 
    391391 
    392392}}} // namespace liblas::detail::v11 
     393 
  • trunk/src/detail/writer11.cpp

    r813 r816  
    276276 
    277277}}} // namespace liblas::detail::v11 
     278 
  • trunk/src/lasheader.cpp

    r813 r816  
    4545#include <liblas/guid.hpp> 
    4646#include <liblas/detail/utility.hpp> 
     47// GeoTIFF 
     48#ifdef HAVE_LIBGEOTIFF 
     49#include <geotiff.h> 
     50#include <geo_simpletags.h> 
     51#include "geo_normalize.h" 
     52#include "geo_simpletags.h" 
     53#include "geovalues.h" 
     54#include "geotiffio.h" 
     55#endif // HAVE_LIBGEOTIFF 
    4756//std 
    4857#include <algorithm> 
     
    5362#include <cstring> // std::memset, std::memcpy, std::strncpy 
    5463#include <cassert> 
    55 #include <time.h> 
    56  
    57  
    58 #ifdef HAVE_LIBGEOTIFF 
    59 #include <geotiff.h> 
    60 #include <geo_simpletags.h> 
    61 #include "geo_normalize.h" 
    62 #include "geo_simpletags.h" 
    63 #include "geovalues.h" 
    64 #include "geotiffio.h"   /* public interface        */ 
    65 #endif /* HAVE_LIBGEOTIFF */ 
     64#include <ctime> 
     65 
    6666 
    6767namespace liblas 
     
    585585 
    586586 
    587     time_t now; 
    588     tm *ptm; 
    589  
    590     time(&now); 
    591     ptm = gmtime(&now); 
     587    std::time_t now; 
     588    std::tm *ptm; 
     589 
     590    std::time(&now); 
     591    ptm = std::gmtime(&now); 
    592592     
    593593    m_createDOY = static_cast<uint16_t>(ptm->tm_yday); 
     
    624624void LASHeader::ClearGeoKeyVLRs() 
    625625{ 
    626  
    627626    std::string const uid("LASF_Projection"); 
    628627 
     
    639638        beg_size += (*i).GetTotalSize(); 
    640639 
    641         uint16_t id = record.GetRecordId(); 
    642         const char* user = record.GetUserId(true).c_str(); 
    643          
    644         if (uid == user && 34735 == id) 
     640        std::string user = record.GetUserId(true); 
     641        if (uid == user.c_str()) 
    645642        { 
    646             // Geotiff SHORT key 
    647             for(j = vlrs.begin(); j != vlrs.end(); ++j) { 
    648                 if (*j == *i) { 
    649                     vlrs.erase(j); 
    650                     break; 
     643            uint16_t id = record.GetRecordId(); 
     644 
     645            if (34735 == id) 
     646            { 
     647                // Geotiff SHORT key 
     648                for(j = vlrs.begin(); j != vlrs.end(); ++j) 
     649                { 
     650                    if (*j == *i) 
     651                    { 
     652                        vlrs.erase(j); 
     653                        break; 
     654                    } 
    651655                } 
    652656            } 
    653         } 
    654  
    655         if (uid == user && 34736 == id) 
    656         { 
    657             // Geotiff DOUBLE key 
    658             for(j = vlrs.begin(); j != vlrs.end(); ++j) { 
    659                 if (*j == *i) { 
    660                     vlrs.erase(j); 
    661                     break; 
     657            else if (34736 == id) 
     658            { 
     659                // Geotiff DOUBLE key 
     660                for(j = vlrs.begin(); j != vlrs.end(); ++j) 
     661                { 
     662                    if (*j == *i) 
     663                    { 
     664                        vlrs.erase(j); 
     665                        break; 
     666                    } 
     667                } 
     668            }         
     669            else if (34737 == id) 
     670            { 
     671                // Geotiff ASCII key 
     672                for (j = vlrs.begin(); j != vlrs.end(); ++j) 
     673                { 
     674                    if (*j == *i) 
     675                    { 
     676                        vlrs.erase(j); 
     677                        break; 
     678                    } 
    662679                } 
    663680            } 
    664         }         
    665  
    666         if (uid == user && 34737 == id) 
    667         { 
    668             // Geotiff ASCII key 
    669             for(j = vlrs.begin(); j != vlrs.end(); ++j) { 
    670                 if (*j == *i) { 
    671                     vlrs.erase(j); 
    672                     break; 
    673                 } 
    674             } 
    675         } 
     681        } // uid == user 
    676682    } 
    677683     
     
    691697     
    692698    // Add the signature if we're a 1.0 file     
    693     if (eVersionMinorMin == m_versionMinor) { 
     699    if (eVersionMinorMin == m_versionMinor) 
     700    { 
    694701        size = end_size + dataSignatureSize;  
    695     } else { 
     702    } 
     703    else 
     704    { 
    696705        size = end_size; 
    697706    } 
     
    704713#ifndef HAVE_LIBGEOTIFF 
    705714 
     715    ; 
     716 
    706717#else 
     718 
    707719    int ret = 0; 
    708720     
    709         // TODO - mloskot: probable lack of RAII here. 
    710         // Who is the owner of st and gt pointees? 
    711  
    712         ST_TIFF* st = ST_Create(); 
    713     assert(0 != st); 
    714  
    715         GTIF* gt = GTIFNewSimpleTags( st );     
    716     assert(0 != gt); 
     721    detail::raii_wrapper<ST_TIFF> st(ST_Create(), ST_Destroy); 
     722    detail::raii_wrapper<GTIF> gt(GTIFNewSimpleTags(st.get()), GTIFFree);     
    717723         
    718724    // Wipe out any existing VLRs that represent geotiff keys on the  
     
    724730                return; 
    725731 
    726     ret = GTIFSetFromProj4(gt, GetProj4().c_str()); 
     732    ret = GTIFSetFromProj4(gt.get(), GetProj4().c_str()); 
    727733    if (!ret) 
    728734        { 
     
    730736    } 
    731737 
    732     ret = GTIFWriteKeys(gt); 
     738    ret = GTIFWriteKeys(gt.get()); 
    733739    if (!ret) 
    734740        { 
     
    737743     
    738744    short* kdata = NULL; 
    739     short kvalue; 
    740     double dvalue; 
     745    short kvalue = 0; 
    741746    double* ddata = NULL; 
    742     char* adata = NULL; 
    743     char* avalue = NULL; 
    744     int atype, dtype, ktype, acount, dcount, kcount; 
     747    double dvalue = 0; 
     748    int dtype = 0; 
     749    int dcount = 0; 
     750    int ktype = 0; 
     751    int kcount = 0; 
    745752 
    746753    //GTIFF_GEOKEYDIRECTORY == 34735 
    747     ret = ST_GetKey(st, 34735, &kcount, &ktype, (void**)&kdata); 
     754    ret = ST_GetKey(st.get(), 34735, &kcount, &ktype, (void**)&kdata); 
    748755    if (ret) 
    749756        {     
     
    777784    // FIXME We don't handle ASCII keys yet 
    778785    // GTIFF_ASCIIPARAMS == 34737 
    779     // ret = ST_GetKey(st, 34737, &acount, &atype, (void**)&adata); 
     786    // ret = ST_GetKey(st.get(), 34737, &acount, &atype, (void**)&adata); 
    780787    // if (ret) { 
    781788    //      
     
    812819 
    813820    // GTIFF_DOUBLEPARAMS == 34736 
    814     ret = ST_GetKey(st, 34736, &dcount, &dtype, (void**)&ddata); 
     821    ret = ST_GetKey(st.get(), 34736, &dcount, &dtype, (void**)&ddata); 
    815822 
    816823    if (ret) 
     
    849856} 
    850857 
    851  
    852858} // namespace liblas 
     859 
  • trunk/src/lasrecordheader.cpp

    r813 r816  
    219219 
    220220} 
     221 
    221222} // namespace liblas 
     223