Renesas / opencv-lib

Dependents:   RZ_A2M_Mbed_samples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers persistence.hpp Source File

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