⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpl_minixml.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/********************************************************************** * $Id: cpl_minixml.cpp,v 1.45 2006/11/07 03:45:22 fwarmerdam Exp $ * * Project:  CPL - Common Portability Library * Purpose:  Implementation of MiniXML Parser and handling. * Author:   Frank Warmerdam, warmerdam@pobox.com * ********************************************************************** * Copyright (c) 2001, Frank Warmerdam * * 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. ********************************************************************** * * Independent Security Audit 2003/04/05 Andrey Kiselev: *   Completed audit of this module. Any documents may be parsed without *   buffer overflows and stack corruptions. *  * Security Audit 2003/03/28 warmerda: *   Completed security audit.  I believe that this module may be safely used  *   to parse, and serialize arbitrary documents provided by a potentially  *   hostile source. * * $Log: cpl_minixml.cpp,v $ * Revision 1.45  2006/11/07 03:45:22  fwarmerdam * Added support for CDATA. * * Revision 1.44  2006/06/30 18:18:17  dron * Avoid warnings. * * Revision 1.43  2006/06/30 14:25:24  dron * Avoid warnings on win/64. * * Revision 1.42  2006/04/19 02:00:20  fwarmerdam * moved ctype.h after cpl include files for VS2005 * * Revision 1.41  2006/02/20 00:42:35  fwarmerdam * Trim. * * Revision 1.40  2006/02/19 21:54:34  mloskot * [WINCE] Changes related to Windows CE port of CPL. Most changes are #ifdef wrappers. * * Revision 1.39  2005/10/07 00:03:29  fwarmerdam * improve documentation * * Revision 1.38  2005/09/11 19:30:12  fwarmerdam * Try to write in text mode through large file API. * * Revision 1.37  2005/09/11 19:14:54  fwarmerdam * Use largefile API for virtualization support.  Note that XML files are * no longer produced in machine-local text format. * * Revision 1.36  2005/05/22 08:17:07  fwarmerdam * allow CPLAddXMLChild() to support siblings * * Revision 1.35  2005/05/13 18:17:48  fwarmerdam * added CPLRemoveXMLChild * * Revision 1.34  2005/03/09 17:07:25  fwarmerdam * added CPLSearchXMLNode * * Revision 1.33  2005/01/17 17:01:56  fwarmerdam * ensure that namespace stripping apply to attributes * * Revision 1.32  2004/10/21 18:59:00  fwarmerdam * Ensure that an empty path in CPLGetXMLValue() means the current node. * * Revision 1.31  2004/08/11 18:42:00  warmerda * fix quirks with CPLSetXMLValue() * * Revision 1.30  2004/03/31 17:11:41  warmerda * fixed return value of CPLCreateXMLElementAndValue() * * Revision 1.29  2004/01/29 17:01:51  warmerda * Added reference to spec. * * Revision 1.28  2004/01/29 15:29:28  warmerda * Added CPLCleanXMLElementName */#include "cpl_minixml.h"#include "cpl_error.h"#include "cpl_conv.h"#include "cpl_string.h"#include <ctype.h>CPL_CVSID("$Id: cpl_minixml.cpp,v 1.45 2006/11/07 03:45:22 fwarmerdam Exp $");typedef enum {    TNone,    TString,     TOpen,     TClose,    TEqual,    TToken,    TSlashClose,    TQuestionClose,    TComment,    TLiteral} XMLTokenType;typedef struct {    const char *pszInput;    int        nInputOffset;    int        nInputLine;    int        bInElement;    XMLTokenType  eTokenType;    char       *pszToken;    size_t     nTokenMaxSize;    size_t     nTokenSize;    int        nStackMaxSize;    int        nStackSize;    CPLXMLNode **papsStack;    CPLXMLNode *psFirstNode;} ParseContext;/************************************************************************//*                              ReadChar()                              *//************************************************************************/static char ReadChar( ParseContext *psContext ){    char        chReturn;    chReturn = psContext->pszInput[psContext->nInputOffset++];    if( chReturn == '\0' )        psContext->nInputOffset--;    else if( chReturn == 10 )        psContext->nInputLine++;        return chReturn;}/************************************************************************//*                             UnreadChar()                             *//************************************************************************/static void UnreadChar( ParseContext *psContext, char chToUnread ){    if( chToUnread == '\0' )    {        /* do nothing */    }    else    {        CPLAssert( chToUnread                    == psContext->pszInput[psContext->nInputOffset-1] );        psContext->nInputOffset--;        if( chToUnread == 10 )            psContext->nInputLine--;    }}/************************************************************************//*                             AddToToken()                             *//************************************************************************/static void AddToToken( ParseContext *psContext, char chNewChar ){    if( psContext->pszToken == NULL )    {        psContext->nTokenMaxSize = 10;        psContext->pszToken = (char *) CPLMalloc(psContext->nTokenMaxSize);    }    else if( psContext->nTokenSize >= psContext->nTokenMaxSize - 2 )    {        psContext->nTokenMaxSize *= 2;        psContext->pszToken = (char *)             CPLRealloc(psContext->pszToken,psContext->nTokenMaxSize);    }    psContext->pszToken[psContext->nTokenSize++] = chNewChar;    psContext->pszToken[psContext->nTokenSize] = '\0';}/************************************************************************//*                             ReadToken()                              *//************************************************************************/static XMLTokenType ReadToken( ParseContext *psContext ){    char        chNext;    psContext->nTokenSize = 0;    psContext->pszToken[0] = '\0';        chNext = ReadChar( psContext );    while( isspace(chNext) )        chNext = ReadChar( psContext );/* -------------------------------------------------------------------- *//*      Handle comments.                                                *//* -------------------------------------------------------------------- */    if( chNext == '<'         && EQUALN(psContext->pszInput+psContext->nInputOffset,"!--",3) )    {        psContext->eTokenType = TComment;        // Skip "!--" characters        ReadChar(psContext);        ReadChar(psContext);        ReadChar(psContext);        while( !EQUALN(psContext->pszInput+psContext->nInputOffset,"-->",3)               && (chNext = ReadChar(psContext)) != '\0' )            AddToToken( psContext, chNext );        // Skip "-->" characters        ReadChar(psContext);        ReadChar(psContext);        ReadChar(psContext);    }/* -------------------------------------------------------------------- *//*      Handle DOCTYPE.                                                 *//* -------------------------------------------------------------------- */    else if( chNext == '<'           && EQUALN(psContext->pszInput+psContext->nInputOffset,"!DOCTYPE",8) )    {        int   bInQuotes = FALSE;        psContext->eTokenType = TLiteral;                AddToToken( psContext, '<' );        do {             chNext = ReadChar(psContext);            if( chNext == '\0' )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Parse error in DOCTYPE on or before line %d, "                          "reached end of file without '>'.",                           psContext->nInputLine );                                break;            }            if( chNext == '\"' )                bInQuotes = !bInQuotes;             if( chNext == '>' && !bInQuotes )            {                AddToToken( psContext, '>' );                break;            }            AddToToken( psContext, chNext );        } while( TRUE );    }/* -------------------------------------------------------------------- *//*      Handle CDATA.                                                   *//* -------------------------------------------------------------------- */    else if( chNext == '<'           && EQUALN(psContext->pszInput+psContext->nInputOffset,"![CDATA[",8) )    {        psContext->eTokenType = TString;        // Skip !CDATA[        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        ReadChar( psContext );        while( !EQUALN(psContext->pszInput+psContext->nInputOffset,"]]>",3)               && (chNext = ReadChar(psContext)) != '\0' )            AddToToken( psContext, chNext );        // Skip "]]>" characters        ReadChar(psContext);        ReadChar(psContext);        ReadChar(psContext);    }/* -------------------------------------------------------------------- *//*      Simple single tokens of interest.                               *//* -------------------------------------------------------------------- */    else if( chNext == '<' && !psContext->bInElement )    {        psContext->eTokenType = TOpen;        psContext->bInElement = TRUE;    }    else if( chNext == '>' && psContext->bInElement )    {        psContext->eTokenType = TClose;        psContext->bInElement = FALSE;    }    else if( chNext == '=' && psContext->bInElement )    {        psContext->eTokenType = TEqual;    }    else if( chNext == '\0' )    {        psContext->eTokenType = TNone;    }/* -------------------------------------------------------------------- *//*      Handle the /> token terminator.                                 *//* -------------------------------------------------------------------- */    else if( chNext == '/' && psContext->bInElement              && psContext->pszInput[psContext->nInputOffset] == '>' )    {        chNext = ReadChar( psContext );        CPLAssert( chNext == '>' );        psContext->eTokenType = TSlashClose;        psContext->bInElement = FALSE;    }/* -------------------------------------------------------------------- *//*      Handle the ?> token terminator.                                 *//* -------------------------------------------------------------------- */    else if( chNext == '?' && psContext->bInElement              && psContext->pszInput[psContext->nInputOffset] == '>' )    {        chNext = ReadChar( psContext );                CPLAssert( chNext == '>' );        psContext->eTokenType = TQuestionClose;        psContext->bInElement = FALSE;    }/* -------------------------------------------------------------------- *//*      Collect a quoted string.                                        *//* -------------------------------------------------------------------- */    else if( psContext->bInElement && chNext == '"' )    {        psContext->eTokenType = TString;        while( (chNext = ReadChar(psContext)) != '"'                && chNext != '\0' )            AddToToken( psContext, chNext );                if( chNext != '"' )        {            psContext->eTokenType = TNone;            CPLError( CE_Failure, CPLE_AppDefined,                   "Parse error on line %d, reached EOF before closing quote.",                       psContext->nInputLine );        }        /* Do we need to unescape it? */        if( strchr(psContext->pszToken,'&') != NULL )        {            int  nLength;            char *pszUnescaped = CPLUnescapeString( psContext->pszToken,                                                     &nLength, CPLES_XML );            strcpy( psContext->pszToken, pszUnescaped );            CPLFree( pszUnescaped );            psContext->nTokenSize = strlen(psContext->pszToken );        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -