| 1 | // This file is part of OpenCV project. |
| 2 | // It is subject to the license terms in the LICENSE file found in the top-level directory |
| 3 | // of this distribution and at http://opencv.org/license.html |
| 4 | |
| 5 | #ifndef OPENCV_CORE_PERSISTENCE_IMPL_HPP |
| 6 | #define OPENCV_CORE_PERSISTENCE_IMPL_HPP |
| 7 | |
| 8 | #include "persistence.hpp" |
| 9 | #include "persistence_base64_encoding.hpp" |
| 10 | #include <unordered_map> |
| 11 | #include <iterator> |
| 12 | |
| 13 | |
| 14 | namespace cv |
| 15 | { |
| 16 | |
| 17 | enum Base64State{ |
| 18 | Uncertain, |
| 19 | NotUse, |
| 20 | InUse, |
| 21 | }; |
| 22 | |
| 23 | class cv::FileStorage::Impl : public FileStorage_API |
| 24 | { |
| 25 | public: |
| 26 | void init(); |
| 27 | |
| 28 | Impl(FileStorage* _fs); |
| 29 | |
| 30 | virtual ~Impl(); |
| 31 | |
| 32 | void release(String* out=0); |
| 33 | |
| 34 | void analyze_file_name( const std::string& file_name, std::vector<std::string>& params ); |
| 35 | |
| 36 | bool open( const char* filename_or_buf, int _flags, const char* encoding ); |
| 37 | |
| 38 | void puts( const char* str ); |
| 39 | |
| 40 | char* getsFromFile( char* buf, int count ); |
| 41 | |
| 42 | char* gets( size_t maxCount ); |
| 43 | |
| 44 | char* gets(); |
| 45 | |
| 46 | bool eof(); |
| 47 | |
| 48 | void setEof(); |
| 49 | |
| 50 | void closeFile(); |
| 51 | |
| 52 | void rewind(); |
| 53 | |
| 54 | char* resizeWriteBuffer( char* ptr, int len ); |
| 55 | |
| 56 | char* flush(); |
| 57 | |
| 58 | void endWriteStruct(); |
| 59 | |
| 60 | void startWriteStruct_helper( const char* key, int struct_flags, |
| 61 | const char* type_name ); |
| 62 | |
| 63 | void startWriteStruct( const char* key, int struct_flags, |
| 64 | const char* type_name ); |
| 65 | |
| 66 | void ( const char* , bool ); |
| 67 | |
| 68 | void startNextStream(); |
| 69 | |
| 70 | void write( const String& key, int value ); |
| 71 | |
| 72 | void write( const String& key, int64_t value ); |
| 73 | |
| 74 | void write( const String& key, double value ); |
| 75 | |
| 76 | void write( const String& key, const String& value ); |
| 77 | |
| 78 | void writeRawData( const std::string& dt, const void* _data, size_t len ); |
| 79 | |
| 80 | void workaround(); |
| 81 | |
| 82 | void switch_to_Base64_state( FileStorage_API::Base64State new_state); |
| 83 | |
| 84 | void make_write_struct_delayed( const char* key, int struct_flags, const char* type_name ); |
| 85 | |
| 86 | void check_if_write_struct_is_delayed( bool change_type_to_base64 ); |
| 87 | |
| 88 | void writeRawDataBase64(const void* _data, size_t len, const char* dt ); |
| 89 | |
| 90 | String releaseAndGetString(); |
| 91 | |
| 92 | FileNode getFirstTopLevelNode() const; |
| 93 | |
| 94 | FileNode root(int streamIdx=0) const; |
| 95 | |
| 96 | FileNode operator[](const String& nodename) const; |
| 97 | |
| 98 | FileNode operator[](const char* /*nodename*/) const; |
| 99 | |
| 100 | int getFormat() const; |
| 101 | |
| 102 | char* bufferPtr() const; |
| 103 | char* bufferStart() const; |
| 104 | char* bufferEnd() const; |
| 105 | void setBufferPtr(char* ptr); |
| 106 | int wrapMargin() const; |
| 107 | |
| 108 | FStructData& getCurrentStruct(); |
| 109 | |
| 110 | void setNonEmpty(); |
| 111 | |
| 112 | void processSpecialDouble( char* buf, double* value, char** endptr ); |
| 113 | |
| 114 | double strtod( char* ptr, char** endptr ); |
| 115 | |
| 116 | void convertToCollection(int type, FileNode& node); |
| 117 | |
| 118 | // a) allocates new FileNode (for that just set blockIdx to the last block and ofs to freeSpaceOfs) or |
| 119 | // b) reallocates just created new node (blockIdx and ofs must be taken from FileNode). |
| 120 | // If there is no enough space in the current block (it should be the last block added so far), |
| 121 | // the last block is shrunk so that it ends immediately before the reallocated node. Then, |
| 122 | // a new block of sufficient size is allocated and the FileNode is placed in the beginning of it. |
| 123 | // The case (a) can be used to allocate the very first node by setting blockIdx == ofs == 0. |
| 124 | // In the case (b) the existing tag and the name are copied automatically. |
| 125 | uchar* reserveNodeSpace(FileNode& node, size_t sz); |
| 126 | |
| 127 | unsigned getStringOfs( const std::string& key ) const; |
| 128 | |
| 129 | FileNode addNode( FileNode& collection, const std::string& key, |
| 130 | int elem_type, const void* value, int len ); |
| 131 | |
| 132 | void finalizeCollection( FileNode& collection ); |
| 133 | |
| 134 | void normalizeNodeOfs(size_t& blockIdx, size_t& ofs) const; |
| 135 | |
| 136 | Base64State get_state_of_writing_base64(); |
| 137 | |
| 138 | int get_space(); |
| 139 | |
| 140 | class Base64Decoder |
| 141 | { |
| 142 | public: |
| 143 | Base64Decoder(); |
| 144 | void init(const Ptr<FileStorageParser>& _parser, char* _ptr, int _indent); |
| 145 | |
| 146 | bool readMore(int needed); |
| 147 | |
| 148 | uchar getUInt8(); |
| 149 | |
| 150 | ushort getUInt16(); |
| 151 | |
| 152 | int getInt32(); |
| 153 | |
| 154 | double getFloat64(); |
| 155 | |
| 156 | bool endOfStream() const; |
| 157 | char* getPtr() const; |
| 158 | protected: |
| 159 | |
| 160 | Ptr<FileStorageParser> parser_do_not_use_direct_dereference; |
| 161 | FileStorageParser& getParser() const |
| 162 | { |
| 163 | if (!parser_do_not_use_direct_dereference) |
| 164 | CV_Error(Error::StsNullPtr, "Parser is not available" ); |
| 165 | return *parser_do_not_use_direct_dereference; |
| 166 | } |
| 167 | char* ptr; |
| 168 | int indent; |
| 169 | std::vector<char> encoded; |
| 170 | std::vector<uchar> decoded; |
| 171 | size_t ofs; |
| 172 | size_t totalchars; |
| 173 | bool eos; |
| 174 | }; |
| 175 | |
| 176 | char* parseBase64(char* ptr, int indent, FileNode& collection); |
| 177 | |
| 178 | void parseError( const char* func_name, const std::string& err_msg, const char* source_file, int source_line ); |
| 179 | |
| 180 | const uchar* getNodePtr(size_t blockIdx, size_t ofs) const; |
| 181 | |
| 182 | std::string getName( size_t nameofs ) const; |
| 183 | |
| 184 | FileStorage* getFS(); |
| 185 | |
| 186 | FileStorage* fs_ext; |
| 187 | |
| 188 | std::string filename; |
| 189 | int flags; |
| 190 | bool empty_stream; |
| 191 | |
| 192 | FILE* file; |
| 193 | gzFile gzfile; |
| 194 | |
| 195 | bool is_opened; |
| 196 | bool dummy_eof; |
| 197 | bool write_mode; |
| 198 | bool mem_mode; |
| 199 | int fmt; |
| 200 | |
| 201 | State state; //!< current state of the FileStorage (used only for writing) |
| 202 | bool is_using_base64; |
| 203 | bool is_write_struct_delayed; |
| 204 | char* delayed_struct_key; |
| 205 | int delayed_struct_flags; |
| 206 | char* delayed_type_name; |
| 207 | FileStorage_API::Base64State state_of_writing_base64; |
| 208 | |
| 209 | int space, wrap_margin; |
| 210 | std::deque<FStructData> write_stack; |
| 211 | std::vector<char> buffer; |
| 212 | size_t bufofs; |
| 213 | |
| 214 | std::deque<char> outbuf; |
| 215 | |
| 216 | Ptr<FileStorageEmitter> emitter_do_not_use_direct_dereference; |
| 217 | FileStorageEmitter& getEmitter() |
| 218 | { |
| 219 | if (!emitter_do_not_use_direct_dereference) |
| 220 | CV_Error(Error::StsNullPtr, "Emitter is not available" ); |
| 221 | return *emitter_do_not_use_direct_dereference; |
| 222 | } |
| 223 | Ptr<FileStorageParser> parser_do_not_use_direct_dereference; |
| 224 | FileStorageParser& getParser() const |
| 225 | { |
| 226 | if (!parser_do_not_use_direct_dereference) |
| 227 | CV_Error(Error::StsNullPtr, "Parser is not available" ); |
| 228 | return *parser_do_not_use_direct_dereference; |
| 229 | } |
| 230 | Base64Decoder base64decoder; |
| 231 | base64::Base64Writer* base64_writer; |
| 232 | |
| 233 | std::vector<FileNode> roots; |
| 234 | std::vector<Ptr<std::vector<uchar> > > fs_data; |
| 235 | std::vector<uchar*> fs_data_ptrs; |
| 236 | std::vector<size_t> fs_data_blksz; |
| 237 | size_t freeSpaceOfs; |
| 238 | typedef std::unordered_map<std::string, unsigned> str_hash_t; |
| 239 | str_hash_t str_hash; |
| 240 | std::vector<char> str_hash_data; |
| 241 | |
| 242 | std::vector<char> strbufv; |
| 243 | char* strbuf; |
| 244 | size_t strbufsize; |
| 245 | size_t strbufpos; |
| 246 | int lineno; |
| 247 | }; |
| 248 | |
| 249 | } |
| 250 | |
| 251 | #endif |
| 252 | |