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