mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
Implemented BASE64 support in cv::FileStorage parser.
This commit is contained in:
parent
225566da7b
commit
bd6ab6d38e
@ -428,10 +428,20 @@ public:
|
||||
return ++ptr;
|
||||
}
|
||||
|
||||
bool getBase64Row(char*, int /*indent*/, char*&, char*&)
|
||||
bool getBase64Row(char* ptr, int /*indent*/, char* &beg, char* &end)
|
||||
{
|
||||
CV_PARSE_ERROR_CPP("Currently, JSON parser does not support base64 data");
|
||||
return false;
|
||||
beg = end = ptr;
|
||||
if( !ptr || !*ptr )
|
||||
return false;
|
||||
|
||||
// find end of the row
|
||||
while( cv_isprint(*ptr) && (*ptr != ',') && (*ptr != '"'))
|
||||
++ptr;
|
||||
if ( *ptr == '\0' )
|
||||
CV_PARSE_ERROR_CPP( "Unexpected end of line" );
|
||||
|
||||
end = ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
char* parseValue( char* ptr, FileNode& node )
|
||||
@ -451,117 +461,15 @@ public:
|
||||
for ( ; (cv_isalnum(*ptr) || *ptr == '$' ) && len <= 9u; ptr++ )
|
||||
len++;
|
||||
|
||||
if ( len >= 8u && memcmp( beg, "$base64$", 8u ) == 0 )
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr = beg + 8;
|
||||
ptr = fs->parseBase64(ptr, 0, node);
|
||||
|
||||
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 ****************/
|
||||
@ -817,7 +725,9 @@ public:
|
||||
else if ( *ptr == '}' )
|
||||
break;
|
||||
else
|
||||
{
|
||||
CV_PARSE_ERROR_CPP( "Unexpected character" );
|
||||
}
|
||||
}
|
||||
|
||||
if (!ptr)
|
||||
|
@ -753,7 +753,7 @@ TEST(Core_InputOutput, filestorage_base64_basic_read_YAML)
|
||||
{
|
||||
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", false);
|
||||
}
|
||||
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_read_JSON)
|
||||
TEST(Core_InputOutput, filestorage_base64_basic_read_JSON)
|
||||
{
|
||||
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user