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 
6 #ifndef SRC_PERSISTENCE_HPP
7 #define SRC_PERSISTENCE_HPP
8 
9 #include "opencv2/core/types_c.h"
10 #include <deque>
11 #include <sstream>
12 #include <string>
13 #include <iterator>
14 
15 #define USE_ZLIB 1
16 #if USE_ZLIB
17 #  ifndef _LFS64_LARGEFILE
18 #    define _LFS64_LARGEFILE 0
19 #  endif
20 #  ifndef _FILE_OFFSET_BITS
21 #    define _FILE_OFFSET_BITS 0
22 #  endif
23 #  include <zlib.h>
24 #else
25 typedef void* gzFile;
26 #endif
27 
28 //=====================================================================================
29 
30 static const size_t PARSER_BASE64_BUFFER_SIZE = 1024U * 1024U / 8U;
31 
32 namespace base64 {
33 
34 enum
35 {
36     HEADER_SIZE         = 24,
37     ENCODED_HEADER_SIZE = 32
38 };
39 
40 } // base64::
41 
42 //=====================================================================================
43 
44 #define CV_FS_MAX_LEN 4096
45 #define CV_FS_MAX_FMT_PAIRS  128
46 
47 /****************************************************************************************\
48 *                            Common macros and type definitions                          *
49 \****************************************************************************************/
50 
51 #define cv_isprint(c)     ((uchar)(c) >= (uchar)' ')
52 #define cv_isprint_or_tab(c)  ((uchar)(c) >= (uchar)' ' || (c) == '\t')
53 
cv_isalnum(char c)54 inline bool cv_isalnum(char c)
55 {
56     return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
57 }
58 
cv_isalpha(char c)59 inline bool cv_isalpha(char c)
60 {
61     return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
62 }
63 
cv_isdigit(char c)64 inline bool cv_isdigit(char c)
65 {
66     return '0' <= c && c <= '9';
67 }
68 
cv_isspace(char c)69 inline bool cv_isspace(char c)
70 {
71     return (9 <= c && c <= 13) || c == ' ';
72 }
73 
cv_skip_BOM(char * ptr)74 inline char* cv_skip_BOM(char* ptr)
75 {
76     if((uchar)ptr[0] == 0xef && (uchar)ptr[1] == 0xbb && (uchar)ptr[2] == 0xbf) //UTF-8 BOM
77     {
78       return ptr + 3;
79     }
80     return ptr;
81 }
82 
83 namespace cv
84 {
85 namespace fs
86 {
87 int strcasecmp(const char* str1, const char* str2);
88 char* itoa( int _val, char* buffer, int /*radix*/ );
89 char* floatToString( char* buf, float value, bool halfprecision, bool explicitZero );
90 char* doubleToString( char* buf, double value, bool explicitZero );
91 
92 int calcStructSize( const char* dt, int initial_size );
93 int calcElemSize( const char* dt, int initial_size );
94 char* encodeFormat( int elem_type, char* dt );
95 int decodeFormat( const char* dt, int* fmt_pairs, int max_len );
96 int decodeSimpleFormat( const char* dt );
97 }
98 
99 
100 #ifdef CV_STATIC_ANALYSIS
101 #define CV_PARSE_ERROR_CPP(errmsg) do { (void)fs; abort(); } while (0)
102 #else
103 #define CV_PARSE_ERROR_CPP( errmsg ) \
104     fs->parseError( CV_Func, (errmsg), __FILE__, __LINE__ )
105 #endif
106 
107 
108 #define CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP() do { \
109     CV_DbgAssert(ptr); \
110     if((ptr)[0] == 0 && (ptr) == fs->bufferEnd() - 1) CV_PARSE_ERROR_CPP("OpenCV persistence doesn't support very long lines"); \
111 } while (0)
112 
113 
114 class FileStorageParser;
115 class FileStorageEmitter;
116 
117 struct FStructData
118 {
FStructDatacv::FStructData119     FStructData() { indent = flags = 0; }
FStructDatacv::FStructData120     FStructData( const std::string& _struct_tag,
121                  int _struct_flags, int _struct_indent )
122     {
123         tag = _struct_tag;
124         flags = _struct_flags;
125         indent = _struct_indent;
126     }
127 
128     std::string tag;
129     int flags;
130     int indent;
131 };
132 
133 class FileStorage_API
134 {
135 public:
136     virtual ~FileStorage_API();
137     virtual FileStorage* getFS() = 0;
138 
139     virtual void puts( const char* str ) = 0;
140     virtual char* gets() = 0;
141     virtual bool eof() = 0;
142     virtual void setEof() = 0;
143     virtual void closeFile() = 0;
144     virtual void rewind() = 0;
145     virtual char* resizeWriteBuffer( char* ptr, int len ) = 0;
146     virtual char* bufferPtr() const = 0;
147     virtual char* bufferStart() const = 0;
148     virtual char* bufferEnd() const = 0;
149     virtual void setBufferPtr(char* ptr) = 0;
150     virtual char* flush() = 0;
151     virtual void setNonEmpty() = 0;
152     virtual int wrapMargin() const = 0;
153 
154     virtual FStructData& getCurrentStruct() = 0;
155 
156     virtual void convertToCollection( int type, FileNode& node ) = 0;
157     virtual FileNode addNode( FileNode& collection, const std::string& key,
158                                int type, const void* value=0, int len=-1 ) = 0;
159     virtual void finalizeCollection( FileNode& collection ) = 0;
160     virtual double strtod(char* ptr, char** endptr) = 0;
161 
162     virtual char* parseBase64(char* ptr, int indent, FileNode& collection) = 0;
163     CV_NORETURN
164     virtual void parseError(const char* funcname, const std::string& msg,
165                             const char* filename, int lineno) = 0;
166 };
167 
168 class FileStorageEmitter
169 {
170 public:
~FileStorageEmitter()171     virtual ~FileStorageEmitter() {}
172 
173     virtual FStructData startWriteStruct( const FStructData& parent, const char* key,
174                                           int struct_flags, const char* type_name=0 ) = 0;
175     virtual void endWriteStruct(const FStructData& current_struct) = 0;
176     virtual void write(const char* key, int value) = 0;
177     virtual void write(const char* key, double value) = 0;
178     virtual void write(const char* key, const char* value, bool quote) = 0;
179     virtual void writeScalar(const char* key, const char* value) = 0;
180     virtual void writeComment(const char* comment, bool eol_comment) = 0;
181     virtual void startNextStream() = 0;
182 };
183 
184 class FileStorageParser
185 {
186 public:
~FileStorageParser()187     virtual ~FileStorageParser() {}
188     virtual bool parse(char* ptr) = 0;
189     virtual bool getBase64Row(char* ptr, int indent, char* &beg, char* &end) = 0;
190 };
191 
192 Ptr<FileStorageEmitter> createXMLEmitter(FileStorage_API* fs);
193 Ptr<FileStorageEmitter> createYAMLEmitter(FileStorage_API* fs);
194 Ptr<FileStorageEmitter> createJSONEmitter(FileStorage_API* fs);
195 
196 Ptr<FileStorageParser> createXMLParser(FileStorage_API* fs);
197 Ptr<FileStorageParser> createYAMLParser(FileStorage_API* fs);
198 Ptr<FileStorageParser> createJSONParser(FileStorage_API* fs);
199 
200 }
201 
202 #endif // SRC_PERSISTENCE_HPP
203