📄 cxpersistence.cpp
字号:
hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i];
hashval &= INT_MAX;
tab_size = map->tab_size;
if( (tab_size & (tab_size - 1)) == 0 )
i = (int)(hashval & (tab_size - 1));
else
i = (int)(hashval % tab_size);
for( node = (CvStringHashNode*)(map->table[i]); node != 0; node = node->next )
{
if( node->hashval == hashval &&
node->str.len == len &&
memcmp( node->str.ptr, str, len ) == 0 )
break;
}
if( !node && create_missing )
{
node = (CvStringHashNode*)cvSetNew( (CvSet*)map );
node->hashval = hashval;
CV_CALL( node->str = cvMemStorageAllocString( map->storage, str, len ));
node->next = (CvStringHashNode*)(map->table[i]);
map->table[i] = node;
}
__END__;
return node;
}
CV_IMPL CvFileNode*
cvGetFileNode( CvFileStorage* fs, CvFileNode* _map_node,
const CvStringHashNode* key,
int create_missing )
{
CvFileNode* value = 0;
CV_FUNCNAME( "cvGetFileNode" );
__BEGIN__;
int k = 0, attempts = 1;
if( !fs )
EXIT;
CV_CHECK_FILE_STORAGE(fs);
if( !key )
CV_ERROR( CV_StsNullPtr, "Null key element" );
if( _map_node )
{
if( !fs->roots )
EXIT;
attempts = fs->roots->total;
}
for( k = 0; k < attempts; k++ )
{
int i, tab_size;
CvFileNode* map_node = _map_node;
CvFileMapNode* another;
CvFileNodeHash* map;
if( !map_node )
map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k );
if( !CV_NODE_IS_MAP(map_node->tag) )
{
if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) &&
CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE )
CV_ERROR( CV_StsError, "The node is neither a map nor an empty collection" );
EXIT;
}
map = map_node->data.map;
tab_size = map->tab_size;
if( (tab_size & (tab_size - 1)) == 0 )
i = (int)(key->hashval & (tab_size - 1));
else
i = (int)(key->hashval % tab_size);
for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next )
if( another->key == key )
{
if( !create_missing )
{
value = &another->value;
EXIT;
}
CV_PARSE_ERROR( "Duplicated key" );
}
if( k == attempts - 1 && create_missing )
{
CvFileMapNode* node = (CvFileMapNode*)cvSetNew( (CvSet*)map );
node->key = key;
node->next = (CvFileMapNode*)(map->table[i]);
map->table[i] = node;
value = (CvFileNode*)node;
}
}
__END__;
return value;
}
CV_IMPL CvFileNode*
cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* _map_node, const char* str )
{
CvFileNode* value = 0;
CV_FUNCNAME( "cvGetFileNodeByName" );
__BEGIN__;
int i, len, tab_size;
unsigned hashval = 0;
int k = 0, attempts = 1;
if( !fs )
EXIT;
CV_CHECK_FILE_STORAGE(fs);
if( !str )
CV_ERROR( CV_StsNullPtr, "Null element name" );
for( i = 0; str[i] != '\0'; i++ )
hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i];
hashval &= INT_MAX;
len = i;
if( !_map_node )
{
if( !fs->roots )
EXIT;
attempts = fs->roots->total;
}
for( k = 0; k < attempts; k++ )
{
CvFileNodeHash* map;
const CvFileNode* map_node = _map_node;
CvFileMapNode* another;
if( !map_node )
map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k );
if( !CV_NODE_IS_MAP(map_node->tag) )
{
if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) &&
CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE )
CV_ERROR( CV_StsError, "The node is neither a map nor an empty collection" );
EXIT;
}
map = map_node->data.map;
tab_size = map->tab_size;
if( (tab_size & (tab_size - 1)) == 0 )
i = (int)(hashval & (tab_size - 1));
else
i = (int)(hashval % tab_size);
for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next )
{
const CvStringHashNode* key = another->key;
if( key->hashval == hashval &&
key->str.len == len &&
memcmp( key->str.ptr, str, len ) == 0 )
{
value = &another->value;
EXIT;
}
}
}
__END__;
return value;
}
CV_IMPL CvFileNode*
cvGetRootFileNode( const CvFileStorage* fs, int stream_index )
{
CvFileNode* value = 0;
CV_FUNCNAME( "cvGetRootFileNode" );
__BEGIN__;
CV_CHECK_FILE_STORAGE(fs);
if( !fs->roots || (unsigned)stream_index >= (unsigned)fs->roots->total )
EXIT;
value = (CvFileNode*)cvGetSeqElem( fs->roots, stream_index );
__END__;
return value;
}
/* returns the sequence element by its index */
/*CV_IMPL CvFileNode*
cvGetFileNodeFromSeq( CvFileStorage* fs,
CvFileNode* seq_node, int index )
{
CvFileNode* value = 0;
CV_FUNCNAME( "cvGetFileNodeFromSeq" );
__BEGIN__;
CvSeq* seq;
if( !seq_node )
seq = fs->roots;
else if( !CV_NODE_IS_SEQ(seq_node->tag) )
{
if( CV_NODE_IS_MAP(seq_node->tag) )
CV_ERROR( CV_StsError, "The node is map. Use cvGetFileNodeFromMap()." );
if( CV_NODE_TYPE(seq_node->tag) == CV_NODE_NONE )
CV_ERROR( CV_StsError, "The node is an empty object (None)." );
if( index != 0 && index != -1 )
CV_ERROR( CV_StsOutOfRange, "" );
value = seq_node;
EXIT;
}
else
seq = seq_node->data.seq;
if( !seq )
CV_ERROR( CV_StsNullPtr, "The file storage is empty" );
value = (CvFileNode*)cvGetSeqElem( seq, index, 0 );
__END__;
return value;
}*/
static char*
icvDoubleToString( char* buf, double value )
{
Cv64suf val;
unsigned ieee754_hi;
val.f = value;
ieee754_hi = (unsigned)(val.u >> 32);
if( (ieee754_hi & 0x7ff00000) != 0x7ff00000 )
{
int ivalue = cvRound(value);
if( ivalue == value )
sprintf( buf, "%d.", ivalue );
else
{
static const char* fmt[] = {"%.16e", "%.16f"};
double avalue = fabs(value);
char* ptr = buf;
sprintf( buf, fmt[0.01 <= avalue && avalue < 1000], value );
if( *ptr == '+' || *ptr == '-' )
ptr++;
for( ; isdigit(*ptr); ptr++ )
;
if( *ptr == ',' )
*ptr = '.';
}
}
else
{
unsigned ieee754_lo = (unsigned)val.u;
if( (ieee754_hi & 0x7fffffff) + (ieee754_lo != 0) > 0x7ff00000 )
strcpy( buf, ".Nan" );
else
strcpy( buf, (int)ieee754_hi < 0 ? "-.Inf" : ".Inf" );
}
return buf;
}
static char*
icvFloatToString( char* buf, float value )
{
Cv32suf val;
unsigned ieee754;
val.f = value;
ieee754 = val.u;
if( (ieee754 & 0x7f800000) != 0x7f800000 )
{
int ivalue = cvRound(value);
if( ivalue == value )
sprintf( buf, "%d.", ivalue );
else
{
static const char* fmt[] = {"%.8e", "%.8f"};
double avalue = fabs((double)value);
char* ptr = buf;
sprintf( buf, fmt[0.01 <= avalue && avalue < 1000], value );
if( *ptr == '+' || *ptr == '-' )
ptr++;
for( ; isdigit(*ptr); ptr++ )
;
if( *ptr == ',' )
*ptr = '.';
}
}
else
{
if( (ieee754 & 0x7fffffff) != 0x7f800000 )
strcpy( buf, ".Nan" );
else
strcpy( buf, (int)ieee754 < 0 ? "-.Inf" : ".Inf" );
}
return buf;
}
static void
icvProcessSpecialDouble( CvFileStorage* fs, char* buf, double* value, char** endptr )
{
CV_FUNCNAME( "icvProcessSpecialDouble" );
__BEGIN__;
char c = buf[0];
int inf_hi = 0x7ff00000;
if( c == '-' || c == '+' )
{
inf_hi = c == '-' ? 0xfff00000 : 0x7ff00000;
c = *++buf;
}
if( c != '.' )
CV_PARSE_ERROR( "Bad format of floating-point constant" );
if( toupper(buf[1]) == 'I' && toupper(buf[2]) == 'N' && toupper(buf[3]) == 'F' )
*(uint64*)value = ((uint64)inf_hi << 32);
else if( toupper(buf[1]) == 'N' && toupper(buf[2]) == 'A' && toupper(buf[3]) == 'N' )
*(uint64*)value = (uint64)-1;
else
CV_PARSE_ERROR( "Bad format of floating-point constant" );
*endptr = buf + 4;
__END__;
}
static double icv_strtod( CvFileStorage* fs, char* ptr, char** endptr )
{
double fval = strtod( ptr, endptr );
if( **endptr == '.' )
{
char* dot_pos = *endptr;
*dot_pos = ',';
double fval2 = strtod( ptr, endptr );
*dot_pos = '.';
if( *endptr > dot_pos )
fval = fval2;
else
*endptr = dot_pos;
}
if( *endptr == ptr || isalpha(**endptr) )
icvProcessSpecialDouble( fs, ptr, &fval, endptr );
return fval;
}
/****************************************************************************************\
* YAML Parser *
\****************************************************************************************/
static char*
icvYMLSkipSpaces( CvFileStorage* fs, char* ptr, int min_indent, int max_comment_indent )
{
CV_FUNCNAME( "icvYMLSkipSpaces" );
__BEGIN__;
for(;;)
{
while( *ptr == ' ' )
ptr++;
if( *ptr == '#' )
{
if( ptr - fs->buffer_start > max_comment_indent )
EXIT;
*ptr = '\0';
}
else if( cv_isprint(*ptr) )
{
if( ptr - fs->buffer_start < min_indent )
CV_PARSE_ERROR( "Incorrect indentation" );
break;
}
else if( *ptr == '\0' || *ptr == '\n' || *ptr == '\r' )
{
int max_size = (int)(fs->buffer_end - fs->buffer_start);
ptr = fgets( fs->buffer_start, max_size, fs->file );
if( !ptr )
{
// emulate end of stream
ptr = fs->buffer_start;
ptr[0] = ptr[1] = ptr[2] = '.';
ptr[3] = '\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++;
}
else
CV_PARSE_ERROR( *ptr == '\t' ? "Tabs are prohibited in YAML!" : "Invalid character" );
}
__END__;
return ptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -