cvpersistence.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 2,051 行 · 第 1/5 页

SVN-BASE
2,051
字号
                const char* dtp = dt;
                int k0 = k;

                for( ;; )
                {
                    if( (n -= (k != k0)) <= 0 )
                    {
                        if( !dtp[0] )
                            break;
                        n = 1;
                        if( isdigit(dtp[0]))
                        {
                            if( !isdigit(dtp[1]))
                            {
                                n = dtp[0] - '0';
                                dtp++;
                            }
                            else
                            {
                                int dl;
                                if( sscanf( dtp, "%d%n", &n, &dl ) <= 0 )
                                    CV_ERROR(CV_StsBadArg,
                                            "Invalid data type specification");
                                dtp += dl;
                            }
                            if( n == 0 )
                                CV_ERROR(CV_StsBadArg,
                                        "Invalid data type specification");
                        }
                        c = *dtp++;
                    }

                    k0 = k;
                    switch( c )
                    {
                    case 'u':
                    case 'c':
                        if( buffer < buffer_end )
                        {
                            *(uchar*)(data + k) = *buffer++;
                            k++;
                        }
                        break;
                    case 's':
                        if( buffer + 1 < buffer_end )
                        {
                            k = (k + sizeof(short) - 1) & -(int)sizeof(short);
                            *(short*)(data + k) = (short)((buffer[0] << 8) + buffer[1]);
                            k += sizeof(short);
                            buffer += 2;
                        }
                        break;
                    case 'i':
                    case 'f':
                        if( buffer + 3 < buffer_end )
                        {
                            k = (k + sizeof(int) - 1) & -(int)sizeof(int);
                            *(int*)(data + k) = (buffer[0] << 24) + (buffer[1] << 16) +
                                                (buffer[2] << 8) + buffer[3];
                            k += sizeof(int);
                            buffer += 4;
                        }
                        break;
                    case 'd':
                        if( buffer + 7 < buffer_end )
                        {
                            unsigned lo, hi;
                            hi = (buffer[0] << 24) + (buffer[1] << 16) +
                                 (buffer[2] << 8) + buffer[3];
                            lo = (buffer[4] << 24) + (buffer[5] << 16) +
                                 (buffer[6] << 8) + buffer[7];
                            k = (k + sizeof(uint64) - 1) & -(int)sizeof(uint64);
                            *(uint64*)(data + k) = ((uint64)hi << 32) + lo;
                            k += sizeof(uint64);
                            buffer += 8;
                        }
                        break;
                    case 'p':
                        {
                            /* just skip it */
                            k = (k + sizeof(void*) - 1) & -(int)sizeof(void*);
                            *(void**)(data+k) = 0;
                            k += sizeof(void*);
                        }
                        break;
                    case 'r':
                        if( buffer + 3 < buffer_end )
                        {
                            unsigned val;
                            k = (k + sizeof(void*) - 1) & -(int)sizeof(void*);
                            val = (buffer[0] << 24) + (buffer[1] << 16) +
                                 (buffer[2] << 8) + buffer[3];
                            *(void**)(data+k) = (void*)(size_t)val;
                            k += sizeof(void*);
                            buffer += 4;
                        }
                        break;
                    default:
                        EXIT;
                    }

                    if( k == k0 )
                    {
                        int len = buffer_end - buffer;
                        storage->base64_buffer = (char*)buffer;
                        if( !icvReadBase64Block( storage ))
                            EXIT;
                        buffer = (uchar*)storage->base64_buffer;
                        buffer_end = (uchar*)storage->base64_buffer_read;
                        if( len >= buffer_end - buffer )
                            EXIT;
                    }
                }
            }
        }

        storage->base64_buffer = (char*)buffer;
    }
    else
    {
        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported encoding format" );
    }

    result = 1;

    __END__;

    if( format == ICV_FORMAT_TEXT )
        storage->buffer = (char*)buffer;

    return result;
}


static int
icvCalcSize( const char* dt )
{
    int size = 0;

    CV_FUNCNAME( "icvCalcSize" );

    __BEGIN__;

    int k = 0;

    if( !dt )
        EXIT;

    for( ;; )
    {
        char c = '\0';
        int n = 1;

        if( !*dt )
            break;
        if( isdigit(*dt))
        {
            int dl = 0;
            sscanf( dt, "%d%n", &n, &dl );
            if( n == 0 )
                CV_ERROR( CV_StsBadArg, "Invalid data type specification" );
            dt += dl;
        }
        c = *dt++;

        switch( c )
        {
        case 'u':
        case 'c':
            k += n;
            break;
        case 's':
            k = (k + sizeof(short) - 1) & -(int)sizeof(short);
            k += sizeof(short)*n;
            break;
        case 'i':
        case 'f':
            k = (k + sizeof(int) - 1) & -(int)sizeof(int);
            k += sizeof(int)*n;
            break;
        case 'd':
            k = (k + sizeof(double) - 1) & -(int)sizeof(double);
            k += sizeof(double)*n;
            break;
        case 'p':
        case 'r':
            k = (k + sizeof(void*) - 1) & -(int)sizeof(void*);
            k += sizeof(void*)*n;
            break;
        default:
            CV_ERROR( CV_StsBadArg, "Unknown format specifier" );
        }
    }

    size = k;

    __END__;

    return size;
}


#define ICV_OPENING_TAG 0
#define ICV_CLOSING_TAG 1

static int
icvFindTag( CvFileStorage* storage )
{
    char* buffer = storage->buffer;
    int is_comment = 0, is_control = 0, is_quot = 0, is_directive = 0;
    int result = -1;

    for( ; buffer < storage->buffer_end; buffer++ )
    {
        int c = buffer[0];
        if( c & ~0x7f )
            goto exit_func;
        if( isspace(c))
        {
            if( c == '\n' )
            {
                storage->line++;
                storage->line_start = buffer;
            }
            continue;
        }

        switch( buffer[0] )
        {
        case '-':
            if( !is_quot )
            {
                if( is_comment )
                {
                    if( buffer[1] == '-' && buffer[2] == '>' )
                        buffer += 2, is_comment = 0;
                }
            }
            break;
        case '<':
            if( !is_quot && !is_comment )
            {
                if( buffer[1] == '!' )
                {
                    if( buffer[2] == '-' )
                    {
                        if( buffer[3] == '-' )
                            buffer += 2, is_comment = 1;
                        else
                            goto exit_func;
                    }
                    else
                        is_control++;
                }
                else if( buffer[1] == '?' )
                {
                    buffer++;
                    is_directive = 1;
                }
                else if( buffer[1] == '/' )
                {
                    result = ICV_CLOSING_TAG;
                    buffer += 2;
                    goto exit_func;
                }
                else
                {
                    result = ICV_OPENING_TAG;
                    buffer++;
                    goto exit_func;
                }
            }
            break;
        case '\"':
        case '\'':
            if( is_quot )
            {
                if( c == is_quot )
                    is_quot = 0;
            }
            else if( !is_comment )
            {
                if( is_control == 0 && is_directive == 0 )
                    goto exit_func;
                is_quot = c;
            }
            break;
        case '>':
            if( !is_quot && !is_comment )
            {
                if( --is_control < 0 )
                    goto exit_func;
            }
            break;
        case '?':
            if( !is_quot && !is_comment )
            {
                if( buffer[1] == '>' )
                    if( is_directive )
                        buffer++, is_directive = 0;
                    else
                        goto exit_func;
            }
            break;
        /*default:
            if( !is_quot && !is_comment && !is_control && !is_directive )
                goto exit_func;*/
        }
    }

exit_func:

    storage->buffer = buffer;
    return result;
}


#define ICV_NEED_TAGNAME 0
#define ICV_NEED_ATTRNAME 1
#define ICV_NEED_EQSIGN 2
#define ICV_NEED_ATTRVAL 3

static int
icvParseXML( CvFileStorage* storage )
{
    const int chunk_size = 10;
    int result = 0;

    CV_FUNCNAME( "icvParseXML" );

    __BEGIN__;

    char errbuf[100];
    char* buffer;

    buffer = storage->line_start = storage->buffer = storage->buffer_start;
    storage->line = 1;

    for(;;)
    {
        int need = ICV_NEED_TAGNAME;
        CvFileNode* node = 0;
        CvFileNode stub_node;
        int free_attr = 0;
        char** attr_arr = 0;
        CvAttrList* last_attr = 0;
        int is_id = 0, is_empty = 0;
        int c, tag;

        storage->buffer = buffer;
        tag = icvFindTag( storage );

        if( tag < 0 )
        {
            sprintf( errbuf, "Syntax error at line %d, column %d",
                     storage->line, (int)(buffer - storage->line_start) );
            CV_ERROR( CV_StsError, errbuf );
        }

        if( tag == ICV_OPENING_TAG )
        {
            CV_CALL( node = (CvFileNode*)cvSetNew( storage->nodes ));
        }
        else
            node = &stub_node;

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

        buffer = storage->buffer;

        #define process_space()                                 \
            if( c != '\n' )                                     \
                ;                                               \
            else                                                \
                storage->line++, storage->line_start = buffer

        for( ; buffer < storage->buffer_end; buffer++ )
        {
            c = buffer[0];
skip_read:
            if( isspace(c) )
            {
                process_space();
                continue;
            }

            if( isalpha(c) || c == '_' || c == ':' )
            {
                char* name_start = buffer;

                if( need != ICV_NEED_TAGNAME && need != ICV_NEED_ATTRNAME )
                    EXIT;
                do
                {
                    c = *++buffer;
                }
                while( isalnum(c) || c == '_' || c == ':' || c == '.' || c == '-' );

                if( need == ICV_NEED_TAGNAME )
                {
                    buffer[0] = '\0';
                    node->tagname = name_start;

                    if( !isspace(c) && c != '/' && c != '>' )
                        EXIT; // a space or closing angle bracket
                              // should go after tag name
                    need = ICV_NEED_ATTRNAME;
                    goto skip_read;
                }
                else if( need == ICV_NEED_ATTRNAME )
                {

⌨️ 快捷键说明

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