GitHub Viewer
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
#include "persistence.hpp"
#define CV_XML_INDENT 2
#define CV_XML_INSIDE_COMMENT 1
#define CV_XML_INSIDE_TAG 2
#define CV_XML_INSIDE_DIRECTIVE 3
#define CV_XML_OPENING_TAG 1
#define CV_XML_CLOSING_TAG 2
#define CV_XML_EMPTY_TAG 3
#define CV_XML_HEADER_TAG 4
#define CV_XML_DIRECTIVE_TAG 5
/****************************************************************************************\
* XML Parser *
\****************************************************************************************/
static char*
icvXMLSkipSpaces( CvFileStorage* fs, char* ptr, int mode )
{
int level = 0;
for(;;)
{
char c;
ptr--;
if( mode == CV_XML_INSIDE_COMMENT )
{
do c = *++ptr;
while( cv_isprint_or_tab(c) && (c != '-' || ptr[1] != '-' || ptr[2] != '>') );
if( c == '-' )
{
assert( ptr[1] == '-' && ptr[2] == '>' );
mode = 0;
ptr += 3;
}
}
else if( mode == CV_XML_INSIDE_DIRECTIVE )
{
// !!!NOTE!!! This is not quite correct, but should work in most cases
do
{
c = *++ptr;
level += c == '';
if( level < 0 )
return ptr;
} while( cv_isprint_or_tab(c) );
}
else
{
do c = *++ptr;
while( c == ' ' || c == '\t' );
if( c == 'dummy_eof )
return ; /* end of file */
if ( *beg == ' (unsigned)255 ||
!endptr || *endptr != ';' )
CV_PARSE_ERROR( "Invalid numeric value in the string" );
c = (char)val;
}
else
{
endptr = ptr;
do c = *++endptr;
while( cv_isalnum(c) );
if( c != ';' )
CV_PARSE_ERROR( "Invalid character in the symbol entity name" );
len = (int)(endptr - ptr);
if( len == 2 && memcmp( ptr, "lt", len ) == 0 )
c = '';
else if( len == 3 && memcmp( ptr, "amp", len ) == 0 )
c = '&';
else if( len == 4 && memcmp( ptr, "apos", len ) == 0 )
c = '\'';
else if( len == 4 && memcmp( ptr, "quot", len ) == 0 )
c = '\"';
else
{
memcpy( buf + i, ptr-1, len + 2 );
i += len + 2;
}
}
ptr = endptr;
CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG();
}
}
buf[i++] = c;
if( i >= CV_FS_MAX_LEN )
CV_PARSE_ERROR( "Too long string literal" );
}
elem->data.str = cvMemStorageAllocString( fs->memstorage, buf, i );
}
if( !CV_NODE_IS_COLLECTION(value_type) && value_type != CV_NODE_NONE )
break;
have_space = false;
}
}
if( (CV_NODE_TYPE(node->tag) == CV_NODE_NONE ||
(CV_NODE_TYPE(node->tag) != value_type &&
!CV_NODE_IS_COLLECTION(node->tag))) &&
CV_NODE_IS_COLLECTION(value_type) )
{
icvFSCreateCollection( fs, CV_NODE_IS_MAP(value_type) ?
CV_NODE_MAP : CV_NODE_SEQ, node );
}
if( value_type != CV_NODE_NONE &&
value_type != CV_NODE_TYPE(node->tag) )
CV_PARSE_ERROR( "The actual type is different from the specified type" );
if( CV_NODE_IS_COLLECTION(node->tag) && is_simple )
node->data.seq->flags |= CV_NODE_SEQ_SIMPLE;
node->tag |= is_user_type ? CV_NODE_USER : 0;
return ptr;
}
static char*
icvXMLParseTag( CvFileStorage* fs, char* ptr, CvStringHashNode** _tag,
CvAttrList** _list, int* _tag_type )
{
int tag_type = 0;
CvStringHashNode* tagname = 0;
CvAttrList *first = 0, *last = 0;
int count = 0, max_count = 4;
int attr_buf_size = (max_count*2 + 1)*sizeof(char*) + sizeof(CvAttrList);
char* endptr;
char c;
int have_space;
if( *ptr == '\0' )
CV_PARSE_ERROR( "Preliminary end of the stream" );
if( *ptr != 'attr[count*2+1] = stub.data.str.ptr;
count++;
}
c = *ptr;
have_space = cv_isspace(c) || c == '\0';
if( c != '>' )
{
ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG );
c = *ptr;
}
if( c == '>' )
{
if( tag_type == CV_XML_HEADER_TAG )
CV_PARSE_ERROR( "Invalid closing tag for \n" );
/*fputs( " fs->buffer_start + fs->struct_indent )
*ptr++ = ' ';
if( !multiline )
{
ptr = icvFSResizeWriteBuffer( fs, ptr, len + 9 );
sprintf( ptr, "", comment );
len = (int)strlen(ptr);
}
else
{
strcpy( ptr, "" );
fs->buffer = ptr + 3;
icvXMLFlush( fs );
}
}