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, double value ); |
73 | |
74 | void write( const String& key, const String& value ); |
75 | |
76 | void writeRawData( const std::string& dt, const void* _data, size_t len ); |
77 | |
78 | void workaround(); |
79 | |
80 | void switch_to_Base64_state( FileStorage_API::Base64State new_state); |
81 | |
82 | void make_write_struct_delayed( const char* key, int struct_flags, const char* type_name ); |
83 | |
84 | void check_if_write_struct_is_delayed( bool change_type_to_base64 ); |
85 | |
86 | void writeRawDataBase64(const void* _data, size_t len, const char* dt ); |
87 | |
88 | String releaseAndGetString(); |
89 | |
90 | FileNode getFirstTopLevelNode() const; |
91 | |
92 | FileNode root(int streamIdx=0) const; |
93 | |
94 | FileNode operator[](const String& nodename) const; |
95 | |
96 | FileNode operator[](const char* /*nodename*/) const; |
97 | |
98 | int getFormat() const; |
99 | |
100 | char* bufferPtr() const; |
101 | char* bufferStart() const; |
102 | char* bufferEnd() const; |
103 | void setBufferPtr(char* ptr); |
104 | int wrapMargin() const; |
105 | |
106 | FStructData& getCurrentStruct(); |
107 | |
108 | void setNonEmpty(); |
109 | |
110 | void processSpecialDouble( char* buf, double* value, char** endptr ); |
111 | |
112 | double strtod( char* ptr, char** endptr ); |
113 | |
114 | void convertToCollection(int type, FileNode& node); |
115 | |
116 | // a) allocates new FileNode (for that just set blockIdx to the last block and ofs to freeSpaceOfs) or |
117 | // b) reallocates just created new node (blockIdx and ofs must be taken from FileNode). |
118 | // If there is no enough space in the current block (it should be the last block added so far), |
119 | // the last block is shrunk so that it ends immediately before the reallocated node. Then, |
120 | // a new block of sufficient size is allocated and the FileNode is placed in the beginning of it. |
121 | // The case (a) can be used to allocate the very first node by setting blockIdx == ofs == 0. |
122 | // In the case (b) the existing tag and the name are copied automatically. |
123 | uchar* reserveNodeSpace(FileNode& node, size_t sz); |
124 | |
125 | unsigned getStringOfs( const std::string& key ) const; |
126 | |
127 | FileNode addNode( FileNode& collection, const std::string& key, |
128 | int elem_type, const void* value, int len ); |
129 | |
130 | void finalizeCollection( FileNode& collection ); |
131 | |
132 | void normalizeNodeOfs(size_t& blockIdx, size_t& ofs) const; |
133 | |
134 | Base64State get_state_of_writing_base64(); |
135 | |
136 | int get_space(); |
137 | |
138 | class Base64Decoder |
139 | { |
140 | public: |
141 | Base64Decoder(); |
142 | void init(const Ptr<FileStorageParser>& _parser, char* _ptr, int _indent); |
143 | |
144 | bool readMore(int needed); |
145 | |
146 | uchar getUInt8(); |
147 | |
148 | ushort getUInt16(); |
149 | |
150 | int getInt32(); |
151 | |
152 | double getFloat64(); |
153 | |
154 | bool endOfStream() const; |
155 | char* getPtr() const; |
156 | protected: |
157 | |
158 | Ptr<FileStorageParser> parser_do_not_use_direct_dereference; |
159 | FileStorageParser& getParser() const |
160 | { |
161 | if (!parser_do_not_use_direct_dereference) |
162 | CV_Error(Error::StsNullPtr, "Parser is not available" ); |
163 | return *parser_do_not_use_direct_dereference; |
164 | } |
165 | char* ptr; |
166 | int indent; |
167 | std::vector<char> encoded; |
168 | std::vector<uchar> decoded; |
169 | size_t ofs; |
170 | size_t totalchars; |
171 | bool eos; |
172 | }; |
173 | |
174 | char* parseBase64(char* ptr, int indent, FileNode& collection); |
175 | |
176 | void parseError( const char* func_name, const std::string& err_msg, const char* source_file, int source_line ); |
177 | |
178 | const uchar* getNodePtr(size_t blockIdx, size_t ofs) const; |
179 | |
180 | std::string getName( size_t nameofs ) const; |
181 | |
182 | FileStorage* getFS(); |
183 | |
184 | FileStorage* fs_ext; |
185 | |
186 | std::string filename; |
187 | int flags; |
188 | bool empty_stream; |
189 | |
190 | FILE* file; |
191 | gzFile gzfile; |
192 | |
193 | bool is_opened; |
194 | bool dummy_eof; |
195 | bool write_mode; |
196 | bool mem_mode; |
197 | int fmt; |
198 | |
199 | State state; //!< current state of the FileStorage (used only for writing) |
200 | bool is_using_base64; |
201 | bool is_write_struct_delayed; |
202 | char* delayed_struct_key; |
203 | int delayed_struct_flags; |
204 | char* delayed_type_name; |
205 | FileStorage_API::Base64State state_of_writing_base64; |
206 | |
207 | int space, wrap_margin; |
208 | std::deque<FStructData> write_stack; |
209 | std::vector<char> buffer; |
210 | size_t bufofs; |
211 | |
212 | std::deque<char> outbuf; |
213 | |
214 | Ptr<FileStorageEmitter> emitter_do_not_use_direct_dereference; |
215 | FileStorageEmitter& getEmitter() |
216 | { |
217 | if (!emitter_do_not_use_direct_dereference) |
218 | CV_Error(Error::StsNullPtr, "Emitter is not available" ); |
219 | return *emitter_do_not_use_direct_dereference; |
220 | } |
221 | Ptr<FileStorageParser> parser_do_not_use_direct_dereference; |
222 | FileStorageParser& getParser() const |
223 | { |
224 | if (!parser_do_not_use_direct_dereference) |
225 | CV_Error(Error::StsNullPtr, "Parser is not available" ); |
226 | return *parser_do_not_use_direct_dereference; |
227 | } |
228 | Base64Decoder base64decoder; |
229 | base64::Base64Writer* base64_writer; |
230 | |
231 | std::vector<FileNode> roots; |
232 | std::vector<Ptr<std::vector<uchar> > > fs_data; |
233 | std::vector<uchar*> fs_data_ptrs; |
234 | std::vector<size_t> fs_data_blksz; |
235 | size_t freeSpaceOfs; |
236 | typedef std::unordered_map<std::string, unsigned> str_hash_t; |
237 | str_hash_t str_hash; |
238 | std::vector<char> str_hash_data; |
239 | |
240 | std::vector<char> strbufv; |
241 | char* strbuf; |
242 | size_t strbufsize; |
243 | size_t strbufpos; |
244 | int lineno; |
245 | }; |
246 | |
247 | } |
248 | |
249 | #endif |
250 | |