Changeset 13866

Show
Ignore:
Timestamp:
02/23/08 14:30:23 (4 months ago)
Author:
rouault
Message:

Speedup detection of KML documents; use VSIF***L API

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/ogr/ogrsf_frmts/kml/kml.cpp

    r13623 r13866  
    4040{ 
    4141        nDepth_ = 0; 
    42         bValid_ = false
     42        validity = KML_VALIDITY_UNKNOWN
    4343        pKMLFile_ = NULL; 
    4444        sError_ = ""; 
     
    5151{ 
    5252    if( NULL != pKMLFile_ ) 
    53         VSIFClose(pKMLFile_); 
     53        VSIFCloseL(pKMLFile_); 
    5454 
    5555    delete poTrunk_; 
     
    5959{ 
    6060    if( NULL != pKMLFile_ ) 
    61         VSIFClose( pKMLFile_ ); 
    62  
    63     pKMLFile_ = VSIFOpen( pszFilename, "r" ); 
     61        VSIFCloseL( pKMLFile_ ); 
     62 
     63    pKMLFile_ = VSIFOpenL( pszFilename, "r" ); 
    6464    if( NULL == pKMLFile_ ) 
    6565    { 
     
    7575    std::size_t nLen = 0; 
    7676    char aBuf[BUFSIZ] = { 0 }; 
    77          
    78        if( NULL == pKMLFile_ ) 
    79     { 
    80                sError_ = "No file given"; 
    81                return; 
    82        
     77 
     78    if( NULL == pKMLFile_ ) 
     79    { 
     80        sError_ = "No file given"; 
     81        return; 
     82   
    8383 
    8484    if(poTrunk_ != NULL) { 
     
    9292        poCurrent_ = NULL; 
    9393    } 
    94          
    95        XML_Parser oParser = XML_ParserCreate(NULL); 
    96        XML_SetUserData(oParser, this); 
    97        XML_SetElementHandler(oParser, startElement, endElement); 
    98        XML_SetCharacterDataHandler(oParser, dataHandler); 
     94 
     95    XML_Parser oParser = XML_ParserCreate(NULL); 
     96    XML_SetUserData(oParser, this); 
     97    XML_SetElementHandler(oParser, startElement, endElement); 
     98    XML_SetCharacterDataHandler(oParser, dataHandler); 
    9999 
    100100    do 
    101101    { 
    102         nLen = (int)VSIFRead( aBuf, 1, sizeof(aBuf), pKMLFile_ ); 
    103         nDone = nLen < sizeof(aBuf); 
     102        nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ ); 
     103        nDone = VSIFEofL(pKMLFile_); 
    104104        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) 
    105105        { 
     
    110110                        XML_GetCurrentColumnNumber(oParser)); 
    111111            XML_ParserFree(oParser); 
    112             VSIRewind(pKMLFile_); 
     112            VSIRewindL(pKMLFile_); 
    113113            return; 
    114114        } 
    115     } while (!nDone); 
    116  
    117        XML_ParserFree(oParser); 
    118     VSIRewind(pKMLFile_); 
     115    } while (!nDone && nLen > 0 ); 
     116 
     117    XML_ParserFree(oParser); 
     118    VSIRewindL(pKMLFile_); 
    119119    poCurrent_ = NULL; 
    120120} 
     
    131131        poTrunk_ = NULL; 
    132132    } 
    133      
     133 
    134134    if(poCurrent_ != NULL) 
    135135    { 
     
    137137        poCurrent_ = NULL; 
    138138    } 
    139          
    140        if(pKMLFile_ == NULL) 
    141     { 
    142                this->sError_ = "No file given"; 
    143                return; 
    144        
    145          
     139 
     140    if(pKMLFile_ == NULL) 
     141    { 
     142        this->sError_ = "No file given"; 
     143        return; 
     144   
     145 
    146146    XML_Parser oParser = XML_ParserCreate(NULL); 
    147147    XML_SetUserData(oParser, this); 
    148148    XML_SetElementHandler(oParser, startElementValidate, NULL); 
    149149 
     150    /* Parses the file until we find the first element */ 
    150151    do 
    151152    { 
    152         nLen = (int)VSIFRead( aBuf, 1, sizeof(aBuf), pKMLFile_ ); 
    153         nDone = nLen < sizeof(aBuf); 
     153        nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ ); 
     154        nDone = VSIFEofL(pKMLFile_); 
    154155        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) 
    155156        { 
     
    176177 
    177178            XML_ParserFree(oParser); 
    178             VSIRewind(pKMLFile_); 
     179            VSIRewindL(pKMLFile_); 
    179180            return; 
    180181        } 
    181     } while (!nDone || bValid_); 
    182          
     182 
     183    } while (!nDone && nLen > 0 && validity == KML_VALIDITY_UNKNOWN); 
     184 
    183185    XML_ParserFree(oParser); 
    184     VSIRewind(pKMLFile_); 
     186    VSIRewindL(pKMLFile_); 
    185187    poCurrent_ = NULL; 
    186188} 
     
    233235void XMLCALL KML::startElementValidate(void* pUserData, const char* pszName, const char** ppszAttr) 
    234236{ 
    235         int i = 0; 
    236         std::string* sName = new std::string(pszName); 
    237         std::string* sAttribute = NULL; 
    238          
    239         if(sName->compare("kml") == 0) 
    240     { 
    241                 // Check all Attributes 
    242                 for (i = 0; ppszAttr[i]; i += 2) 
    243         { 
    244                         sAttribute = new std::string(ppszAttr[i]); 
    245                         // Find the namespace 
    246  
    247                         if(sAttribute->compare("xmlns") == 0) 
     237    int i = 0; 
     238    std::string* sName = new std::string(pszName); 
     239    std::string* sAttribute = NULL; 
     240 
     241    if (((KML *)pUserData)->validity != KML_VALIDITY_UNKNOWN) 
     242        return; 
     243 
     244    ((KML *)pUserData)->validity = KML_VALIDITY_INVALID; 
     245 
     246    if(sName->compare("kml") == 0) 
     247    { 
     248        // Check all Attributes 
     249        for (i = 0; ppszAttr[i]; i += 2) 
     250        { 
     251            sAttribute = new std::string(ppszAttr[i]); 
     252            // Find the namespace 
     253 
     254            if(sAttribute->compare("xmlns") == 0) 
    248255            { 
    249                            delete sAttribute; 
    250                                sAttribute = new std::string(ppszAttr[i + 1]); 
    251                                // Is it KML 2.1? 
    252                                if(sAttribute->compare("http://earth.google.com/kml/2.2") == 0) 
    253                
    254                                        ((KML *)pUserData)->bValid_ = true
    255                                        ((KML *)pUserData)->sVersion_ = "2.2 (beta)"; 
    256                                
    257                 else if(sAttribute->compare("http://earth.google.com/kml/2.1") == 0) 
    258                
    259                                        ((KML *)pUserData)->bValid_ = true
    260                                        ((KML *)pUserData)->sVersion_ = "2.1"; 
    261                                
    262                 else if(sAttribute->compare("http://earth.google.com/kml/2.0") == 0) 
    263                
    264                                        ((KML *)pUserData)->bValid_ = true
    265                                        ((KML *)pUserData)->sVersion_ = "2.0"; 
    266                                
    267                        
    268                        delete sAttribute; 
    269                
    270        
    271        delete sName; 
     256                delete sAttribute; 
     257                    sAttribute = new std::string(ppszAttr[i + 1]); 
     258                    // Is it KML 2.1? 
     259                    if(sAttribute->compare("http://earth.google.com/kml/2.2") == 0) 
     260                   
     261                        ((KML *)pUserData)->validity = KML_VALIDITY_VALID
     262                        ((KML *)pUserData)->sVersion_ = "2.2 (beta)"; 
     263                   
     264                    else if(sAttribute->compare("http://earth.google.com/kml/2.1") == 0) 
     265                   
     266                        ((KML *)pUserData)->validity = KML_VALIDITY_VALID
     267                        ((KML *)pUserData)->sVersion_ = "2.1"; 
     268                   
     269                    else if(sAttribute->compare("http://earth.google.com/kml/2.0") == 0) 
     270                   
     271                        ((KML *)pUserData)->validity = KML_VALIDITY_VALID
     272                        ((KML *)pUserData)->sVersion_ = "2.0"; 
     273                   
     274           
     275            delete sAttribute; 
     276       
     277   
     278    delete sName; 
    272279} 
    273280 
     
    368375bool KML::isValid() 
    369376{ 
    370         checkValidity(); 
    371          
    372     CPLDebug("KML", "Valid: %d Version: %s", bValid_, sVersion_.c_str()); 
    373         return bValid_; 
     377    checkValidity(); 
     378 
     379    CPLDebug("KML", "Valid: %d Version: %s", validity == KML_VALIDITY_VALID, sVersion_.c_str()); 
     380 
     381    return validity == KML_VALIDITY_VALID; 
    374382} 
    375383 
  • trunk/gdal/ogr/ogrsf_frmts/kml/kml.h

    r13710 r13866  
    4444 
    4545class KMLNode; 
     46 
     47 
     48typedef enum 
     49{ 
     50    KML_VALIDITY_UNKNOWN, 
     51    KML_VALIDITY_INVALID, 
     52    KML_VALIDITY_VALID 
     53} OGRKMLValidity; 
    4654 
    4755class KML 
     
    9199        // KML version number 
    92100        std::string sVersion_; 
    93         // set when the file was validated and is kml 
    94         bool bValid_
     101        // set to KML_VALIDITY_VALID if the beginning of the file is detected as KML 
     102        OGRKMLValidity validity
    95103        // file descriptor 
    96104        FILE *pKMLFile_;