Commit 60a0ebbd authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

added optional encoding parameter to cvOpenFileStorage() and FileStorage::open()…

added optional encoding parameter to cvOpenFileStorage() and FileStorage::open() (ticket #976). moved some implementation parts of CommandLineParser to cmdparser.cpp.
parent 81060431
......@@ -3804,14 +3804,14 @@ public:
//! the default constructor
CV_WRAP FileStorage();
//! the full constructor that opens file storage for reading or writing
CV_WRAP FileStorage(const string& filename, int flags);
CV_WRAP FileStorage(const string& filename, int flags, const string& encoding=string());
//! the constructor that takes pointer to the C FileStorage structure
FileStorage(CvFileStorage* fs);
//! the destructor. calls release()
virtual ~FileStorage();
//! opens file storage for reading or writing. The previous storage is closed with release()
CV_WRAP virtual bool open(const string& filename, int flags);
CV_WRAP virtual bool open(const string& filename, int flags, const string& encoding=string());
//! returns true if the object is associated with currently opened file.
CV_WRAP virtual bool isOpened() const;
//! closes the file and releases all the memory buffers
......@@ -4193,7 +4193,7 @@ class CV_EXPORTS CommandLineParser
std::string str = getString(name);
if (!has(name))
return default_value;
return analizeValue<_Tp>(str);
return analyzeValue<_Tp>(str);
}
protected:
......@@ -4201,55 +4201,23 @@ class CV_EXPORTS CommandLineParser
std::string getString(const std::string& name) const;
template<typename _Tp>
_Tp analizeValue(const std::string& str);
template<typename _Tp>
static _Tp getData(const std::string& str)
{
_Tp res;
std::stringstream s1(str);
s1 >> res;
return res;
}
template<typename _Tp>
static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers
{
if (str.empty())
CV_Error(CV_StsParseError, "Empty string cannot be converted to a number");
const char* c_str=str.c_str();
if((!isdigit(c_str[0]))
&&
(
(c_str[0]!='-') || (strlen(c_str) <= 1) || ( !isdigit(c_str[1]) )
)
)
{
CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number");
}
return getData<_Tp>(str);
}
_Tp analyzeValue(const std::string& str);
};
template<> CV_EXPORTS
std::string CommandLineParser::analizeValue<std::string>(const std::string& str);
std::string CommandLineParser::analyzeValue<std::string>(const std::string& str);
template<> CV_EXPORTS
int CommandLineParser::analizeValue<int>(const std::string& str);
int CommandLineParser::analyzeValue<int>(const std::string& str);
template<> CV_EXPORTS
unsigned CommandLineParser::analizeValue<unsigned int>(const std::string& str);
unsigned CommandLineParser::analyzeValue<unsigned int>(const std::string& str);
template<> CV_EXPORTS
float CommandLineParser::analizeValue<float>(const std::string& str);
float CommandLineParser::analyzeValue<float>(const std::string& str);
template<> CV_EXPORTS
double CommandLineParser::analizeValue<double>(const std::string& str);
double CommandLineParser::analyzeValue<double>(const std::string& str);
}
......
......@@ -1525,9 +1525,8 @@ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
/********************************** High-level functions ********************************/
/* opens existing or creates new file storage */
CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename,
CvMemStorage* memstorage,
int flags );
CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage,
int flags, const char* encoding CV_DEFAULT(NULL) );
/* closes file storage and deallocates buffers */
CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs );
......
......@@ -32,7 +32,7 @@ void PreprocessArgs(int _argc, const char* _argv[], int& argc, char**& argv)
find_symbol = buffer_string.find('=');
if (find_symbol == -1)
buffer_vector.push_back(buffer_string);
else if (find_symbol == 0 || find_symbol == (buffer_string.length() - 1))
else if (find_symbol == 0 || find_symbol == (int)(buffer_string.length() - 1))
{
buffer_string.erase(find_symbol, (find_symbol + 1));
if(!buffer_string.empty())
......@@ -135,32 +135,56 @@ std::string CommandLineParser::getString(const std::string& keys) const
}
template<typename _Tp>
static _Tp getData(const std::string& str)
{
_Tp res;
std::stringstream s1(str);
s1 >> res;
return res;
}
template<typename _Tp>
static _Tp fromStringNumber(const std::string& str)//the default conversion function for numbers
{
if (str.empty())
CV_Error(CV_StsParseError, "Empty string cannot be converted to a number");
const char* c_str=str.c_str();
if( !isdigit(c_str[0]) &&
(c_str[0] != '-' || strlen(c_str) <= 1 || !isdigit(c_str[1]) ))
CV_Error(CV_StsParseError, "The string '"+ str +"' cannot be converted to a number");
return getData<_Tp>(str);
}
template<>
std::string CommandLineParser::analizeValue<std::string>(const std::string& str)
std::string CommandLineParser::analyzeValue<std::string>(const std::string& str)
{
return str;
}
template<>
int CommandLineParser::analizeValue<int>(const std::string& str)
int CommandLineParser::analyzeValue<int>(const std::string& str)
{
return fromStringNumber<int>(str);
}
template<>
unsigned int CommandLineParser::analizeValue<unsigned int>(const std::string& str)
unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str)
{
return fromStringNumber<unsigned int>(str);
}
template<>
float CommandLineParser::analizeValue<float>(const std::string& str)
float CommandLineParser::analyzeValue<float>(const std::string& str)
{
return fromStringNumber<float>(str);
}
template<>
double CommandLineParser::analizeValue<double>(const std::string& str)
double CommandLineParser::analyzeValue<double>(const std::string& str)
{
return fromStringNumber<double>(str);
}
......
......@@ -2167,13 +2167,15 @@ icvXMLParse( CvFileStorage* fs )
if( version && strncmp( version, "1.", 2 ) != 0 )
CV_Error( CV_StsParseError, "Unsupported version of XML" );
}*/
{
// we support any 8-bit encoding, so we do not need to check the actual encoding.
// we do not support utf-16, but in the case of utf-16 we will not get here anyway.
/*{
const char* encoding = cvAttrValue( list, "encoding" );
if( encoding && strcmp( encoding, "ASCII" ) != 0 &&
strcmp( encoding, "UTF-8" ) != 0 &&
strcmp( encoding, "utf-8" ) != 0 )
CV_PARSE_ERROR( "Unsupported encoding" );
}
}*/
while( *ptr != '\0' )
{
......@@ -2587,7 +2589,7 @@ icvXMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment )
\****************************************************************************************/
CV_IMPL CvFileStorage*
cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags )
cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, const char* encoding )
{
CvFileStorage* fs = 0;
char* xml_buf = 0;
......@@ -2673,7 +2675,20 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags )
fs->strstorage = cvCreateChildMemStorage( fs->memstorage );
if( !append || file_size == 0 )
{
icvPuts( fs, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
if( encoding )
{
if( strcmp( encoding, "UTF-16" ) == 0 ||
strcmp( encoding, "utf-16" ) == 0 ||
strcmp( encoding, "Utf-16" ) == 0 )
CV_Error( CV_StsBadArg, "UTF-16 XML encoding is not supported! Use 8-bit encoding\n");
CV_Assert( strlen(encoding) < 1000 );
char buf[1100];
sprintf(buf, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
icvPuts( fs, buf );
}
else
icvPuts( fs, "<?xml version=\"1.0\"?>\n" );
icvPuts( fs, "<opencv_storage>\n" );
}
else
......@@ -4995,10 +5010,10 @@ FileStorage::FileStorage()
state = UNDEFINED;
}
FileStorage::FileStorage(const string& filename, int flags)
FileStorage::FileStorage(const string& filename, int flags, const string& encoding)
{
state = UNDEFINED;
open( filename, flags );
open( filename, flags, encoding );
}
FileStorage::FileStorage(CvFileStorage* _fs)
......@@ -5016,10 +5031,11 @@ FileStorage::~FileStorage()
}
}
bool FileStorage::open(const string& filename, int flags)
bool FileStorage::open(const string& filename, int flags, const string& encoding)
{
release();
fs = Ptr<CvFileStorage>(cvOpenFileStorage( filename.c_str(), 0, flags ));
fs = Ptr<CvFileStorage>(cvOpenFileStorage( filename.c_str(), 0, flags,
!encoding.empty() ? encoding.c_str() : 0));
bool ok = isOpened();
state = ok ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED;
return ok;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment