mirror of https://github.com/opencv/opencv.git
Merge pull request #20143 from rogday:base64_encoding
commit
4ab0377c6e
10 changed files with 2156 additions and 1232 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,370 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#include "precomp.hpp" |
||||||
|
#include "persistence_impl.hpp" |
||||||
|
#include "persistence_base64_encoding.hpp" |
||||||
|
|
||||||
|
namespace cv |
||||||
|
{ |
||||||
|
|
||||||
|
class base64::Base64ContextEmitter |
||||||
|
{ |
||||||
|
public: |
||||||
|
explicit Base64ContextEmitter(cv::FileStorage::Impl& fs, bool needs_indent_) |
||||||
|
: file_storage(fs) |
||||||
|
, needs_indent(needs_indent_) |
||||||
|
, binary_buffer(BUFFER_LEN) |
||||||
|
, base64_buffer(base64_encode_buffer_size(BUFFER_LEN)) |
||||||
|
, src_beg(0) |
||||||
|
, src_cur(0) |
||||||
|
, src_end(0) |
||||||
|
{ |
||||||
|
src_beg = binary_buffer.data(); |
||||||
|
src_end = src_beg + BUFFER_LEN; |
||||||
|
src_cur = src_beg; |
||||||
|
|
||||||
|
CV_Assert(fs.write_mode); |
||||||
|
|
||||||
|
if (needs_indent) |
||||||
|
{ |
||||||
|
file_storage.flush(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
~Base64ContextEmitter() |
||||||
|
{ |
||||||
|
/* cleaning */ |
||||||
|
if (src_cur != src_beg) |
||||||
|
flush(); /* encode the rest binary data to base64 buffer */ |
||||||
|
} |
||||||
|
|
||||||
|
Base64ContextEmitter & write(const uchar * beg, const uchar * end) |
||||||
|
{ |
||||||
|
if (beg >= end) |
||||||
|
return *this; |
||||||
|
|
||||||
|
while (beg < end) { |
||||||
|
/* collect binary data and copy to binary buffer */ |
||||||
|
size_t len = std::min(end - beg, src_end - src_cur); |
||||||
|
std::memcpy(src_cur, beg, len); |
||||||
|
beg += len; |
||||||
|
src_cur += len; |
||||||
|
|
||||||
|
if (src_cur >= src_end) { |
||||||
|
/* binary buffer is full. */ |
||||||
|
/* encode it to base64 and send result to fs */ |
||||||
|
flush(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* a convertor must provide : |
||||||
|
* - `operator >> (uchar * & dst)` for writing current binary data to `dst` and moving to next data. |
||||||
|
* - `operator bool` for checking if current loaction is valid and not the end. |
||||||
|
*/ |
||||||
|
template<typename _to_binary_convertor_t> inline |
||||||
|
Base64ContextEmitter & write(_to_binary_convertor_t & convertor) |
||||||
|
{ |
||||||
|
static const size_t BUFFER_MAX_LEN = 1024U; |
||||||
|
|
||||||
|
std::vector<uchar> buffer(BUFFER_MAX_LEN); |
||||||
|
uchar * beg = buffer.data(); |
||||||
|
uchar * end = beg; |
||||||
|
|
||||||
|
while (convertor) { |
||||||
|
convertor >> end; |
||||||
|
write(beg, end); |
||||||
|
end = beg; |
||||||
|
} |
||||||
|
|
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
bool flush() |
||||||
|
{ |
||||||
|
/* control line width, so on. */ |
||||||
|
size_t len = base64_encode(src_beg, base64_buffer.data(), 0U, src_cur - src_beg); |
||||||
|
if (len == 0U) |
||||||
|
return false; |
||||||
|
|
||||||
|
src_cur = src_beg; |
||||||
|
|
||||||
|
if ( !needs_indent) |
||||||
|
{ |
||||||
|
file_storage.puts((const char*)base64_buffer.data()); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
const char newline[] = "\n"; |
||||||
|
char space[80]; |
||||||
|
int ident = file_storage.write_stack.back().indent; |
||||||
|
memset(space, ' ', static_cast<int>(ident)); |
||||||
|
space[ident] = '\0'; |
||||||
|
|
||||||
|
file_storage.puts(space); |
||||||
|
file_storage.puts((const char*)base64_buffer.data()); |
||||||
|
file_storage.puts(newline); |
||||||
|
file_storage.flush(); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
/* because of Base64, we must keep its length a multiple of 3 */ |
||||||
|
static const size_t BUFFER_LEN = 48U; |
||||||
|
// static_assert(BUFFER_LEN % 3 == 0, "BUFFER_LEN is invalid");
|
||||||
|
|
||||||
|
private: |
||||||
|
cv::FileStorage::Impl& file_storage; |
||||||
|
bool needs_indent; |
||||||
|
|
||||||
|
std::vector<uchar> binary_buffer; |
||||||
|
std::vector<uchar> base64_buffer; |
||||||
|
uchar * src_beg; |
||||||
|
uchar * src_cur; |
||||||
|
uchar * src_end; |
||||||
|
}; |
||||||
|
|
||||||
|
std::string base64::make_base64_header(const char *dt) { |
||||||
|
std::ostringstream oss; |
||||||
|
oss << dt << ' '; |
||||||
|
std::string buffer(oss.str()); |
||||||
|
CV_Assert(buffer.size() < ::base64::HEADER_SIZE); |
||||||
|
|
||||||
|
buffer.reserve(::base64::HEADER_SIZE); |
||||||
|
while (buffer.size() < ::base64::HEADER_SIZE) |
||||||
|
buffer += ' '; |
||||||
|
|
||||||
|
return buffer; |
||||||
|
} |
||||||
|
|
||||||
|
size_t base64::base64_encode(const uint8_t *src, uint8_t *dst, size_t off, size_t cnt) { |
||||||
|
if (!src || !dst || !cnt) |
||||||
|
return 0; |
||||||
|
|
||||||
|
/* initialize beginning and end */ |
||||||
|
uint8_t * dst_beg = dst; |
||||||
|
uint8_t * dst_cur = dst_beg; |
||||||
|
|
||||||
|
uint8_t const * src_beg = src + off; |
||||||
|
uint8_t const * src_cur = src_beg; |
||||||
|
uint8_t const * src_end = src_cur + cnt / 3U * 3U; |
||||||
|
|
||||||
|
/* integer multiples part */ |
||||||
|
while (src_cur < src_end) { |
||||||
|
uint8_t _2 = *src_cur++; |
||||||
|
uint8_t _1 = *src_cur++; |
||||||
|
uint8_t _0 = *src_cur++; |
||||||
|
*dst_cur++ = base64_mapping[ _2 >> 2U]; |
||||||
|
*dst_cur++ = base64_mapping[(_1 & 0xF0U) >> 4U | (_2 & 0x03U) << 4U]; |
||||||
|
*dst_cur++ = base64_mapping[(_0 & 0xC0U) >> 6U | (_1 & 0x0FU) << 2U]; |
||||||
|
*dst_cur++ = base64_mapping[ _0 & 0x3FU]; |
||||||
|
} |
||||||
|
|
||||||
|
/* remainder part */ |
||||||
|
size_t rst = src_beg + cnt - src_cur; |
||||||
|
if (rst == 1U) { |
||||||
|
uint8_t _2 = *src_cur++; |
||||||
|
*dst_cur++ = base64_mapping[ _2 >> 2U]; |
||||||
|
*dst_cur++ = base64_mapping[(_2 & 0x03U) << 4U]; |
||||||
|
} else if (rst == 2U) { |
||||||
|
uint8_t _2 = *src_cur++; |
||||||
|
uint8_t _1 = *src_cur++; |
||||||
|
*dst_cur++ = base64_mapping[ _2 >> 2U]; |
||||||
|
*dst_cur++ = base64_mapping[(_2 & 0x03U) << 4U | (_1 & 0xF0U) >> 4U]; |
||||||
|
*dst_cur++ = base64_mapping[(_1 & 0x0FU) << 2U]; |
||||||
|
} |
||||||
|
|
||||||
|
/* padding */ |
||||||
|
switch (rst) |
||||||
|
{ |
||||||
|
case 1U: *dst_cur++ = base64_padding; |
||||||
|
/* fallthrough */ |
||||||
|
case 2U: *dst_cur++ = base64_padding; |
||||||
|
/* fallthrough */ |
||||||
|
default: *dst_cur = 0; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
return static_cast<size_t>(dst_cur - dst_beg); |
||||||
|
} |
||||||
|
|
||||||
|
int base64::icvCalcStructSize(const char *dt, int initial_size) { |
||||||
|
int size = cv::fs::calcElemSize( dt, initial_size ); |
||||||
|
size_t elem_max_size = 0; |
||||||
|
for ( const char * type = dt; *type != '\0'; type++ ) { |
||||||
|
switch ( *type ) |
||||||
|
{ |
||||||
|
case 'u': { elem_max_size = std::max( elem_max_size, sizeof(uchar ) ); break; } |
||||||
|
case 'c': { elem_max_size = std::max( elem_max_size, sizeof(schar ) ); break; } |
||||||
|
case 'w': { elem_max_size = std::max( elem_max_size, sizeof(ushort) ); break; } |
||||||
|
case 's': { elem_max_size = std::max( elem_max_size, sizeof(short ) ); break; } |
||||||
|
case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; } |
||||||
|
case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; } |
||||||
|
case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; } |
||||||
|
default: break; |
||||||
|
} |
||||||
|
} |
||||||
|
size = cvAlign( size, static_cast<int>(elem_max_size) ); |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
size_t base64::base64_encode_buffer_size(size_t cnt, bool is_end_with_zero) { |
||||||
|
size_t additional = static_cast<size_t>(is_end_with_zero == true); |
||||||
|
return (cnt + 2U) / 3U * 4U + additional; |
||||||
|
} |
||||||
|
|
||||||
|
base64::Base64Writer::Base64Writer(cv::FileStorage::Impl& fs, bool can_indent) |
||||||
|
: emitter(new Base64ContextEmitter(fs, can_indent)) |
||||||
|
, data_type_string() |
||||||
|
{ |
||||||
|
CV_Assert(fs.write_mode); |
||||||
|
} |
||||||
|
|
||||||
|
void base64::Base64Writer::write(const void* _data, size_t len, const char* dt) |
||||||
|
{ |
||||||
|
check_dt(dt); |
||||||
|
RawDataToBinaryConvertor convertor(_data, static_cast<int>(len), data_type_string); |
||||||
|
emitter->write(convertor); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename _to_binary_convertor_t> inline |
||||||
|
void base64::Base64Writer::write(_to_binary_convertor_t & convertor, const char* dt) |
||||||
|
{ |
||||||
|
check_dt(dt); |
||||||
|
emitter->write(convertor); |
||||||
|
} |
||||||
|
|
||||||
|
base64::Base64Writer::~Base64Writer() |
||||||
|
{ |
||||||
|
delete emitter; |
||||||
|
} |
||||||
|
|
||||||
|
void base64::Base64Writer::check_dt(const char* dt) |
||||||
|
{ |
||||||
|
if ( dt == 0 ) |
||||||
|
CV_Error( cv::Error::StsBadArg, "Invalid \'dt\'." ); |
||||||
|
else if (data_type_string.empty()) { |
||||||
|
data_type_string = dt; |
||||||
|
|
||||||
|
/* output header */ |
||||||
|
std::string buffer = make_base64_header(dt); |
||||||
|
const uchar * beg = reinterpret_cast<const uchar *>(buffer.data()); |
||||||
|
const uchar * end = beg + buffer.size(); |
||||||
|
|
||||||
|
emitter->write(beg, end); |
||||||
|
} else if ( data_type_string != dt ) |
||||||
|
CV_Error( cv::Error::StsBadArg, "\'dt\' does not match." ); |
||||||
|
} |
||||||
|
|
||||||
|
base64::RawDataToBinaryConvertor::RawDataToBinaryConvertor(const void* src, int len, const std::string & dt) |
||||||
|
: beg(reinterpret_cast<const uchar *>(src)) |
||||||
|
, cur(0) |
||||||
|
, end(0) |
||||||
|
{ |
||||||
|
CV_Assert(src); |
||||||
|
CV_Assert(!dt.empty()); |
||||||
|
CV_Assert(len > 0); |
||||||
|
|
||||||
|
/* calc step and to_binary_funcs */ |
||||||
|
step_packed = make_to_binary_funcs(dt); |
||||||
|
|
||||||
|
end = beg; |
||||||
|
cur = beg; |
||||||
|
|
||||||
|
step = icvCalcStructSize(dt.c_str(), 0); |
||||||
|
end = beg + static_cast<size_t>(len); |
||||||
|
} |
||||||
|
|
||||||
|
inline base64::RawDataToBinaryConvertor& base64::RawDataToBinaryConvertor::operator >>(uchar * & dst) |
||||||
|
{ |
||||||
|
CV_DbgAssert(*this); |
||||||
|
|
||||||
|
for (size_t i = 0U, n = to_binary_funcs.size(); i < n; i++) { |
||||||
|
elem_to_binary_t & pack = to_binary_funcs[i]; |
||||||
|
pack.func(cur + pack.offset, dst + pack.offset_packed); |
||||||
|
} |
||||||
|
cur += step; |
||||||
|
dst += step_packed; |
||||||
|
|
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
inline base64::RawDataToBinaryConvertor::operator bool() const |
||||||
|
{ |
||||||
|
return cur < end; |
||||||
|
} |
||||||
|
|
||||||
|
size_t base64::RawDataToBinaryConvertor::make_to_binary_funcs(const std::string &dt) |
||||||
|
{ |
||||||
|
size_t cnt = 0; |
||||||
|
size_t offset = 0; |
||||||
|
size_t offset_packed = 0; |
||||||
|
char type = '\0'; |
||||||
|
|
||||||
|
std::istringstream iss(dt); |
||||||
|
while (!iss.eof()) { |
||||||
|
if (!(iss >> cnt)) { |
||||||
|
iss.clear(); |
||||||
|
cnt = 1; |
||||||
|
} |
||||||
|
CV_Assert(cnt > 0U); |
||||||
|
if (!(iss >> type)) |
||||||
|
break; |
||||||
|
|
||||||
|
while (cnt-- > 0) |
||||||
|
{ |
||||||
|
elem_to_binary_t pack; |
||||||
|
|
||||||
|
size_t size = 0; |
||||||
|
switch (type) |
||||||
|
{ |
||||||
|
case 'u': |
||||||
|
case 'c': |
||||||
|
size = sizeof(uchar); |
||||||
|
pack.func = to_binary<uchar>; |
||||||
|
break; |
||||||
|
case 'w': |
||||||
|
case 's': |
||||||
|
size = sizeof(ushort); |
||||||
|
pack.func = to_binary<ushort>; |
||||||
|
break; |
||||||
|
case 'i': |
||||||
|
size = sizeof(uint); |
||||||
|
pack.func = to_binary<uint>; |
||||||
|
break; |
||||||
|
case 'f': |
||||||
|
size = sizeof(float); |
||||||
|
pack.func = to_binary<float>; |
||||||
|
break; |
||||||
|
case 'd': |
||||||
|
size = sizeof(double); |
||||||
|
pack.func = to_binary<double>; |
||||||
|
break; |
||||||
|
case 'r': |
||||||
|
default: |
||||||
|
CV_Error(cv::Error::StsError, "type is not supported"); |
||||||
|
}; |
||||||
|
|
||||||
|
offset = static_cast<size_t>(cvAlign(static_cast<int>(offset), static_cast<int>(size))); |
||||||
|
pack.offset = offset; |
||||||
|
offset += size; |
||||||
|
|
||||||
|
pack.offset_packed = offset_packed; |
||||||
|
offset_packed += size; |
||||||
|
|
||||||
|
to_binary_funcs.push_back(pack); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
CV_Assert(iss.eof()); |
||||||
|
return offset_packed; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#ifndef OPENCV_CORE_BASE64_ENCODING_HPP |
||||||
|
#define OPENCV_CORE_BASE64_ENCODING_HPP |
||||||
|
|
||||||
|
namespace cv |
||||||
|
{ |
||||||
|
|
||||||
|
namespace base64 |
||||||
|
{ |
||||||
|
/* A decorator for CvFileStorage
|
||||||
|
* - no copyable |
||||||
|
* - not safe for now |
||||||
|
* - move constructor may be needed if C++11 |
||||||
|
*/ |
||||||
|
uint8_t const base64_mapping[] = |
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
||||||
|
"abcdefghijklmnopqrstuvwxyz" |
||||||
|
"0123456789+/"; |
||||||
|
|
||||||
|
uint8_t const base64_padding = '='; |
||||||
|
|
||||||
|
std::string make_base64_header(const char * dt); |
||||||
|
|
||||||
|
size_t base64_encode(uint8_t const * src, uint8_t * dst, size_t off, size_t cnt); |
||||||
|
|
||||||
|
|
||||||
|
int icvCalcStructSize( const char* dt, int initial_size ); |
||||||
|
|
||||||
|
class Base64ContextEmitter; |
||||||
|
class Impl; |
||||||
|
|
||||||
|
class Base64Writer |
||||||
|
{ |
||||||
|
public: |
||||||
|
Base64Writer(cv::FileStorage::Impl& fs, bool can_indent); |
||||||
|
~Base64Writer(); |
||||||
|
void write(const void* _data, size_t len, const char* dt); |
||||||
|
template<typename _to_binary_convertor_t> void write(_to_binary_convertor_t & convertor, const char* dt); |
||||||
|
|
||||||
|
private: |
||||||
|
void check_dt(const char* dt); |
||||||
|
|
||||||
|
private: |
||||||
|
// disable copy and assignment
|
||||||
|
Base64Writer(const Base64Writer &); |
||||||
|
Base64Writer & operator=(const Base64Writer &); |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
Base64ContextEmitter * emitter; |
||||||
|
std::string data_type_string; |
||||||
|
}; |
||||||
|
|
||||||
|
size_t base64_encode_buffer_size(size_t cnt, bool is_end_with_zero = true); |
||||||
|
|
||||||
|
template<typename _uint_t> inline size_t |
||||||
|
to_binary(_uint_t val, uchar * cur) |
||||||
|
{ |
||||||
|
size_t delta = CHAR_BIT; |
||||||
|
size_t cnt = sizeof(_uint_t); |
||||||
|
while (cnt --> static_cast<size_t>(0U)) { |
||||||
|
*cur++ = static_cast<uchar>(val); |
||||||
|
val >>= delta; |
||||||
|
} |
||||||
|
return sizeof(_uint_t); |
||||||
|
} |
||||||
|
|
||||||
|
template<> inline size_t to_binary(double val, uchar * cur) |
||||||
|
{ |
||||||
|
Cv64suf bit64; |
||||||
|
bit64.f = val; |
||||||
|
return to_binary(bit64.u, cur); |
||||||
|
} |
||||||
|
|
||||||
|
template<> inline size_t to_binary(float val, uchar * cur) |
||||||
|
{ |
||||||
|
Cv32suf bit32; |
||||||
|
bit32.f = val; |
||||||
|
return to_binary(bit32.u, cur); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename _primitive_t> inline size_t |
||||||
|
to_binary(uchar const * val, uchar * cur) |
||||||
|
{ |
||||||
|
return to_binary<_primitive_t>(*reinterpret_cast<_primitive_t const *>(val), cur); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RawDataToBinaryConvertor |
||||||
|
{ |
||||||
|
public: |
||||||
|
// NOTE: len is already multiplied by element size here
|
||||||
|
RawDataToBinaryConvertor(const void* src, int len, const std::string & dt); |
||||||
|
|
||||||
|
inline RawDataToBinaryConvertor & operator >>(uchar * & dst); |
||||||
|
inline operator bool() const; |
||||||
|
|
||||||
|
private: |
||||||
|
typedef size_t(*to_binary_t)(const uchar *, uchar *); |
||||||
|
struct elem_to_binary_t |
||||||
|
{ |
||||||
|
size_t offset; |
||||||
|
size_t offset_packed; |
||||||
|
to_binary_t func; |
||||||
|
}; |
||||||
|
|
||||||
|
private: |
||||||
|
size_t make_to_binary_funcs(const std::string &dt); |
||||||
|
|
||||||
|
private: |
||||||
|
const uchar * beg; |
||||||
|
const uchar * cur; |
||||||
|
const uchar * end; |
||||||
|
|
||||||
|
size_t step; |
||||||
|
size_t step_packed; |
||||||
|
std::vector<elem_to_binary_t> to_binary_funcs; |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,231 @@ |
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#ifndef OPENCV_CORE_PERSISTENCE_IMPL_HPP |
||||||
|
#define OPENCV_CORE_PERSISTENCE_IMPL_HPP |
||||||
|
|
||||||
|
#include "persistence.hpp" |
||||||
|
#include "persistence_base64_encoding.hpp" |
||||||
|
#include <unordered_map> |
||||||
|
#include <iterator> |
||||||
|
|
||||||
|
|
||||||
|
namespace cv |
||||||
|
{ |
||||||
|
|
||||||
|
enum Base64State{ |
||||||
|
Uncertain, |
||||||
|
NotUse, |
||||||
|
InUse, |
||||||
|
}; |
||||||
|
|
||||||
|
class cv::FileStorage::Impl : public FileStorage_API |
||||||
|
{ |
||||||
|
public: |
||||||
|
void init(); |
||||||
|
|
||||||
|
Impl(FileStorage* _fs); |
||||||
|
|
||||||
|
virtual ~Impl(); |
||||||
|
|
||||||
|
void release(String* out=0); |
||||||
|
|
||||||
|
void analyze_file_name( const std::string& file_name, std::vector<std::string>& params ); |
||||||
|
|
||||||
|
bool open( const char* filename_or_buf, int _flags, const char* encoding ); |
||||||
|
|
||||||
|
void puts( const char* str ); |
||||||
|
|
||||||
|
char* getsFromFile( char* buf, int count ); |
||||||
|
|
||||||
|
char* gets( size_t maxCount ); |
||||||
|
|
||||||
|
char* gets(); |
||||||
|
|
||||||
|
bool eof(); |
||||||
|
|
||||||
|
void setEof(); |
||||||
|
|
||||||
|
void closeFile(); |
||||||
|
|
||||||
|
void rewind(); |
||||||
|
|
||||||
|
char* resizeWriteBuffer( char* ptr, int len ); |
||||||
|
|
||||||
|
char* flush(); |
||||||
|
|
||||||
|
void endWriteStruct(); |
||||||
|
|
||||||
|
void startWriteStruct_helper( const char* key, int struct_flags, |
||||||
|
const char* type_name ); |
||||||
|
|
||||||
|
void startWriteStruct( const char* key, int struct_flags, |
||||||
|
const char* type_name ); |
||||||
|
|
||||||
|
void writeComment( const char* comment, bool eol_comment ); |
||||||
|
|
||||||
|
void startNextStream(); |
||||||
|
|
||||||
|
void write( const String& key, int value ); |
||||||
|
|
||||||
|
void write( const String& key, double value ); |
||||||
|
|
||||||
|
void write( const String& key, const String& value ); |
||||||
|
|
||||||
|
void writeRawData( const std::string& dt, const void* _data, size_t len ); |
||||||
|
|
||||||
|
void workaround(); |
||||||
|
|
||||||
|
void switch_to_Base64_state( FileStorage_API::Base64State new_state); |
||||||
|
|
||||||
|
void make_write_struct_delayed( const char* key, int struct_flags, const char* type_name ); |
||||||
|
|
||||||
|
void check_if_write_struct_is_delayed( bool change_type_to_base64 ); |
||||||
|
|
||||||
|
void writeRawDataBase64(const void* _data, size_t len, const char* dt ); |
||||||
|
|
||||||
|
String releaseAndGetString(); |
||||||
|
|
||||||
|
FileNode getFirstTopLevelNode() const; |
||||||
|
|
||||||
|
FileNode root(int streamIdx=0) const; |
||||||
|
|
||||||
|
FileNode operator[](const String& nodename) const; |
||||||
|
|
||||||
|
FileNode operator[](const char* /*nodename*/) const; |
||||||
|
|
||||||
|
int getFormat() const; |
||||||
|
|
||||||
|
char* bufferPtr() const; |
||||||
|
char* bufferStart() const; |
||||||
|
char* bufferEnd() const; |
||||||
|
void setBufferPtr(char* ptr); |
||||||
|
int wrapMargin() const; |
||||||
|
|
||||||
|
FStructData& getCurrentStruct(); |
||||||
|
|
||||||
|
void setNonEmpty(); |
||||||
|
|
||||||
|
void processSpecialDouble( char* buf, double* value, char** endptr ); |
||||||
|
|
||||||
|
double strtod( char* ptr, char** endptr ); |
||||||
|
|
||||||
|
void convertToCollection(int type, FileNode& node); |
||||||
|
|
||||||
|
// a) allocates new FileNode (for that just set blockIdx to the last block and ofs to freeSpaceOfs) or
|
||||||
|
// b) reallocates just created new node (blockIdx and ofs must be taken from FileNode).
|
||||||
|
// If there is no enough space in the current block (it should be the last block added so far),
|
||||||
|
// the last block is shrunk so that it ends immediately before the reallocated node. Then,
|
||||||
|
// a new block of sufficient size is allocated and the FileNode is placed in the beginning of it.
|
||||||
|
// The case (a) can be used to allocate the very first node by setting blockIdx == ofs == 0.
|
||||||
|
// In the case (b) the existing tag and the name are copied automatically.
|
||||||
|
uchar* reserveNodeSpace(FileNode& node, size_t sz); |
||||||
|
|
||||||
|
unsigned getStringOfs( const std::string& key ) const; |
||||||
|
|
||||||
|
FileNode addNode( FileNode& collection, const std::string& key, |
||||||
|
int elem_type, const void* value, int len ); |
||||||
|
|
||||||
|
void finalizeCollection( FileNode& collection ); |
||||||
|
|
||||||
|
void normalizeNodeOfs(size_t& blockIdx, size_t& ofs) const; |
||||||
|
|
||||||
|
Base64State get_state_of_writing_base64(); |
||||||
|
|
||||||
|
int get_space(); |
||||||
|
|
||||||
|
class Base64Decoder |
||||||
|
{ |
||||||
|
public: |
||||||
|
Base64Decoder(); |
||||||
|
void init(Ptr<FileStorageParser>& _parser, char* _ptr, int _indent); |
||||||
|
|
||||||
|
bool readMore(int needed); |
||||||
|
|
||||||
|
uchar getUInt8(); |
||||||
|
|
||||||
|
ushort getUInt16(); |
||||||
|
|
||||||
|
int getInt32(); |
||||||
|
|
||||||
|
double getFloat64(); |
||||||
|
|
||||||
|
bool endOfStream() const; |
||||||
|
char* getPtr() const; |
||||||
|
protected: |
||||||
|
|
||||||
|
Ptr<FileStorageParser> parser; |
||||||
|
char* ptr; |
||||||
|
int indent; |
||||||
|
std::vector<char> encoded; |
||||||
|
std::vector<uchar> decoded; |
||||||
|
size_t ofs; |
||||||
|
size_t totalchars; |
||||||
|
bool eos; |
||||||
|
}; |
||||||
|
|
||||||
|
char* parseBase64(char* ptr, int indent, FileNode& collection); |
||||||
|
|
||||||
|
void parseError( const char* func_name, const std::string& err_msg, const char* source_file, int source_line ); |
||||||
|
|
||||||
|
const uchar* getNodePtr(size_t blockIdx, size_t ofs) const; |
||||||
|
|
||||||
|
std::string getName( size_t nameofs ) const; |
||||||
|
|
||||||
|
FileStorage* getFS(); |
||||||
|
|
||||||
|
FileStorage* fs_ext; |
||||||
|
|
||||||
|
std::string filename; |
||||||
|
int flags; |
||||||
|
bool empty_stream; |
||||||
|
|
||||||
|
FILE* file; |
||||||
|
gzFile gzfile; |
||||||
|
|
||||||
|
bool is_opened; |
||||||
|
bool dummy_eof; |
||||||
|
bool write_mode; |
||||||
|
bool mem_mode; |
||||||
|
int fmt; |
||||||
|
|
||||||
|
State state; //!< current state of the FileStorage (used only for writing)
|
||||||
|
bool is_using_base64; |
||||||
|
bool is_write_struct_delayed; |
||||||
|
char* delayed_struct_key; |
||||||
|
int delayed_struct_flags; |
||||||
|
char* delayed_type_name; |
||||||
|
FileStorage_API::Base64State state_of_writing_base64; |
||||||
|
|
||||||
|
int space, wrap_margin; |
||||||
|
std::deque<FStructData> write_stack; |
||||||
|
std::vector<char> buffer; |
||||||
|
size_t bufofs; |
||||||
|
|
||||||
|
std::deque<char> outbuf; |
||||||
|
|
||||||
|
Ptr<FileStorageEmitter> emitter; |
||||||
|
Ptr<FileStorageParser> parser; |
||||||
|
Base64Decoder base64decoder; |
||||||
|
base64::Base64Writer* base64_writer; |
||||||
|
|
||||||
|
std::vector<FileNode> roots; |
||||||
|
std::vector<Ptr<std::vector<uchar> > > fs_data; |
||||||
|
std::vector<uchar*> fs_data_ptrs; |
||||||
|
std::vector<size_t> fs_data_blksz; |
||||||
|
size_t freeSpaceOfs; |
||||||
|
typedef std::unordered_map<std::string, unsigned> str_hash_t; |
||||||
|
str_hash_t str_hash; |
||||||
|
std::vector<char> str_hash_data; |
||||||
|
|
||||||
|
std::vector<char> strbufv; |
||||||
|
char* strbuf; |
||||||
|
size_t strbufsize; |
||||||
|
size_t strbufpos; |
||||||
|
int lineno; |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue