char* parseValue( char* ptr, FileNode& node )
    {
        if (!ptr)
            CV_PARSE_ERROR_CPP("Invalid value input");

        ptr = skipSpaces( ptr );
        if( !ptr || !*ptr )
            CV_PARSE_ERROR_CPP( "Unexpected End-Of-File" );

        if( *ptr == '"' )
        {   /* must be string or Base64 string */
            ptr++;
            char * beg = ptr;
            size_t len = 0u;
            for ( ; (cv_isalnum(*ptr) || *ptr == '$' ) && len <= 9u; ptr++ )
                len++;

            if ( len >= 8u && memcmp( beg, "$base64$", 8u ) == 0 )
            {   /**************** Base64 string ****************/
                CV_PARSE_ERROR_CPP("base64 data is not supported");
#if 0
                ptr = beg += 8;

                std::string base64_buffer;
                base64_buffer.reserve( PARSER_BASE64_BUFFER_SIZE );

                bool is_matching = false;
                while ( !is_matching )
                {
                    switch ( *ptr )
                    {
                        case '\0':
                        {
                            base64_buffer.append( beg, ptr );

                            ptr = fs->gets();
                            if( !ptr || !*ptr )
                                CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );
                            beg = ptr;
                            break;
                        }
                        case '\"':
                        {
                            base64_buffer.append( beg, ptr );
                            beg = ptr;
                            is_matching = true;
                            break;
                        }
                        case '\n':
                        case '\r':
                        {
                            CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );
                            break;
                        }
                        default:
                        {
                            ptr++;
                            break;
                        }
                    }
                }

                if ( *ptr != '\"' )
                    CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );
                else
                    ptr++;

                if ( base64_buffer.size() >= base64::ENCODED_HEADER_SIZE )
                {
                    const char * base64_beg = base64_buffer.data();
                    const char * base64_end = base64_beg + base64_buffer.size();

                    /* get dt from header */
                    std::string dt;
                    {
                        std::vector<char> header(base64::HEADER_SIZE + 1, ' ');
                        base64::base64_decode(base64_beg, header.data(), 0U, base64::ENCODED_HEADER_SIZE);
                        if ( !base64::read_base64_header(header, dt) || dt.empty() )
                            CV_PARSE_ERROR_CPP("Invalid `dt` in Base64 header");
                    }


                    if ( base64_buffer.size() > base64::ENCODED_HEADER_SIZE )
                    {
                        /* set base64_beg to beginning of base64 data */
                        base64_beg = &base64_buffer.at( base64::ENCODED_HEADER_SIZE );
                        if ( !base64::base64_valid( base64_beg, 0U, base64_end - base64_beg ) )
                            CV_PARSE_ERROR_CPP( "Invalid Base64 data." );

                        /* buffer for decoded data(exclude header) */
                        std::vector<uchar> binary_buffer( base64::base64_decode_buffer_size(base64_end - base64_beg) );
                        int total_byte_size = static_cast<int>(
                                                               base64::base64_decode_buffer_size( base64_end - base64_beg, base64_beg, false )
                                                               );
                        {
                            base64::Base64ContextParser parser(binary_buffer.data(), binary_buffer.size() );
                            const uchar * binary_beg = reinterpret_cast<const uchar *>( base64_beg );
                            const uchar * binary_end = binary_beg + (base64_end - base64_beg);
                            parser.read( binary_beg, binary_end );
                            parser.flush();
                        }

                        /* save as CvSeq */
                        int elem_size = ::icvCalcStructSize(dt.c_str(), 0);
                        if (total_byte_size % elem_size != 0)
                            CV_PARSE_ERROR_CPP("Byte size not match elememt size");
                        int elem_cnt = total_byte_size / elem_size;

                        /* after icvFSCreateCollection, node->tag == struct_flags */
                        icvFSCreateCollection(fs, FileNode::FLOW | FileNode::SEQ, node);
                        base64::make_seq(binary_buffer.data(), elem_cnt, dt.c_str(), *node->data.seq);
                    }
                    else
                    {
                        /* empty */
                        icvFSCreateCollection(fs, FileNode::FLOW | FileNode::SEQ, node);
                    }
                }
                else if ( base64_buffer.empty() )
                {
                    /* empty */
                    icvFSCreateCollection(fs, FileNode::FLOW | FileNode::SEQ, node);
                }
                else
                {
                    CV_PARSE_ERROR("Unrecognized Base64 header");
                }
#endif
            }
            else
            {   /**************** normal string ****************/
                int i = 0, sz;

                ptr = beg;
                bool is_matching = false;
                while ( !is_matching )
                {
                    switch ( *ptr )
                    {
                        case '\\':
                        {
                            sz = (int)(ptr - beg);
                            if( sz > 0 )
                            {
                                if (i + sz >= CV_FS_MAX_LEN)
                                    CV_PARSE_ERROR_CPP("string is too long");
                                memcpy(buf + i, beg, sz);
                                i += sz;
                            }
                            ptr++;
                            if (i + 1 >= CV_FS_MAX_LEN)
                                CV_PARSE_ERROR_CPP("string is too long");
                            switch ( *ptr )
                            {
                            case '\\':
                            case '\"':
                            case '\'': { buf[i++] = *ptr; break; }
                            case 'n' : { buf[i++] = '\n'; break; }
                            case 'r' : { buf[i++] = '\r'; break; }
                            case 't' : { buf[i++] = '\t'; break; }
                            case 'b' : { buf[i++] = '\b'; break; }
                            case 'f' : { buf[i++] = '\f'; break; }
                            case 'u' : { CV_PARSE_ERROR_CPP( "'\\uXXXX' currently not supported" ); break; }
                            default  : { CV_PARSE_ERROR_CPP( "Invalid escape character" ); }
                            break;
                            }
                            ptr++;
                            beg = ptr;
                            break;
                        }
                        case '\0':
                        {
                            sz = (int)(ptr - beg);
                            if( sz > 0 )
                            {
                                if (i + sz >= CV_FS_MAX_LEN)
                                    CV_PARSE_ERROR_CPP("string is too long");
                                memcpy(buf + i, beg, sz);
                                i += sz;
                            }
                            ptr = fs->gets();
                            if ( !ptr || !*ptr )
                                CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );

                            beg = ptr;
                            break;
                        }
                        case '\"':
                        {
                            sz = (int)(ptr - beg);
                            if( sz > 0 )
                            {
                                if (i + sz >= CV_FS_MAX_LEN)
                                    CV_PARSE_ERROR_CPP("string is too long");
                                memcpy(buf + i, beg, sz);
                                i += sz;
                            }
                            beg = ptr;
                            is_matching = true;
                            break;
                        }
                        case '\n':
                        case '\r':
                        {
                            CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );
                            break;
                        }
                        default:
                        {
                            ptr++;
                            break;
                        }
                    }
                }

                if ( *ptr != '\"' )
                    CV_PARSE_ERROR_CPP( "'\"' - right-quote of string is missing" );
                else
                    ptr++;

                node.setValue(FileNode::STRING, buf, i);
            }
        }
        else if ( cv_isdigit(*ptr) || *ptr == '-' || *ptr == '+' || *ptr == '.' )
        {    /**************** number ****************/
            char * beg = ptr;
            if ( *ptr == '+' || *ptr == '-' )
            {
                ptr++;
                CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP();
            }
            while( cv_isdigit(*ptr) )
            {
                ptr++;
                CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP();
            }
            if (*ptr == '.' || *ptr == 'e')
            {
                double fval = fs->strtod( beg, &ptr );
                CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP();

                node.setValue(FileNode::REAL, &fval);
            }
            else
            {
                int ival = (int)strtol( beg, &ptr, 0 );
                CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP();

                node.setValue(FileNode::INT, &ival);
            }

            if ( beg >= ptr )
                CV_PARSE_ERROR_CPP( "Invalid numeric value (inconsistent explicit type specification?)" );
        }
        else
        {    /**************** other data ****************/
            const char* beg = ptr;
            int len = 0;
            for ( ; cv_isalpha(*ptr) && len <= 6; )
            {
                len++;
                ptr++;
                CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP();
            }

            if( len == 4 && memcmp( beg, "null", 4 ) == 0 )
            {
                CV_PARSE_ERROR_CPP( "Value 'null' is not supported by this parser" );
            }
            else if( (len == 4 && memcmp( beg, "true", 4 ) == 0) ||
                     (len == 5 && memcmp( beg, "false", 5 ) == 0) )
            {
                int ival = *beg == 't' ? 1 : 0;
                node.setValue(FileNode::INT, &ival);
            }
            else
            {
                CV_PARSE_ERROR_CPP( "Unrecognized value" );
            }
        }

        return ptr;
    }