opencv/modules/core/src/persistence_impl.hpp
2022-01-18 04:56:43 +00:00

250 lines
6.6 KiB
C++

// 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(const 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_do_not_use_direct_dereference;
FileStorageParser& getParser() const
{
if (!parser_do_not_use_direct_dereference)
CV_Error(Error::StsNullPtr, "Parser is not available");
return *parser_do_not_use_direct_dereference;
}
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_do_not_use_direct_dereference;
FileStorageEmitter& getEmitter()
{
if (!emitter_do_not_use_direct_dereference)
CV_Error(Error::StsNullPtr, "Emitter is not available");
return *emitter_do_not_use_direct_dereference;
}
Ptr<FileStorageParser> parser_do_not_use_direct_dereference;
FileStorageParser& getParser() const
{
if (!parser_do_not_use_direct_dereference)
CV_Error(Error::StsNullPtr, "Parser is not available");
return *parser_do_not_use_direct_dereference;
}
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