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

📄 cxpersistence.cpp

📁 这个是基于在CCS开发环境下
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}


static char*
icvYMLParseKey( CvFileStorage* fs, char* ptr,
                CvFileNode* map_node, CvFileNode** value_placeholder )
{
    CV_FUNCNAME( "icvYMLParseKey" );
    
    __BEGIN__;

    char c;
    char *endptr = ptr - 1, *saveptr;
    CvStringHashNode* str_hash_node;

    if( *ptr == '-' )
        CV_PARSE_ERROR( "Key may not start with \'-\'" );

    do c = *++endptr;
    while( cv_isprint(c) && c != ':' );

    if( c != ':' )
        CV_PARSE_ERROR( "Missing \':\'" );

    saveptr = endptr + 1;
    do c = *--endptr;
    while( c == ' ' );

    ++endptr;
    if( endptr == ptr )
        CV_PARSE_ERROR( "An empty key" );
    
    CV_CALL( str_hash_node = cvGetHashedKey( fs, ptr, (int)(endptr - ptr), 1 ));
    CV_CALL( *value_placeholder = cvGetFileNode( fs, map_node, str_hash_node, 1 ));
    ptr = saveptr;

    __END__;

    return ptr;
}


static char*
icvYMLParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node,
                  int parent_flags, int min_indent )
{
    CV_FUNCNAME( "icvYMLParseValue" );
    
    __BEGIN__;

    char buf[CV_FS_MAX_LEN + 1024];
    char* endptr = 0;
    char c = ptr[0], d = ptr[1];
    int is_parent_flow = CV_NODE_IS_FLOW(parent_flags);
    int value_type = CV_NODE_NONE;
    int len;

    memset( node, 0, sizeof(*node) );

    if( c == '!' ) // handle explicit type specification
    {
        if( d == '!' || d == '^' )
        {
            ptr++;
            value_type |= CV_NODE_USER;
        }

        endptr = ptr++;
        do d = *++endptr;
        while( cv_isprint(d) && d != ' ' );
        len = (int)(endptr - ptr);
        if( len == 0 )
            CV_PARSE_ERROR( "Empty type name" );
        d = *endptr;
        *endptr = '\0';
        
        if( len == 3 && !CV_NODE_IS_USER(value_type) )
        {
            if( memcmp( ptr, "str", 3 ) == 0 )
                value_type = CV_NODE_STRING;
            else if( memcmp( ptr, "int", 3 ) == 0 )
                value_type = CV_NODE_INT;
            else if( memcmp( ptr, "seq", 3 ) == 0 )
                value_type = CV_NODE_SEQ;
            else if( memcmp( ptr, "map", 3 ) == 0 )
                value_type = CV_NODE_MAP;
        }
        else if( len == 5 && !CV_NODE_IS_USER(value_type) )
        {
            if( memcmp( ptr, "float", 5 ) == 0 )
                value_type = CV_NODE_REAL;
        }
        else if( CV_NODE_IS_USER(value_type) )
        {
            CV_CALL( node->info = cvFindType( ptr ));
            if( !node->info )
                node->tag &= ~CV_NODE_USER;
        }

        *endptr = d;
        CV_CALL( ptr = icvYMLSkipSpaces( fs, endptr, min_indent, INT_MAX ));
        
        c = *ptr;

        if( !CV_NODE_IS_USER(value_type) )
        {
            if( value_type == CV_NODE_STRING && c != '\'' && c != '\"' )
                goto force_string;
            if( value_type == CV_NODE_INT )
                goto force_int;
            if( value_type == CV_NODE_REAL )
                goto force_real;
        }
    }

    if( isdigit(c) ||
        (c == '-' || c == '+') && (isdigit(d) || d == '.') ||
        c == '.' && isalnum(d)) // a number
    {
        double fval;
        int ival;
        endptr = ptr + (c == '-' || c == '+');
        while( isdigit(*endptr) )
            endptr++;
        if( *endptr == '.' || *endptr == 'e' )
        {
force_real:
            fval = icv_strtod( fs, ptr, &endptr );
            /*if( endptr == ptr || isalpha(*endptr) )
                CV_CALL( icvProcessSpecialDouble( fs, endptr, &fval, &endptr ));*/

            node->tag = CV_NODE_REAL;
            node->data.f = fval;
        }
        else
        {
force_int:
            ival = (int)strtol( ptr, &endptr, 0 );
            node->tag = CV_NODE_INT;
            node->data.i = ival;
        }

        if( !endptr || endptr == ptr )
            CV_PARSE_ERROR( "Invalid numeric value (inconsistent explicit type specification?)" );

        ptr = endptr;
    }
    else if( c == '\'' || c == '\"' ) // an explicit string
    {
        node->tag = CV_NODE_STRING;
        if( c == '\'' )
            for( len = 0; len < CV_FS_MAX_LEN; )
            {
                c = *++ptr;
                if( isalnum(c) || (c != '\'' && cv_isprint(c)))
                    buf[len++] = c;
                else if( c == '\'' )
                {
                    c = *++ptr;
                    if( c != '\'' )
                        break;
                    buf[len++] = c;
                }
                else
                    CV_PARSE_ERROR( "Invalid character" );
            }
        else
            for( len = 0; len < CV_FS_MAX_LEN; )
            {
                c = *++ptr;
                if( isalnum(c) || (c != '\\' && c != '\"' && cv_isprint(c)))
                    buf[len++] = c;
                else if( c == '\"' )
                {
                    ++ptr;
                    break;
                }
                else if( c == '\\' )
                {
                    d = *++ptr;
                    if( d == '\'' )
                        buf[len++] = d;
                    else if( d == '\"' || d == '\\' || d == '\'' )
                        buf[len++] = d;
                    else if( d == 'n' )
                        buf[len++] = '\n';
                    else if( d == 'r' )
                        buf[len++] = '\r';
                    else if( d == 't' )
                        buf[len++] = '\t';
                    else if( d == 'x' || isdigit(d) && d < '8' )
                    {
                        int val, is_hex = d == 'x';
                        c = ptr[3];
                        ptr[3] = '\0';
                        val = strtol( ptr + is_hex, &endptr, is_hex ? 8 : 16 );
                        ptr[3] = c;
                        if( endptr == ptr + is_hex )
                            buf[len++] = 'x';
                        else
                        {
                            buf[len++] = (char)val;
                            ptr = endptr;
                        }
                    }
                }
                else
                    CV_PARSE_ERROR( "Invalid character" );
            }

        if( len >= CV_FS_MAX_LEN )
            CV_PARSE_ERROR( "Too long string literal" );

        CV_CALL( node->data.str = cvMemStorageAllocString( fs->memstorage, buf, len ));
    }
    else if( c == '[' || c == '{' ) // collection as a flow
    {
        int new_min_indent = min_indent + !is_parent_flow;
        int struct_flags = CV_NODE_FLOW + (c == '{' ? CV_NODE_MAP : CV_NODE_SEQ);
        int is_simple = 1;
        
        CV_CALL( icvFSCreateCollection( fs, CV_NODE_TYPE(struct_flags) +
                                        (node->info ? CV_NODE_USER : 0), node ));

        d = c == '[' ? ']' : '}';

        for( ++ptr ;;)
        {
            CvFileNode* elem = 0;

            CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, new_min_indent, INT_MAX ));
            if( *ptr == '}' || *ptr == ']' )
            {
                if( *ptr != d )
                    CV_PARSE_ERROR( "The wrong closing bracket" );
                ptr++;
                break;
            }

            if( node->data.seq->total != 0 )
            {
                if( *ptr != ',' )
                    CV_PARSE_ERROR( "Missing , between the elements" );
                CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr + 1, new_min_indent, INT_MAX ));
            }

            if( CV_NODE_IS_MAP(struct_flags) )
            {
                CV_CALL( ptr = icvYMLParseKey( fs, ptr, node, &elem ));
                CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, new_min_indent, INT_MAX ));
            }
            else
            {
                if( *ptr == ']' )
                    break;
                elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 );
            }
            CV_CALL( ptr = icvYMLParseValue( fs, ptr, elem, struct_flags, new_min_indent ));
            if( CV_NODE_IS_MAP(struct_flags) )
                elem->tag |= CV_NODE_NAMED;
            is_simple &= !CV_NODE_IS_COLLECTION(elem->tag);
        }
        node->data.seq->flags |= is_simple ? CV_NODE_SEQ_SIMPLE : 0;
    }
    else
    {
        int indent, struct_flags, is_simple;
        
        if( is_parent_flow || c != '-' )
        {
            // implicit (one-line) string or nested block-style collection
            if( !is_parent_flow )
            {
                if( c == '?' )
                    CV_PARSE_ERROR( "Complex keys are not supported" );
                if( c == '|' || c == '>' )
                    CV_PARSE_ERROR( "Multi-line text literals are not supported" );
            }

force_string:
            endptr = ptr - 1;

            do c = *++endptr;
            while( cv_isprint(c) &&
                   (!is_parent_flow || c != ',' && c != '}' && c != ']') &&
                   (is_parent_flow || c != ':' || value_type == CV_NODE_STRING));

            if( endptr == ptr )
                CV_PARSE_ERROR( "Invalid character" );

            if( is_parent_flow || c != ':' )
            {
                char* str_end = endptr;
                node->tag = CV_NODE_STRING;
                // strip spaces in the end of string
                do c = *--str_end;
                while( str_end > ptr && c == ' ' );
                str_end++;
                CV_CALL( node->data.str = cvMemStorageAllocString( fs->memstorage, ptr, (int)(str_end - ptr) ));
                ptr = endptr;
                EXIT;
            }
            struct_flags = CV_NODE_MAP;
        }
        else
            struct_flags = CV_NODE_SEQ;

        CV_CALL( icvFSCreateCollection( fs, struct_flags +
                    (node->info ? CV_NODE_USER : 0), node ));
        
        indent = (int)(ptr - fs->buffer_start);
        is_simple = 1;

        for(;;)
        {
            CvFileNode* elem = 0;
            
            if( CV_NODE_IS_MAP(struct_flags) )
            {
                CV_CALL( ptr = icvYMLParseKey( fs, ptr, node, &elem ));
            }
            else
            {
                c = *ptr++;
                if( c != '-' )
                    CV_PARSE_ERROR( "Block sequence elements must be preceded with \'-\'" );

                CV_CALL( elem = (CvFileNode*)cvSeqPush( node->data.seq, 0 ));
            }

            CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, indent + 1, INT_MAX ));
            CV_CALL( ptr = icvYMLParseValue( fs, ptr, elem, struct_flags, indent + 1 ));
            if( CV_NODE_IS_MAP(struct_flags) )
                elem->tag |= CV_NODE_NAMED;
            is_simple &= !CV_NODE_IS_COLLECTION(elem->tag);

            CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ));
            if( ptr - fs->buffer_start != indent )
            {
                if( ptr - fs->buffer_start < indent )
                    break;
                else
                    CV_PARSE_ERROR( "Incorrect indentation" );
            }
            if( memcmp( ptr, "...", 3 ) == 0 )
                break;
        }

        node->data.seq->flags |= is_simple ? CV_NODE_SEQ_SIMPLE : 0;
    }

    __END__;

    return ptr;
}


static void
icvYMLParse( CvFileStorage* fs )
{
    CV_FUNCNAME( "icvYMLParse" );

    __BEGIN__;

    char* ptr = fs->buffer_start;
    int is_first = 1;

    for(;;)
    {
        // 0. skip leading comments and directives  and ...
        // 1. reach the first item
        for(;;)
        {
            CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ));
            if( !ptr )
                EXIT;

            if( *ptr == '%' )
            {
                if( memcmp( ptr, "%YAML:", 6 ) == 0 &&
                    memcmp( ptr, "%YAML:1.", 8 ) != 0 )
                    CV_PARSE_ERROR( "Unsupported YAML version (it must be 1.x)" );
                *ptr = '\0';
            }
            else if( *ptr == '-' )
            {
                if( memcmp(ptr, "---", 3) == 0 )
                {
                    ptr += 3;
                    break;
                }
                else if( is_first )
                    break;
            }
            else if( isalnum(*ptr) || *ptr=='_')
            {
                if( !is_first )
                    CV_PARSE_ERROR( "The YAML streams must start with '---', except the first one" );
                break;
            }
            else
                CV_PARSE_ERROR( "Invalid or unsupported syntax" );
        }

        CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ));
        if( memcmp( ptr, "...", 3 ) != 0 )
        {
            // 2. parse the collection
            CvFileNode* root_node = (CvFileNode*)cvSeqPush( fs->roots, 0 );

            CV_CALL( ptr = icvYMLParseValue( fs, ptr, root_node, CV_NODE_NONE, 0 ));
            if( !CV_NODE_IS_COLLECTION(root_node->tag) )
                CV_PARSE_ERROR( "Only collections as YAML streams are supported by this parser" );
            
            // 3. parse until the end of file or next collection
            CV_CALL( ptr = icvYMLSkipSpaces( fs, ptr, 0, INT_MAX ));
            if( !ptr )
                EXIT;
        }

        if( fs->dummy_eof )
            break;
        ptr += 3;
        is_first = 0;
    }

    __END__;
}


/****************************************************************************************\
*                                       YAML Emitter                                     *
\****************************************************************************************/

static void
icvYMLWrite( CvFileStorage* fs, const char* key, const char* data, const char* cvFuncName )
{
    //CV_FUNCNAME( "icvYMLWrite" );

    __BEGIN__;
    
    int i, keylen = 0;

⌨️ 快捷键说明

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