Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
persistence.hpp
00001 /*M/////////////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 00004 // 00005 // By downloading, copying, installing or using the software you agree to this license. 00006 // If you do not agree to this license, do not download, install, 00007 // copy or use the software. 00008 // 00009 // 00010 // License Agreement 00011 // For Open Source Computer Vision Library 00012 // 00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved. 00015 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 00016 // Third party copyrights are property of their respective owners. 00017 // 00018 // Redistribution and use in source and binary forms, with or without modification, 00019 // are permitted provided that the following conditions are met: 00020 // 00021 // * Redistribution's of source code must retain the above copyright notice, 00022 // this list of conditions and the following disclaimer. 00023 // 00024 // * Redistribution's in binary form must reproduce the above copyright notice, 00025 // this list of conditions and the following disclaimer in the documentation 00026 // and/or other materials provided with the distribution. 00027 // 00028 // * The name of the copyright holders may not be used to endorse or promote products 00029 // derived from this software without specific prior written permission. 00030 // 00031 // This software is provided by the copyright holders and contributors "as is" and 00032 // any express or implied warranties, including, but not limited to, the implied 00033 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00034 // In no event shall the Intel Corporation or contributors be liable for any direct, 00035 // indirect, incidental, special, exemplary, or consequential damages 00036 // (including, but not limited to, procurement of substitute goods or services; 00037 // loss of use, data, or profits; or business interruption) however caused 00038 // and on any theory of liability, whether in contract, strict liability, 00039 // or tort (including negligence or otherwise) arising in any way out of 00040 // the use of this software, even if advised of the possibility of such damage. 00041 // 00042 //M*/ 00043 00044 #ifndef __OPENCV_CORE_PERSISTENCE_HPP__ 00045 #define __OPENCV_CORE_PERSISTENCE_HPP__ 00046 00047 #ifndef __cplusplus 00048 # error persistence.hpp header must be compiled as C++ 00049 #endif 00050 00051 //! @addtogroup core_c 00052 //! @{ 00053 00054 /** @brief "black box" representation of the file storage associated with a file on disk. 00055 00056 Several functions that are described below take CvFileStorage\* as inputs and allow the user to 00057 save or to load hierarchical collections that consist of scalar values, standard CXCore objects 00058 (such as matrices, sequences, graphs), and user-defined objects. 00059 00060 OpenCV can read and write data in XML (<http://www.w3c.org/XML>) or YAML (<http://www.yaml.org>) 00061 formats. Below is an example of 3x3 floating-point identity matrix A, stored in XML and YAML files 00062 using CXCore functions: 00063 XML: 00064 @code{.xml} 00065 <?xml version="1.0"> 00066 <opencv_storage> 00067 <A type_id="opencv-matrix"> 00068 <rows>3</rows> 00069 <cols>3</cols> 00070 <dt>f</dt> 00071 <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data> 00072 </A> 00073 </opencv_storage> 00074 @endcode 00075 YAML: 00076 @code{.yaml} 00077 %YAML:1.0 00078 A: !!opencv-matrix 00079 rows: 3 00080 cols: 3 00081 dt: f 00082 data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.] 00083 @endcode 00084 As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses 00085 indentation for that purpose (similar to the Python programming language). 00086 00087 The same functions can read and write data in both formats; the particular format is determined by 00088 the extension of the opened file, ".xml" for XML files and ".yml" or ".yaml" for YAML. 00089 */ 00090 typedef struct CvFileStorage CvFileStorage; 00091 typedef struct CvFileNode CvFileNode; 00092 00093 //! @} core_c 00094 00095 #include "opencv2/core/types.hpp" 00096 #include "opencv2/core/mat.hpp" 00097 00098 namespace cv { 00099 00100 /** @addtogroup core_xml 00101 00102 XML/YAML file storages. {#xml_storage} 00103 ======================= 00104 Writing to a file storage. 00105 -------------------------- 00106 You can store and then restore various OpenCV data structures to/from XML (<http://www.w3c.org/XML>) 00107 or YAML (<http://www.yaml.org>) formats. Also, it is possible store and load arbitrarily complex 00108 data structures, which include OpenCV data structures, as well as primitive data types (integer and 00109 floating-point numbers and text strings) as their elements. 00110 00111 Use the following procedure to write something to XML or YAML: 00112 -# Create new FileStorage and open it for writing. It can be done with a single call to 00113 FileStorage::FileStorage constructor that takes a filename, or you can use the default constructor 00114 and then call FileStorage::open. Format of the file (XML or YAML) is determined from the filename 00115 extension (".xml" and ".yml"/".yaml", respectively) 00116 -# Write all the data you want using the streaming operator `<<`, just like in the case of STL 00117 streams. 00118 -# Close the file using FileStorage::release. FileStorage destructor also closes the file. 00119 00120 Here is an example: 00121 @code 00122 #include "opencv2/opencv.hpp" 00123 #include <time.h> 00124 00125 using namespace cv; 00126 00127 int main(int, char** argv) 00128 { 00129 FileStorage fs("test.yml", FileStorage::WRITE); 00130 00131 fs << "frameCount" << 5; 00132 time_t rawtime; time(&rawtime); 00133 fs << "calibrationDate" << asctime(localtime(&rawtime)); 00134 Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); 00135 Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0); 00136 fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs; 00137 fs << "features" << "["; 00138 for( int i = 0; i < 3; i++ ) 00139 { 00140 int x = rand() % 640; 00141 int y = rand() % 480; 00142 uchar lbp = rand() % 256; 00143 00144 fs << "{:" << "x" << x << "y" << y << "lbp" << "[:"; 00145 for( int j = 0; j < 8; j++ ) 00146 fs << ((lbp >> j) & 1); 00147 fs << "]" << "}"; 00148 } 00149 fs << "]"; 00150 fs.release(); 00151 return 0; 00152 } 00153 @endcode 00154 The sample above stores to XML and integer, text string (calibration date), 2 matrices, and a custom 00155 structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here 00156 is output of the sample: 00157 @code{.yaml} 00158 %YAML:1.0 00159 frameCount: 5 00160 calibrationDate: "Fri Jun 17 14:09:29 2011\n" 00161 cameraMatrix: !!opencv-matrix 00162 rows: 3 00163 cols: 3 00164 dt: d 00165 data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ] 00166 distCoeffs: !!opencv-matrix 00167 rows: 5 00168 cols: 1 00169 dt: d 00170 data: [ 1.0000000000000001e-01, 1.0000000000000000e-02, 00171 -1.0000000000000000e-03, 0., 0. ] 00172 features: 00173 - { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] } 00174 - { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] } 00175 - { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] } 00176 @endcode 00177 00178 As an exercise, you can replace ".yml" with ".xml" in the sample above and see, how the 00179 corresponding XML file will look like. 00180 00181 Several things can be noted by looking at the sample code and the output: 00182 00183 - The produced YAML (and XML) consists of heterogeneous collections that can be nested. There are 2 00184 types of collections: named collections (mappings) and unnamed collections (sequences). In mappings 00185 each element has a name and is accessed by name. This is similar to structures and std::map in 00186 C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by 00187 indices. This is similar to arrays and std::vector in C/C++ and lists, tuples in Python. 00188 "Heterogeneous" means that elements of each single collection can have different types. 00189 00190 Top-level collection in YAML/XML is a mapping. Each matrix is stored as a mapping, and the matrix 00191 elements are stored as a sequence. Then, there is a sequence of features, where each feature is 00192 represented a mapping, and lbp value in a nested sequence. 00193 00194 - When you write to a mapping (a structure), you write element name followed by its value. When you 00195 write to a sequence, you simply write the elements one by one. OpenCV data structures (such as 00196 cv::Mat) are written in absolutely the same way as simple C data structures - using `<<` 00197 operator. 00198 00199 - To write a mapping, you first write the special string `{` to the storage, then write the 00200 elements as pairs (`fs << <element_name> << <element_value>`) and then write the closing 00201 `}`. 00202 00203 - To write a sequence, you first write the special string `[`, then write the elements, then 00204 write the closing `]`. 00205 00206 - In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline 00207 form. In the sample above matrix elements, as well as each feature, including its lbp value, is 00208 stored in such inline form. To store a mapping/sequence in a compact form, put `:` after the 00209 opening character, e.g. use `{:` instead of `{` and `[:` instead of `[`. When the 00210 data is written to XML, those extra `:` are ignored. 00211 00212 Reading data from a file storage. 00213 --------------------------------- 00214 To read the previously written XML or YAML file, do the following: 00215 -# Open the file storage using FileStorage::FileStorage constructor or FileStorage::open method. 00216 In the current implementation the whole file is parsed and the whole representation of file 00217 storage is built in memory as a hierarchy of file nodes (see FileNode) 00218 00219 -# Read the data you are interested in. Use FileStorage::operator [], FileNode::operator [] 00220 and/or FileNodeIterator. 00221 00222 -# Close the storage using FileStorage::release. 00223 00224 Here is how to read the file created by the code sample above: 00225 @code 00226 FileStorage fs2("test.yml", FileStorage::READ); 00227 00228 // first method: use (type) operator on FileNode. 00229 int frameCount = (int)fs2["frameCount"]; 00230 00231 String date; 00232 // second method: use FileNode::operator >> 00233 fs2["calibrationDate"] >> date; 00234 00235 Mat cameraMatrix2, distCoeffs2; 00236 fs2["cameraMatrix"] >> cameraMatrix2; 00237 fs2["distCoeffs"] >> distCoeffs2; 00238 00239 cout << "frameCount: " << frameCount << endl 00240 << "calibration date: " << date << endl 00241 << "camera matrix: " << cameraMatrix2 << endl 00242 << "distortion coeffs: " << distCoeffs2 << endl; 00243 00244 FileNode features = fs2["features"]; 00245 FileNodeIterator it = features.begin(), it_end = features.end(); 00246 int idx = 0; 00247 std::vector<uchar> lbpval; 00248 00249 // iterate through a sequence using FileNodeIterator 00250 for( ; it != it_end; ++it, idx++ ) 00251 { 00252 cout << "feature #" << idx << ": "; 00253 cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: ("; 00254 // you can also easily read numerical arrays using FileNode >> std::vector operator. 00255 (*it)["lbp"] >> lbpval; 00256 for( int i = 0; i < (int)lbpval.size(); i++ ) 00257 cout << " " << (int)lbpval[i]; 00258 cout << ")" << endl; 00259 } 00260 fs2.release(); 00261 @endcode 00262 00263 Format specification {#format_spec} 00264 -------------------- 00265 `([count]{u|c|w|s|i|f|d})`... where the characters correspond to fundamental C++ types: 00266 - `u` 8-bit unsigned number 00267 - `c` 8-bit signed number 00268 - `w` 16-bit unsigned number 00269 - `s` 16-bit signed number 00270 - `i` 32-bit signed number 00271 - `f` single precision floating-point number 00272 - `d` double precision floating-point number 00273 - `r` pointer, 32 lower bits of which are written as a signed integer. The type can be used to 00274 store structures with links between the elements. 00275 00276 `count` is the optional counter of values of a given type. For example, `2if` means that each array 00277 element is a structure of 2 integers, followed by a single-precision floating-point number. The 00278 equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u` 00279 means that the array consists of bytes, and `2d` means the array consists of pairs of doubles. 00280 00281 @see @ref filestorage.cpp 00282 */ 00283 00284 //! @{ 00285 00286 /** @example filestorage.cpp 00287 A complete example using the FileStorage interface 00288 */ 00289 00290 ////////////////////////// XML & YAML I/O ////////////////////////// 00291 00292 class CV_EXPORTS FileNode; 00293 class CV_EXPORTS FileNodeIterator; 00294 00295 /** @brief XML/YAML file storage class that encapsulates all the information necessary for writing or reading 00296 data to/from a file. 00297 */ 00298 class CV_EXPORTS_W FileStorage 00299 { 00300 public: 00301 //! file storage mode 00302 enum Mode 00303 { 00304 READ = 0, //!< value, open the file for reading 00305 WRITE = 1, //!< value, open the file for writing 00306 APPEND = 2, //!< value, open the file for appending 00307 MEMORY = 4, //!< flag, read data from source or write data to the internal buffer (which is 00308 //!< returned by FileStorage::release) 00309 FORMAT_MASK = (7<<3), //!< mask for format flags 00310 FORMAT_AUTO = 0, //!< flag, auto format 00311 FORMAT_XML = (1<<3), //!< flag, XML format 00312 FORMAT_YAML = (2<<3) //!< flag, YAML format 00313 }; 00314 enum 00315 { 00316 UNDEFINED = 0, 00317 VALUE_EXPECTED = 1, 00318 NAME_EXPECTED = 2, 00319 INSIDE_MAP = 4 00320 }; 00321 00322 /** @brief The constructors. 00323 00324 The full constructor opens the file. Alternatively you can use the default constructor and then 00325 call FileStorage::open. 00326 */ 00327 CV_WRAP FileStorage(); 00328 00329 /** @overload 00330 @param source Name of the file to open or the text string to read the data from. Extension of the 00331 file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). Also you can append .gz 00332 to work with compressed files, for example myHugeMatrix.xml.gz. If both FileStorage::WRITE and 00333 FileStorage::MEMORY flags are specified, source is used just to specify the output file format (e.g. 00334 mydata.xml, .yml etc.). 00335 @param flags Mode of operation. See FileStorage::Mode 00336 @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and 00337 you should use 8-bit encoding instead of it. 00338 */ 00339 CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String()); 00340 00341 /** @overload */ 00342 FileStorage(CvFileStorage* fs, bool owning=true); 00343 00344 //! the destructor. calls release() 00345 virtual ~FileStorage(); 00346 00347 /** @brief Opens a file. 00348 00349 See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release 00350 before opening the file. 00351 @param filename Name of the file to open or the text string to read the data from. 00352 Extension of the file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). 00353 Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both 00354 FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify 00355 the output file format (e.g. mydata.xml, .yml etc.). 00356 @param flags Mode of operation. One of FileStorage::Mode 00357 @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and 00358 you should use 8-bit encoding instead of it. 00359 */ 00360 CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String()); 00361 00362 /** @brief Checks whether the file is opened. 00363 00364 @returns true if the object is associated with the current file and false otherwise. It is a 00365 good practice to call this method after you tried to open a file. 00366 */ 00367 CV_WRAP virtual bool isOpened() const; 00368 00369 /** @brief Closes the file and releases all the memory buffers. 00370 00371 Call this method after all I/O operations with the storage are finished. 00372 */ 00373 CV_WRAP virtual void release(); 00374 00375 /** @brief Closes the file and releases all the memory buffers. 00376 00377 Call this method after all I/O operations with the storage are finished. If the storage was 00378 opened for writing data and FileStorage::WRITE was specified 00379 */ 00380 CV_WRAP virtual String releaseAndGetString(); 00381 00382 /** @brief Returns the first element of the top-level mapping. 00383 @returns The first element of the top-level mapping. 00384 */ 00385 CV_WRAP FileNode getFirstTopLevelNode() const; 00386 00387 /** @brief Returns the top-level mapping 00388 @param streamidx Zero-based index of the stream. In most cases there is only one stream in the file. 00389 However, YAML supports multiple streams and so there can be several. 00390 @returns The top-level mapping. 00391 */ 00392 CV_WRAP FileNode root(int streamidx=0) const; 00393 00394 /** @brief Returns the specified element of the top-level mapping. 00395 @param nodename Name of the file node. 00396 @returns Node with the given name. 00397 */ 00398 FileNode operator[](const String& nodename) const; 00399 00400 /** @overload */ 00401 CV_WRAP FileNode operator[](const char* nodename) const; 00402 00403 /** @brief Returns the obsolete C FileStorage structure. 00404 @returns Pointer to the underlying C FileStorage structure 00405 */ 00406 CvFileStorage* operator *() { return fs.get(); } 00407 00408 /** @overload */ 00409 const CvFileStorage* operator *() const { return fs.get(); } 00410 00411 /** @brief Writes multiple numbers. 00412 00413 Writes one or more numbers of the specified format to the currently written structure. Usually it is 00414 more convenient to use operator `<<` instead of this method. 00415 @param fmt Specification of each array element, see @ref format_spec "format specification" 00416 @param vec Pointer to the written array. 00417 @param len Number of the uchar elements to write. 00418 */ 00419 void writeRaw( const String& fmt, const uchar* vec, size_t len ); 00420 00421 /** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq). 00422 @param name Name of the written object. 00423 @param obj Pointer to the object. 00424 @see ocvWrite for details. 00425 */ 00426 void writeObj( const String& name, const void* obj ); 00427 00428 /** @brief Returns the normalized object name for the specified name of a file. 00429 @param filename Name of a file 00430 @returns The normalized object name. 00431 */ 00432 static String getDefaultObjectName(const String& filename); 00433 00434 Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure 00435 String elname; //!< the currently written element 00436 std::vector<char> structs; //!< the stack of written structures 00437 int state; //!< the writer state 00438 }; 00439 00440 template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const; 00441 00442 /** @brief File Storage Node class. 00443 00444 The node is used to store each and every element of the file storage opened for reading. When 00445 XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of 00446 nodes. Each node can be a “leaf” that is contain a single number or a string, or be a collection of 00447 other nodes. There can be named collections (mappings) where each element has a name and it is 00448 accessed by a name, and ordered collections (sequences) where elements do not have names but rather 00449 accessed by index. Type of the file node can be determined using FileNode::type method. 00450 00451 Note that file nodes are only used for navigating file storages opened for reading. When a file 00452 storage is opened for writing, no data is stored in memory after it is written. 00453 */ 00454 class CV_EXPORTS_W_SIMPLE FileNode 00455 { 00456 public: 00457 //! type of the file storage node 00458 enum Type 00459 { 00460 NONE = 0, //!< empty node 00461 INT = 1, //!< an integer 00462 REAL = 2, //!< floating-point number 00463 FLOAT = REAL, //!< synonym or REAL 00464 STR = 3, //!< text string in UTF-8 encoding 00465 STRING = STR, //!< synonym for STR 00466 REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others 00467 SEQ = 5, //!< sequence 00468 MAP = 6, //!< mapping 00469 TYPE_MASK = 7, 00470 FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer 00471 USER = 16, //!< a registered object (e.g. a matrix) 00472 EMPTY = 32, //!< empty structure (sequence or mapping) 00473 NAMED = 64 //!< the node has a name (i.e. it is element of a mapping) 00474 }; 00475 /** @brief The constructors. 00476 00477 These constructors are used to create a default file node, construct it from obsolete structures or 00478 from the another file node. 00479 */ 00480 CV_WRAP FileNode(); 00481 00482 /** @overload 00483 @param fs Pointer to the obsolete file storage structure. 00484 @param node File node to be used as initialization for the created file node. 00485 */ 00486 FileNode(const CvFileStorage* fs, const CvFileNode* node); 00487 00488 /** @overload 00489 @param node File node to be used as initialization for the created file node. 00490 */ 00491 FileNode(const FileNode& node); 00492 00493 /** @brief Returns element of a mapping node or a sequence node. 00494 @param nodename Name of an element in the mapping node. 00495 @returns Returns the element with the given identifier. 00496 */ 00497 FileNode operator[](const String& nodename) const; 00498 00499 /** @overload 00500 @param nodename Name of an element in the mapping node. 00501 */ 00502 CV_WRAP FileNode operator[](const char* nodename) const; 00503 00504 /** @overload 00505 @param i Index of an element in the sequence node. 00506 */ 00507 CV_WRAP FileNode operator[](int i) const; 00508 00509 /** @brief Returns type of the node. 00510 @returns Type of the node. See FileNode::Type 00511 */ 00512 CV_WRAP int type() const; 00513 00514 //! returns true if the node is empty 00515 CV_WRAP bool empty() const; 00516 //! returns true if the node is a "none" object 00517 CV_WRAP bool isNone() const; 00518 //! returns true if the node is a sequence 00519 CV_WRAP bool isSeq() const; 00520 //! returns true if the node is a mapping 00521 CV_WRAP bool isMap() const; 00522 //! returns true if the node is an integer 00523 CV_WRAP bool isInt() const; 00524 //! returns true if the node is a floating-point number 00525 CV_WRAP bool isReal() const; 00526 //! returns true if the node is a text string 00527 CV_WRAP bool isString() const; 00528 //! returns true if the node has a name 00529 CV_WRAP bool isNamed() const; 00530 //! returns the node name or an empty string if the node is nameless 00531 CV_WRAP String name() const; 00532 //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise. 00533 CV_WRAP size_t size() const; 00534 //! returns the node content as an integer. If the node stores floating-point number, it is rounded. 00535 operator int() const; 00536 //! returns the node content as float 00537 operator float() const; 00538 //! returns the node content as double 00539 operator double() const; 00540 //! returns the node content as text string 00541 operator String() const; 00542 #ifndef OPENCV_NOSTL 00543 operator std::string() const; 00544 #endif 00545 00546 //! returns pointer to the underlying file node 00547 CvFileNode* operator *(); 00548 //! returns pointer to the underlying file node 00549 const CvFileNode* operator* () const; 00550 00551 //! returns iterator pointing to the first node element 00552 FileNodeIterator begin() const; 00553 //! returns iterator pointing to the element following the last node element 00554 FileNodeIterator end() const; 00555 00556 /** @brief Reads node elements to the buffer with the specified format. 00557 00558 Usually it is more convenient to use operator `>>` instead of this method. 00559 @param fmt Specification of each array element. See @ref format_spec "format specification" 00560 @param vec Pointer to the destination array. 00561 @param len Number of elements to read. If it is greater than number of remaining elements then all 00562 of them will be read. 00563 */ 00564 void readRaw( const String& fmt, uchar* vec, size_t len ) const; 00565 00566 //! reads the registered object and returns pointer to it 00567 void* readObj() const; 00568 00569 // do not use wrapper pointer classes for better efficiency 00570 const CvFileStorage* fs; 00571 const CvFileNode* node; 00572 }; 00573 00574 00575 /** @brief used to iterate through sequences and mappings. 00576 00577 A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a 00578 sequence, stored in node. See the data reading sample in the beginning of the section. 00579 */ 00580 class CV_EXPORTS FileNodeIterator 00581 { 00582 public: 00583 /** @brief The constructors. 00584 00585 These constructors are used to create a default iterator, set it to specific element in a file node 00586 or construct it from another iterator. 00587 */ 00588 FileNodeIterator(); 00589 00590 /** @overload 00591 @param fs File storage for the iterator. 00592 @param node File node for the iterator. 00593 @param ofs Index of the element in the node. The created iterator will point to this element. 00594 */ 00595 FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0); 00596 00597 /** @overload 00598 @param it Iterator to be used as initialization for the created iterator. 00599 */ 00600 FileNodeIterator(const FileNodeIterator& it); 00601 00602 //! returns the currently observed element 00603 FileNode operator *() const; 00604 //! accesses the currently observed element methods 00605 FileNode operator ->() const; 00606 00607 //! moves iterator to the next node 00608 FileNodeIterator& operator ++ (); 00609 //! moves iterator to the next node 00610 FileNodeIterator operator ++ (int); 00611 //! moves iterator to the previous node 00612 FileNodeIterator& operator -- (); 00613 //! moves iterator to the previous node 00614 FileNodeIterator operator -- (int); 00615 //! moves iterator forward by the specified offset (possibly negative) 00616 FileNodeIterator& operator += (int ofs); 00617 //! moves iterator backward by the specified offset (possibly negative) 00618 FileNodeIterator& operator -= (int ofs); 00619 00620 /** @brief Reads node elements to the buffer with the specified format. 00621 00622 Usually it is more convenient to use operator `>>` instead of this method. 00623 @param fmt Specification of each array element. See @ref format_spec "format specification" 00624 @param vec Pointer to the destination array. 00625 @param maxCount Number of elements to read. If it is greater than number of remaining elements then 00626 all of them will be read. 00627 */ 00628 FileNodeIterator& readRaw( const String& fmt, uchar* vec, 00629 size_t maxCount=(size_t)INT_MAX ); 00630 00631 struct SeqReader 00632 { 00633 int header_size; 00634 void* seq; /* sequence, beign read; CvSeq */ 00635 void* block; /* current block; CvSeqBlock */ 00636 schar* ptr; /* pointer to element be read next */ 00637 schar* block_min; /* pointer to the beginning of block */ 00638 schar* block_max; /* pointer to the end of block */ 00639 int delta_index;/* = seq->first->start_index */ 00640 schar* prev_elem; /* pointer to previous element */ 00641 }; 00642 00643 const CvFileStorage* fs; 00644 const CvFileNode* container; 00645 SeqReader reader; 00646 size_t remaining; 00647 }; 00648 00649 //! @} core_xml 00650 00651 /////////////////// XML & YAML I/O implementation ////////////////// 00652 00653 //! @relates cv::FileStorage 00654 //! @{ 00655 00656 CV_EXPORTS void write( FileStorage& fs, const String& name, int value ); 00657 CV_EXPORTS void write( FileStorage& fs, const String& name, float value ); 00658 CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); 00659 CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value ); 00660 CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value ); 00661 CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); 00662 CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& value); 00663 CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<DMatch>& value); 00664 00665 CV_EXPORTS void writeScalar( FileStorage& fs, int value ); 00666 CV_EXPORTS void writeScalar( FileStorage& fs, float value ); 00667 CV_EXPORTS void writeScalar( FileStorage& fs, double value ); 00668 CV_EXPORTS void writeScalar( FileStorage& fs, const String& value ); 00669 00670 //! @} 00671 00672 //! @relates cv::FileNode 00673 //! @{ 00674 00675 CV_EXPORTS void read(const FileNode& node, int& value, int default_value); 00676 CV_EXPORTS void read(const FileNode& node, float& value, float default_value); 00677 CV_EXPORTS void read(const FileNode& node, double& value, double default_value); 00678 CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value); 00679 CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); 00680 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() ); 00681 CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints); 00682 CV_EXPORTS void read(const FileNode& node, std::vector<DMatch>& matches); 00683 00684 template<typename _Tp> static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) 00685 { 00686 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00687 value = temp.size() != 2 ? default_value : Point_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); 00688 } 00689 00690 template<typename _Tp> static inline void read(const FileNode& node, Point3_<_Tp>& value, const Point3_<_Tp>& default_value) 00691 { 00692 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00693 value = temp.size() != 3 ? default_value : Point3_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), 00694 saturate_cast<_Tp>(temp[2])); 00695 } 00696 00697 template<typename _Tp> static inline void read(const FileNode& node, Size_<_Tp>& value, const Size_<_Tp>& default_value) 00698 { 00699 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00700 value = temp.size() != 2 ? default_value : Size_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); 00701 } 00702 00703 template<typename _Tp> static inline void read(const FileNode& node, Complex<_Tp>& value, const Complex<_Tp>& default_value) 00704 { 00705 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00706 value = temp.size() != 2 ? default_value : Complex<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); 00707 } 00708 00709 template<typename _Tp> static inline void read(const FileNode& node, Rect_<_Tp>& value, const Rect_<_Tp>& default_value) 00710 { 00711 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00712 value = temp.size() != 4 ? default_value : Rect_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), 00713 saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); 00714 } 00715 00716 template<typename _Tp, int cn> static inline void read(const FileNode& node, Vec<_Tp, cn>& value, const Vec<_Tp, cn>& default_value) 00717 { 00718 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00719 value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]); 00720 } 00721 00722 template<typename _Tp> static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value) 00723 { 00724 std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; 00725 value = temp.size() != 4 ? default_value : Scalar_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), 00726 saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); 00727 } 00728 00729 static inline void read(const FileNode& node, Range& value, const Range& default_value) 00730 { 00731 Point2i temp(value.start, value.end); const Point2i default_temp = Point2i(default_value.start, default_value.end); 00732 read(node, temp, default_temp); 00733 value.start = temp.x; value.end = temp.y; 00734 } 00735 00736 //! @} 00737 00738 /** @brief Writes string to a file storage. 00739 @relates cv::FileStorage 00740 */ 00741 CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str); 00742 00743 //! @cond IGNORED 00744 00745 namespace internal 00746 { 00747 class CV_EXPORTS WriteStructContext 00748 { 00749 public: 00750 WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String()); 00751 ~WriteStructContext(); 00752 private: 00753 FileStorage* fs; 00754 }; 00755 00756 template<typename _Tp, int numflag> class VecWriterProxy 00757 { 00758 public: 00759 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} 00760 void operator()(const std::vector<_Tp>& vec) const 00761 { 00762 size_t count = vec.size(); 00763 for (size_t i = 0; i < count; i++) 00764 write(*fs, vec[i]); 00765 } 00766 private: 00767 FileStorage* fs; 00768 }; 00769 00770 template<typename _Tp> class VecWriterProxy<_Tp, 1> 00771 { 00772 public: 00773 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} 00774 void operator()(const std::vector<_Tp>& vec) const 00775 { 00776 int _fmt = DataType<_Tp>::fmt; 00777 char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' }; 00778 fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp)); 00779 } 00780 private: 00781 FileStorage* fs; 00782 }; 00783 00784 template<typename _Tp, int numflag> class VecReaderProxy 00785 { 00786 public: 00787 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} 00788 void operator()(std::vector<_Tp>& vec, size_t count) const 00789 { 00790 count = std::min(count, it->remaining); 00791 vec.resize(count); 00792 for (size_t i = 0; i < count; i++, ++(*it)) 00793 read(**it, vec[i], _Tp()); 00794 } 00795 private: 00796 FileNodeIterator* it; 00797 }; 00798 00799 template<typename _Tp> class VecReaderProxy<_Tp, 1> 00800 { 00801 public: 00802 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} 00803 void operator()(std::vector<_Tp>& vec, size_t count) const 00804 { 00805 size_t remaining = it->remaining; 00806 size_t cn = DataType<_Tp>::channels; 00807 int _fmt = DataType<_Tp>::fmt; 00808 char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' }; 00809 size_t remaining1 = remaining / cn; 00810 count = count < remaining1 ? count : remaining1; 00811 vec.resize(count); 00812 it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp)); 00813 } 00814 private: 00815 FileNodeIterator* it; 00816 }; 00817 00818 } // internal 00819 00820 //! @endcond 00821 00822 //! @relates cv::FileStorage 00823 //! @{ 00824 00825 template<typename _Tp> static inline 00826 void write(FileStorage& fs, const _Tp& value) 00827 { 00828 write(fs, String(), value); 00829 } 00830 00831 template<> inline 00832 void write( FileStorage& fs, const int& value ) 00833 { 00834 writeScalar(fs, value); 00835 } 00836 00837 template<> inline 00838 void write( FileStorage& fs, const float& value ) 00839 { 00840 writeScalar(fs, value); 00841 } 00842 00843 template<> inline 00844 void write( FileStorage& fs, const double& value ) 00845 { 00846 writeScalar(fs, value); 00847 } 00848 00849 template<> inline 00850 void write( FileStorage& fs, const String& value ) 00851 { 00852 writeScalar(fs, value); 00853 } 00854 00855 template<typename _Tp> static inline 00856 void write(FileStorage& fs, const Point_<_Tp>& pt ) 00857 { 00858 write(fs, pt.x); 00859 write(fs, pt.y); 00860 } 00861 00862 template<typename _Tp> static inline 00863 void write(FileStorage& fs, const Point3_<_Tp>& pt ) 00864 { 00865 write(fs, pt.x); 00866 write(fs, pt.y); 00867 write(fs, pt.z); 00868 } 00869 00870 template<typename _Tp> static inline 00871 void write(FileStorage& fs, const Size_<_Tp>& sz ) 00872 { 00873 write(fs, sz.width); 00874 write(fs, sz.height); 00875 } 00876 00877 template<typename _Tp> static inline 00878 void write(FileStorage& fs, const Complex<_Tp>& c ) 00879 { 00880 write(fs, c.re); 00881 write(fs, c.im); 00882 } 00883 00884 template<typename _Tp> static inline 00885 void write(FileStorage& fs, const Rect_<_Tp>& r ) 00886 { 00887 write(fs, r.x); 00888 write(fs, r.y); 00889 write(fs, r.width); 00890 write(fs, r.height); 00891 } 00892 00893 template<typename _Tp, int cn> static inline 00894 void write(FileStorage& fs, const Vec<_Tp, cn>& v ) 00895 { 00896 for(int i = 0; i < cn; i++) 00897 write(fs, v.val[i]); 00898 } 00899 00900 template<typename _Tp> static inline 00901 void write(FileStorage& fs, const Scalar_<_Tp>& s ) 00902 { 00903 write(fs, s.val[0]); 00904 write(fs, s.val[1]); 00905 write(fs, s.val[2]); 00906 write(fs, s.val[3]); 00907 } 00908 00909 static inline 00910 void write(FileStorage& fs, const Range& r ) 00911 { 00912 write(fs, r.start); 00913 write(fs, r.end); 00914 } 00915 00916 template<typename _Tp> static inline 00917 void write( FileStorage& fs, const std::vector<_Tp>& vec ) 00918 { 00919 cv::internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); 00920 w(vec); 00921 } 00922 00923 00924 template<typename _Tp> static inline 00925 void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt ) 00926 { 00927 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00928 write(fs, pt); 00929 } 00930 00931 template<typename _Tp> static inline 00932 void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt ) 00933 { 00934 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00935 write(fs, pt); 00936 } 00937 00938 template<typename _Tp> static inline 00939 void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz ) 00940 { 00941 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00942 write(fs, sz); 00943 } 00944 00945 template<typename _Tp> static inline 00946 void write(FileStorage& fs, const String& name, const Complex<_Tp>& c ) 00947 { 00948 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00949 write(fs, c); 00950 } 00951 00952 template<typename _Tp> static inline 00953 void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r ) 00954 { 00955 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00956 write(fs, r); 00957 } 00958 00959 template<typename _Tp, int cn> static inline 00960 void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v ) 00961 { 00962 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00963 write(fs, v); 00964 } 00965 00966 template<typename _Tp> static inline 00967 void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s ) 00968 { 00969 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00970 write(fs, s); 00971 } 00972 00973 static inline 00974 void write(FileStorage& fs, const String& name, const Range& r ) 00975 { 00976 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); 00977 write(fs, r); 00978 } 00979 00980 template<typename _Tp> static inline 00981 void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec ) 00982 { 00983 cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); 00984 write(fs, vec); 00985 } 00986 00987 //! @} FileStorage 00988 00989 //! @relates cv::FileNode 00990 //! @{ 00991 00992 static inline 00993 void read(const FileNode& node, bool& value, bool default_value) 00994 { 00995 int temp; 00996 read(node, temp, (int)default_value); 00997 value = temp != 0; 00998 } 00999 01000 static inline 01001 void read(const FileNode& node, uchar& value, uchar default_value) 01002 { 01003 int temp; 01004 read(node, temp, (int)default_value); 01005 value = saturate_cast<uchar>(temp); 01006 } 01007 01008 static inline 01009 void read(const FileNode& node, schar& value, schar default_value) 01010 { 01011 int temp; 01012 read(node, temp, (int)default_value); 01013 value = saturate_cast<schar>(temp); 01014 } 01015 01016 static inline 01017 void read(const FileNode& node, ushort& value, ushort default_value) 01018 { 01019 int temp; 01020 read(node, temp, (int)default_value); 01021 value = saturate_cast<ushort>(temp); 01022 } 01023 01024 static inline 01025 void read(const FileNode& node, short& value, short default_value) 01026 { 01027 int temp; 01028 read(node, temp, (int)default_value); 01029 value = saturate_cast<short>(temp); 01030 } 01031 01032 template<typename _Tp> static inline 01033 void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX ) 01034 { 01035 cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); 01036 r(vec, maxCount); 01037 } 01038 01039 template<typename _Tp> static inline 01040 void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() ) 01041 { 01042 if(!node.node) 01043 vec = default_value; 01044 else 01045 { 01046 FileNodeIterator it = node.begin(); 01047 read( it, vec ); 01048 } 01049 } 01050 01051 //! @} FileNode 01052 01053 //! @relates cv::FileStorage 01054 //! @{ 01055 01056 /** @brief Writes data to a file storage. 01057 */ 01058 template<typename _Tp> static inline 01059 FileStorage& operator << (FileStorage& fs, const _Tp& value) 01060 { 01061 if( !fs.isOpened() ) 01062 return fs; 01063 if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP ) 01064 CV_Error( Error::StsError, "No element name has been given" ); 01065 write( fs, fs.elname, value ); 01066 if( fs.state & FileStorage::INSIDE_MAP ) 01067 fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP; 01068 return fs; 01069 } 01070 01071 /** @brief Writes data to a file storage. 01072 */ 01073 static inline 01074 FileStorage& operator << (FileStorage& fs, const char* str) 01075 { 01076 return (fs << String(str)); 01077 } 01078 01079 /** @brief Writes data to a file storage. 01080 */ 01081 static inline 01082 FileStorage& operator << (FileStorage& fs, char* value) 01083 { 01084 return (fs << String(value)); 01085 } 01086 01087 //! @} FileStorage 01088 01089 //! @relates cv::FileNodeIterator 01090 //! @{ 01091 01092 /** @brief Reads data from a file storage. 01093 */ 01094 template<typename _Tp> static inline 01095 FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) 01096 { 01097 read( *it, value, _Tp()); 01098 return ++it; 01099 } 01100 01101 /** @brief Reads data from a file storage. 01102 */ 01103 template<typename _Tp> static inline 01104 FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec) 01105 { 01106 cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); 01107 r(vec, (size_t)INT_MAX); 01108 return it; 01109 } 01110 01111 //! @} FileNodeIterator 01112 01113 //! @relates cv::FileNode 01114 //! @{ 01115 01116 /** @brief Reads data from a file storage. 01117 */ 01118 template<typename _Tp> static inline 01119 void operator >> (const FileNode& n, _Tp& value) 01120 { 01121 read( n, value, _Tp()); 01122 } 01123 01124 /** @brief Reads data from a file storage. 01125 */ 01126 template<typename _Tp> static inline 01127 void operator >> (const FileNode& n, std::vector<_Tp>& vec) 01128 { 01129 FileNodeIterator it = n.begin(); 01130 it >> vec; 01131 } 01132 01133 //! @} FileNode 01134 01135 //! @relates cv::FileNodeIterator 01136 //! @{ 01137 01138 static inline 01139 bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2) 01140 { 01141 return it1.fs == it2.fs && it1.container == it2.container && 01142 it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining; 01143 } 01144 01145 static inline 01146 bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2) 01147 { 01148 return !(it1 == it2); 01149 } 01150 01151 static inline 01152 ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2) 01153 { 01154 return it2.remaining - it1.remaining; 01155 } 01156 01157 static inline 01158 bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) 01159 { 01160 return it1.remaining > it2.remaining; 01161 } 01162 01163 //! @} FileNodeIterator 01164 01165 //! @cond IGNORED 01166 01167 inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); } 01168 inline FileNode::FileNode() : fs(0), node(0) {} 01169 inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {} 01170 inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {} 01171 inline bool FileNode::empty() const { return node == 0; } 01172 inline bool FileNode::isNone() const { return type() == NONE; } 01173 inline bool FileNode::isSeq() const { return type() == SEQ; } 01174 inline bool FileNode::isMap() const { return type() == MAP; } 01175 inline bool FileNode::isInt() const { return type() == INT; } 01176 inline bool FileNode::isReal() const { return type() == REAL; } 01177 inline bool FileNode::isString() const { return type() == STR; } 01178 inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; } 01179 inline const CvFileNode* FileNode::operator* () const { return node; } 01180 inline FileNode::operator int() const { int value; read(*this, value, 0); return value; } 01181 inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; } 01182 inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; } 01183 inline FileNode::operator String() const { String value; read(*this, value, value); return value; } 01184 inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); } 01185 inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); } 01186 inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); } 01187 inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); } 01188 inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); } 01189 inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); } 01190 01191 //! @endcond 01192 01193 } // cv 01194 01195 #endif // __OPENCV_CORE_PERSISTENCE_HPP__ 01196
Generated on Tue Jul 12 2022 14:47:32 by
