cvpersistence.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,051 行 · 第 1/5 页
SVN-BASE
2,051 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/* data structures I/O to XML */
#include "_cv.h"
#include <ctype.h>
#define ICV_FORMAT_TEXT 0
#define ICV_FORMAT_BINARY 1
#define ICV_IS_BINARY(storage) (((storage)->flags & 3) == CV_STORAGE_WRITE_BINARY)
#define ICV_IS_WRITE_MODE(storage) (((storage)->flags & 3) != 0)
#define ICV_DT_SHIFT(dt_buf) (dt_buf[0] == '1' && !isdigit(dt_buf[1]))
static const char icvTypeSymbol[] = "ucsifd";
static const char* icvStandardTags[] = { "struct", "elem", 0 };
/* these are hacked versions of strtod & strtol that inserts NUL character
at the possible end-of-number position that speeds up strtod & strtol execution in
case of huge files ('cause they may call strlen() internally) */
static double icv_strtod( const char* ptr, char** endptr )
{
double val;
char* eonum = (char*)ptr;
char char_copy;
while( isspace(*eonum))
eonum++;
while( isdigit(*eonum) || *eonum == '.' || *eonum == '-' ||
*eonum == 'e' || *eonum == 'E' || *eonum == '+' )
eonum++;
char_copy = *eonum;
*eonum = (char)'\0';
val = strtod( ptr, endptr );
*eonum = char_copy;
return val;
}
static long icv_strtol( const char* ptr, char** endptr, int base )
{
long val;
char* eonum = (char*)ptr;
char char_copy;
while( isspace(*eonum))
eonum++;
while( isdigit(*eonum) || *eonum == '-' || *eonum == '+' )
eonum++;
char_copy = *eonum;
*eonum = (char)'\0';
val = strtol( ptr, endptr, base );
*eonum = char_copy;
return val;
}
/* "black box" file storage */
typedef struct CvFileStorage
{
int flags;
int width;
int max_width;
FILE* file;
CvMemStorage* dststorage;
CvMemStorage* memstorage;
CvSet* nodes;
CvFileNode* root;
CvFileNode* parent;
int buffer_size;
int line;
char* filename;
char* base64_buffer;
char* base64_buffer_read;
char* base64_buffer_start;
char* base64_buffer_end;
char* buffer_start;
char* buffer_end;
char* buffer;
char* line_start;
CvFileNode** hashtable;
int hashsize;
}
CvFileStorage;
/*********************************** Adding own types ***********************************/
static int
icvCheckString( const char* str, char termchar CV_DEFAULT(0))
{
int l = 0;
CV_FUNCNAME("icvCheckString");
__BEGIN__;
if( !str )
CV_ERROR( CV_StsNullPtr, "NULL string" );
if( (termchar & ~0x7f) != 0 || termchar == '\\' ||
termchar == '\"' || (termchar != '\0' && !isprint(termchar)))
CV_ERROR( CV_StsBadArg, "Invalid termination character" );
for( ; l < CV_MAX_STRLEN && str[l] != '\0'; l++ )
{
int c = str[l];
/*if( c == '\\' )
{
c = str[++l];
if( c != '\\')// && c != '\"')
CV_ERROR( CV_StsError,
"Only \'\\\\\' esc-sequences is supported" );
continue;
}*/
if( c == termchar )
break;
if( c > 0x7f || !isprint(c) || c == '\"' )
{
char msg[32];
sprintf( msg, "Invalid character: %c (=\'\\x%02x\')", c, c );
CV_ERROR( CV_StsBadArg, msg );
}
}
if( l == CV_MAX_STRLEN )
CV_ERROR( CV_StsOutOfRange, "Too long string" );
__END__;
if( cvGetErrStatus() < 0 )
l = -1;
return l;
}
CV_IMPL const char*
cvAttrValue( const CvAttrList* attr, const char* attr_name )
{
while( attr && attr->attr )
{
int i;
for( i = 0; attr->attr[i*2] != 0; i++ )
{
if( strcmp( attr_name, attr->attr[i*2] ) == 0 )
return attr->attr[i*2+1];
}
attr = attr->next;
}
return 0;
}
static CvFileNode*
icvQueryName( CvFileStorage* storage, const char* name,
CvFileNode* new_node CV_DEFAULT(0))
{
CvFileNode* result_node = 0;
CV_FUNCNAME( "icvQueryName" );
__BEGIN__;
unsigned hash_val = 0;
int i;
CvFileNode* node;
if( !storage || !name )
CV_ERROR( CV_StsNullPtr, "" );
for( i = 0; name[i] != 0; i++ )
hash_val = hash_val*33 + (uchar)name[i];
i = hash_val % storage->hashsize;
for( node = storage->hashtable[i]; node != 0; node = node->hash_next )
{
assert( node->name );
if( node->hash_val == hash_val && strcmp( node->name, name ) == 0 )
break;
}
if( node )
result_node = node;
else if( new_node )
{
new_node->hash_val = hash_val;
assert( strcmp(new_node->name, name) == 0 );
new_node->hash_next = storage->hashtable[i];
storage->hashtable[i] = new_node;
result_node = new_node;
}
__END__;
return result_node;
}
#define ICV_EMPTY_TAG 1
#define ICV_INCOMPLETE_TAG 2
static void
icvPushXMLTag( CvFileStorage* storage, const char* tagname,
CvAttrList _attr, int flags CV_DEFAULT(0))
{
CV_FUNCNAME( "icvPushXMLTag" );
__BEGIN__;
int i, dl;
CvAttrList* attr = &_attr;
assert( storage && storage->file && tagname );
CV_CALL( icvCheckString( tagname ));
assert( storage->width == 0 );
dl = 0;
fprintf( storage->file, "<%s%n", tagname, &dl );
storage->width += dl;
while( attr && attr->attr )
{
for( i = 0; attr->attr[i] != 0; i += 2 )
{
CV_CALL( icvCheckString( attr->attr[i] ));
if( attr->attr[i] == 0 )
CV_ERROR( CV_StsNullPtr, "One of attribute values is NULL" );
CV_CALL( icvCheckString( attr->attr[i+1] ));
dl = 0;
fprintf( storage->file, " %s=\"%s\"%n", attr->attr[i], attr->attr[i+1], &dl );
storage->width += dl;
if( storage->width >= storage->max_width )
{
fprintf( storage->file, "\n" );
storage->width = 0;
}
}
attr = attr->next;
}
if( !(flags & ICV_INCOMPLETE_TAG) )
{
fprintf( storage->file, (flags & ICV_EMPTY_TAG) ? "/>\n" : ">\n" );
storage->width = 0;
}
for( i = 0; icvStandardTags[i] != 0; i++ )
{
if( strcmp( icvStandardTags[i], tagname ) == 0 )
{
tagname = icvStandardTags[i];
break;
}
}
if( icvStandardTags[i] == 0 )
{
char* ptr;
CV_CALL( ptr = (char*)cvMemStorageAlloc( storage->memstorage, strlen(tagname) + 1 ));
strcpy( ptr, tagname );
tagname = ptr;
}
{
CvFileNode* node = (CvFileNode*)cvSetNew( storage->nodes );
memset( node, 0, sizeof(*node));
node->tagname = tagname;
if( storage->root )
{
if( !storage->parent )
CV_ERROR( CV_StsError, "<opencv_storage> is already closed" );
cvInsertNodeIntoTree( node, storage->parent, 0 );
}
else
storage->root = storage->parent = node;
if( !(flags & ICV_EMPTY_TAG) )
storage->parent = node;
}
__END__;
}
static const char icvBase64Tab[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void
icvWriteBase64Block( CvFileStorage* storage, int flush_flag )
{
/*CV_FUNCNAME( "icvWriteBase64Block" );*/
__BEGIN__;
uchar* buffer = (uchar*)storage->base64_buffer_start;
int i, len = storage->base64_buffer - storage->base64_buffer_start;
int val;
for( i = 0; i <= len - 3; i += 3 )
{
int dl = 0;
val = (buffer[i]<<16) + (buffer[i+1]<<8) + buffer[i+2];
fprintf( storage->file, "%c%c%c%c%n",
icvBase64Tab[val >> 18], icvBase64Tab[(val >> 12) & 63],
icvBase64Tab[(val >> 6) & 63], icvBase64Tab[val & 63], &dl );
storage->width += dl;
if( storage->width > 72 )
{
fprintf( storage->file, "\n" );
storage->width = 0;
}
}
if( flush_flag )
{
buffer[len] = buffer[len+1] = '\0';
val = (buffer[i]<<16) + (buffer[i+1]<<8) + buffer[i+2];
switch( len - i )
{
case 0:
if( storage->width )
fprintf( storage->file, "\n" );
break;
case 1:
fprintf( storage->file, "%c%c==\n",
icvBase64Tab[(val >> 18)], icvBase64Tab[(val >> 12) & 63] );
break;
case 2:
fprintf( storage->file, "%c%c%c=\n",
icvBase64Tab[(val >> 18)], icvBase64Tab[(val >> 12) & 63],
icvBase64Tab[(val >> 6) & 63]);
break;
default:
assert(0);
}
storage->width = 0;
storage->base64_buffer = storage->base64_buffer_start;
}
else
{
len -= i;
if( len )
memmove( storage->base64_buffer_start,
storage->base64_buffer_start + i, len );
storage->base64_buffer = storage->base64_buffer_start + len;
}
__END__;
}
static const uchar icvInvBase64Tab[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 62, 255, 255, 255, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 64, 255, 255, 255, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 255, 255, 255, 255, 255, 255, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?