diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index 8d48759714..cf09891006 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -462,6 +462,11 @@ public: */ static String getDefaultObjectName(const String& filename); + /** @brief Returns the current format. + * @returns The current format, see FileStorage::Mode + */ + CV_WRAP int getFormat() const; + Ptr fs; //!< the underlying C FileStorage structure String elname; //!< the currently written element std::vector structs; //!< the stack of written structures diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index bb4d953d4a..a67578428e 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -4270,11 +4270,25 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const if( fmt == CV_STORAGE_FORMAT_AUTO && filename ) { - const char* dot_pos = strrchr( filename, '.' ); + const char* dot_pos = NULL; + const char* dot_pos2 = NULL; + // like strrchr() implementation, but save two last positions simultaneously + for (const char* pos = filename; pos[0] != 0; pos++) + { + if (pos[0] == '.') + { + dot_pos2 = dot_pos; + dot_pos = pos; + } + } + if (cv_strcasecmp(dot_pos, ".gz") && dot_pos2 != NULL) + { + dot_pos = dot_pos2; + } fs->fmt - = cv_strcasecmp( dot_pos, ".xml" ) + = (cv_strcasecmp(dot_pos, ".xml") || cv_strcasecmp(dot_pos, ".xml.gz")) ? CV_STORAGE_FORMAT_XML - : cv_strcasecmp( dot_pos, ".json" ) + : (cv_strcasecmp(dot_pos, ".json") || cv_strcasecmp(dot_pos, ".json.gz")) ? CV_STORAGE_FORMAT_JSON : CV_STORAGE_FORMAT_YAML ; @@ -6920,6 +6934,12 @@ FileNode FileStorage::root(int streamidx) const return isOpened() ? FileNode(fs, cvGetRootFileNode(fs, streamidx)) : FileNode(); } +int FileStorage::getFormat() const +{ + CV_Assert(!fs.empty()); + return fs->fmt & FORMAT_MASK; +} + FileStorage& operator << (FileStorage& fs, const String& str) { CV_TRACE_REGION_VERBOSE(); diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 253d2a60f0..939e80d7fb 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -1236,3 +1236,59 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector) } } } + +TEST(Core_InputOutput, FileStorage_format_xml) +{ + FileStorage fs; + fs.open("opencv_storage.xml", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_XML, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_xml_gz) +{ + FileStorage fs; + fs.open("opencv_storage.xml.gz", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_XML, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_json) +{ + FileStorage fs; + fs.open("opencv_storage.json", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_JSON, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_json_gz) +{ + FileStorage fs; + fs.open("opencv_storage.json.gz", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_JSON, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_yaml) +{ + FileStorage fs; + fs.open("opencv_storage.yaml", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_yaml_gz) +{ + FileStorage fs; + fs.open("opencv_storage.yaml.gz", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_yml) +{ + FileStorage fs; + fs.open("opencv_storage.yml", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat()); +} + +TEST(Core_InputOutput, FileStorage_format_yml_gz) +{ + FileStorage fs; + fs.open("opencv_storage.yml.gz", FileStorage::WRITE | FileStorage::MEMORY); + EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat()); +}