📄 cxpersistence.cpp
字号:
int datalen = 0;
int struct_flags;
char* ptr;
struct_flags = fs->struct_flags;
if( key && key[0] == '\0' )
key = 0;
if( CV_NODE_IS_COLLECTION(struct_flags) )
{
if( (CV_NODE_IS_MAP(struct_flags) ^ (key != 0)) )
CV_ERROR( CV_StsBadArg, "An attempt to add element without a key to a map, "
"or add element with key to sequence" );
}
else
{
fs->is_first = 0;
struct_flags = CV_NODE_EMPTY | (key ? CV_NODE_MAP : CV_NODE_SEQ);
}
if( key )
{
keylen = (int)strlen(key);
if( keylen == 0 )
CV_ERROR( CV_StsBadArg, "The key is an empty" );
if( keylen > CV_FS_MAX_LEN )
CV_ERROR( CV_StsBadArg, "The key is too long" );
}
if( data )
datalen = (int)strlen(data);
if( CV_NODE_IS_FLOW(struct_flags) )
{
int new_offset;
ptr = fs->buffer;
if( !CV_NODE_IS_EMPTY(struct_flags) )
*ptr++ = ',';
new_offset = (int)(ptr - fs->buffer_start) + keylen + datalen;
if( new_offset > fs->wrap_margin && new_offset - fs->struct_indent > 10 )
{
fs->buffer = ptr;
ptr = icvFSFlush(fs);
}
else
*ptr++ = ' ';
}
else
{
ptr = icvFSFlush(fs);
if( !CV_NODE_IS_MAP(struct_flags) )
{
*ptr++ = '-';
if( data )
*ptr++ = ' ';
}
}
if( key )
{
if( !isalpha(key[0]) && key[0] != '_' )
CV_ERROR( CV_StsBadArg, "Key must start with a letter or _" );
ptr = icvFSResizeWriteBuffer( fs, ptr, keylen );
for( i = 0; i < keylen; i++ )
{
int c = key[i];
ptr[i] = (char)c;
if( !isalnum(c) && c != '-' && c != '_' && c != ' ' )
CV_ERROR( CV_StsBadArg, "Invalid character occurs in the key" );
}
ptr += keylen;
*ptr++ = ':';
if( !CV_NODE_IS_FLOW(struct_flags) && data )
*ptr++ = ' ';
}
if( data )
{
ptr = icvFSResizeWriteBuffer( fs, ptr, datalen );
memcpy( ptr, data, datalen );
ptr += datalen;
}
fs->buffer = ptr;
fs->struct_flags = struct_flags & ~CV_NODE_EMPTY;
__END__;
}
static void
icvYMLStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags,
const char* type_name CV_DEFAULT(0))
{
CV_FUNCNAME( "icvYMLStartWriteStruct" );
__BEGIN__;
int parent_flags;
char buf[CV_FS_MAX_LEN + 1024];
const char* data = 0;
struct_flags = (struct_flags & (CV_NODE_TYPE_MASK|CV_NODE_FLOW)) | CV_NODE_EMPTY;
if( !CV_NODE_IS_COLLECTION(struct_flags))
CV_ERROR( CV_StsBadArg,
"Some collection type - CV_NODE_SEQ or CV_NODE_MAP, must be specified" );
if( CV_NODE_IS_FLOW(struct_flags) )
{
char c = CV_NODE_IS_MAP(struct_flags) ? '{' : '[';
struct_flags |= CV_NODE_FLOW;
if( type_name )
sprintf( buf, "!!%s %c", type_name, c );
else
{
buf[0] = c;
buf[1] = '\0';
}
data = buf;
}
else if( type_name )
{
sprintf( buf, "!!%s", type_name );
data = buf;
}
CV_CALL( icvYMLWrite( fs, key, data, cvFuncName ));
parent_flags = fs->struct_flags;
cvSeqPush( fs->write_stack, &parent_flags );
fs->struct_flags = struct_flags;
if( !CV_NODE_IS_FLOW(parent_flags) )
fs->struct_indent += CV_YML_INDENT + CV_NODE_IS_FLOW(struct_flags);
__END__;
}
static void
icvYMLEndWriteStruct( CvFileStorage* fs )
{
CV_FUNCNAME( "icvYMLEndWriteStruct" );
__BEGIN__;
int parent_flags = 0, struct_flags;
char* ptr;
struct_flags = fs->struct_flags;
if( fs->write_stack->total == 0 )
CV_ERROR( CV_StsError, "EndWriteStruct w/o matching StartWriteStruct" );
cvSeqPop( fs->write_stack, &parent_flags );
if( CV_NODE_IS_FLOW(struct_flags) )
{
ptr = fs->buffer;
if( ptr > fs->buffer_start + fs->struct_indent && !CV_NODE_IS_EMPTY(struct_flags) )
*ptr++ = ' ';
*ptr++ = CV_NODE_IS_MAP(struct_flags) ? '}' : ']';
fs->buffer = ptr;
}
else if( CV_NODE_IS_EMPTY(struct_flags) )
{
ptr = icvFSFlush(fs);
memcpy( ptr, CV_NODE_IS_MAP(struct_flags) ? "{}" : "[]", 2 );
fs->buffer = ptr + 2;
}
if( !CV_NODE_IS_FLOW(parent_flags) )
fs->struct_indent -= CV_YML_INDENT + CV_NODE_IS_FLOW(struct_flags);
assert( fs->struct_indent >= 0 );
fs->struct_flags = parent_flags;
__END__;
}
static void
icvYMLStartNextStream( CvFileStorage* fs )
{
//CV_FUNCNAME( "icvYMLStartNextStream" );
__BEGIN__;
if( !fs->is_first )
{
while( fs->write_stack->total > 0 )
icvYMLEndWriteStruct(fs);
fs->struct_indent = 0;
icvFSFlush(fs);
fputs( "...\n", fs->file );
fputs( "---\n", fs->file );
fs->buffer = fs->buffer_start;
}
__END__;
}
static void
icvYMLWriteInt( CvFileStorage* fs, const char* key, int value )
{
CV_FUNCNAME( "icvYMLWriteInt" );
__BEGIN__;
char buf[128];
CV_CALL( icvYMLWrite( fs, key, icv_itoa( value, buf, 10 ), cvFuncName ));
__END__;
}
static void
icvYMLWriteReal( CvFileStorage* fs, const char* key, double value )
{
CV_FUNCNAME( "icvYMLWriteReal" );
__BEGIN__;
char buf[128];
CV_CALL( icvYMLWrite( fs, key, icvDoubleToString( buf, value ), cvFuncName ));
__END__;
}
static void
icvYMLWriteString( CvFileStorage* fs, const char* key,
const char* str, int quote CV_DEFAULT(0))
{
CV_FUNCNAME( "icvYMLWriteString" );
__BEGIN__;
char buf[CV_FS_MAX_LEN*4+16];
char* data = (char*)str;
int i, len;
if( !str )
CV_ERROR( CV_StsNullPtr, "Null string pointer" );
len = (int)strlen(str);
if( len > CV_FS_MAX_LEN )
CV_ERROR( CV_StsBadArg, "The written string is too long" );
if( quote || len == 0 || str[0] != str[len-1] || str[0] != '\"' && str[0] != '\'' )
{
int need_quote = quote || len == 0;
data = buf;
*data++ = '\"';
for( i = 0; i < len; i++ )
{
char c = str[i];
if( !need_quote && !isalnum(c) && c != '_' && c != ' ' && c != '-' &&
c != '(' && c != ')' && c != '/' && c != '+' && c != ';' )
need_quote = 1;
if( !isalnum(c) && (!cv_isprint(c) || c == '\\' || c == '\'' || c == '\"') )
{
*data++ = '\\';
if( cv_isprint(c) )
*data++ = c;
else if( c == '\n' )
*data++ = 'n';
else if( c == '\r' )
*data++ = 'r';
else if( c == '\t' )
*data++ = 't';
else
{
sprintf( data, "x%02x", c );
data += 3;
}
}
else
*data++ = c;
}
if( !need_quote && (isdigit(str[0]) ||
str[0] == '+' || str[0] == '-' || str[0] == '.' ))
need_quote = 1;
if( need_quote )
*data++ = '\"';
*data++ = '\0';
data = buf + !need_quote;
}
CV_CALL( icvYMLWrite( fs, key, data, cvFuncName ));
__END__;
}
static void
icvYMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment )
{
CV_FUNCNAME( "icvYMLWriteComment" );
__BEGIN__;
int len; //, indent;
int multiline;
const char* eol;
char* ptr;
if( !comment )
CV_ERROR( CV_StsNullPtr, "Null comment" );
len = (int)strlen(comment);
eol = strchr(comment, '\n');
multiline = eol != 0;
ptr = fs->buffer;
if( !eol_comment || multiline ||
fs->buffer_end - ptr < len || ptr == fs->buffer_start )
ptr = icvFSFlush( fs );
else
*ptr++ = ' ';
while( comment )
{
*ptr++ = '#';
*ptr++ = ' ';
if( eol )
{
ptr = icvFSResizeWriteBuffer( fs, ptr, (int)(eol - comment) + 1 );
memcpy( ptr, comment, eol - comment + 1 );
fs->buffer = ptr + (eol - comment);
comment = eol + 1;
eol = strchr( comment, '\n' );
}
else
{
len = (int)strlen(comment);
ptr = icvFSResizeWriteBuffer( fs, ptr, len );
memcpy( ptr, comment, len );
fs->buffer = ptr + len;
comment = 0;
}
ptr = icvFSFlush( fs );
}
__END__;
}
/****************************************************************************************\
* XML Parser *
\****************************************************************************************/
#define CV_XML_INSIDE_COMMENT 1
#define CV_XML_INSIDE_TAG 2
#define CV_XML_INSIDE_DIRECTIVE 3
static char*
icvXMLSkipSpaces( CvFileStorage* fs, char* ptr, int mode )
{
CV_FUNCNAME( "icvXMLSkipSpaces" );
__BEGIN__;
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 == '<';
level -= c == '>';
if( level < 0 )
EXIT;
} while( cv_isprint_or_tab(c) );
}
else
{
do c = *++ptr;
while( c == ' ' || c == '\t' );
if( c == '<' && ptr[1] == '!' && ptr[2] == '-' && ptr[3] == '-' )
{
if( mode != 0 )
CV_PARSE_ERROR( "Comments are not allowed here" );
mode = CV_XML_INSIDE_COMMENT;
ptr += 4;
}
else if( cv_isprint(c) )
break;
}
if( !cv_isprint(*ptr) )
{
int max_size = (int)(fs->buffer_end - fs->buffer_start);
if( *ptr != '\0' && *ptr != '\n' && *ptr != '\r' )
CV_PARSE_ERROR( "Invalid character in the stream" );
ptr = fgets( fs->buffer_start, max_size, fs->file );
if( !ptr )
{
ptr = fs->buffer_start;
*ptr = '\0';
fs->dummy_eof = 1;
break;
}
else
{
int l = (int)strlen(ptr);
if( ptr[l-1] != '\n' && ptr[l-1] != '\r' && !feof(fs->file) )
CV_PARSE_ERROR( "Too long string or a last string w/o newline" );
}
fs->lineno++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -