Filestorage roadmap (#1208)

FileStorage: added FileStorage features
This commit is contained in:
diegohce
2024-09-01 06:03:58 -03:00
committed by GitHub
parent a54b37615d
commit 96933edced
6 changed files with 646 additions and 0 deletions

77
persistence.h Normal file
View File

@@ -0,0 +1,77 @@
#ifndef _OPENCV3_OBJDETECT_H_
#define _OPENCV3_OBJDETECT_H_
#include <stdbool.h>
#ifdef __cplusplus
#include <opencv2/opencv.hpp>
extern "C" {
#endif
#include "core.h"
#ifdef __cplusplus
typedef cv::FileStorage* FileStorage;
typedef cv::FileNode* FileNode;
#else
typedef void* FileStorage;
typedef void* FileNode;
#endif
// FileStorage
FileStorage FileStorage_Create(void);
FileStorage FileStorage_CreateWithParams(const char* filename, int flags, const char* encoding);
void FileStorage_Close(FileStorage fs);
const char *FileStorage_ElName(FileStorage fs);
int FileStorage_State(FileStorage fs);
void FileStorage_EndWriteStruct(FileStorage fs);
int FileStorage_GetFormat(FileStorage fs);
bool FileStorage_IsOpened(FileStorage fs);
bool FileStorage_Open(FileStorage fs, const char* filename, int flags, const char* encoding);
void FileStorage_Release(FileStorage fs);
const char* FileStorage_ReleaseAndGetString(FileStorage fs);
void FileStorage_StartWriteStruct(FileStorage fs, const char* name, int flags, const char* typeName);
void FileStorage_WriteMat(FileStorage fs, const char* name, Mat val);
void FileStorage_WriteString(FileStorage fs, const char* name, const char* val);
void FileStorage_WriteStringArray(FileStorage fs, const char* name, const char** val, size_t len);
void FileStorage_WriteDouble(FileStorage fs, const char* name, double val);
void FileStorage_WriteInt(FileStorage fs, const char* name, int val);
void FileStorage_WriteComment(FileStorage fs, const char* comment, bool append);
void FileStorage_WriteRaw(FileStorage fs, const char* fmt, const void* vec, size_t len);
FileNode FileStorage_GetFirstTopLevelNode(FileStorage fs);
FileNode FileStorage_GetNode(FileStorage fs, const char* nodename);
FileNode FileStorage_Root(FileStorage fs, int streamidx);
bool FileNode_Empty(FileNode fn);
bool FileNode_IsInt(FileNode fn);
bool FileNode_IsMap(FileNode fn);
bool FileNode_IsNamed(FileNode fn);
bool FileNode_IsNone(FileNode fn);
bool FileNode_IsReal(FileNode fn);
bool FileNode_IsSeq(FileNode fn);
bool FileNode_IsString(FileNode fn);
char** FileNode_Keys(FileNode fn);
size_t FileNode_KeysCount(FileNode fn);
void FileNode_KeysFree(char** keys, size_t len);
Mat FileNode_Mat(FileNode fn);
const char* FileNode_Name(FileNode fn);
float FileNode_Float(FileNode fn);
const char* FileNode_String(FileNode fn);
FileNode FileNode_Get(FileNode fn, int i); //FileNode operator[] (int i) const
FileNode FileNode_GetByName(FileNode fn, const char* nodename); //FileNode operator[] (const char *nodename) const
size_t FileNode_RawSize(FileNode fn);
void FileNode_ReadRaw(FileNode fn, const char* fmt, void *vec, size_t len);
void FileNode_SetValue(FileNode fn, int type, const void *value, int len);
size_t FileNode_Size(FileNode fn);
int FileNode_Type(FileNode fn);
void FileNode_Close(FileNode fn);
#ifdef __cplusplus
}
#endif
#endif //_OPENCV3_OBJDETECT_H_

113
persistence_filenode.cpp Normal file
View File

@@ -0,0 +1,113 @@
#include <string.h>
#include "persistence.h"
bool FileNode_Empty(FileNode fn) {
return fn->empty();
}
bool FileNode_IsInt(FileNode fn){
return fn->isInt();
}
bool FileNode_IsMap(FileNode fn){
return fn->isMap();
}
bool FileNode_IsNamed(FileNode fn) {
return fn->isNamed();
}
bool FileNode_IsNone(FileNode fn){
return fn->isNone();
}
bool FileNode_IsReal(FileNode fn){
return fn->isReal();
}
bool FileNode_IsSeq(FileNode fn) {
return fn->isSeq();
}
bool FileNode_IsString(FileNode fn) {
return fn->isString();
}
char** FileNode_Keys(FileNode fn) {
std::vector<cv::String> keys = fn->keys();
char** c_keys = new char*[keys.size()];
for (int i = 0; i < keys.size(); i++) {
char *c_key = new char[keys[i].length()+1];
strcpy(c_key, keys[i].c_str());
c_keys[i] = c_key;
}
return c_keys;
}
size_t FileNode_KeysCount(FileNode fn) {
return fn->keys().size();
}
void FileNode_KeysFree(char** keys, size_t len) {
for(int i = 0; i < len; i++) {
delete keys[i];
}
delete keys;
}
Mat FileNode_Mat(FileNode fn) {
return new cv::Mat(fn->mat());
}
const char* FileNode_Name(FileNode fn) {
char* str = new char[fn->name().length()+1];
strcpy(str, fn->name().c_str());
return str;
}
float FileNode_Float(FileNode fn) {
return (float)fn->real();
}
const char* FileNode_String(FileNode fn) {
char* str = new char[fn->string().length()+1];
strcpy(str, fn->string().c_str());
return str;
}
FileNode FileNode_Get(FileNode fn, int i) {
return new cv::FileNode((*fn)[i]);
}
FileNode FileNode_GetByName(FileNode fn, const char* nodename) {
return new cv::FileNode((*fn)[nodename]);
}
size_t FileNode_RawSize(FileNode fn) {
return fn->rawSize();
}
void FileNode_ReadRaw(FileNode fn, const char* fmt, void *vec, size_t len) {
fn->readRaw(fmt, vec, len);
}
void FileNode_SetValue(FileNode fn, int type, const void *value, int len) {
fn->setValue(type, value, len);
}
size_t FileNode_Size(FileNode fn) {
return fn->size();
}
int FileNode_Type(FileNode fn) {
return fn->type();
}
void FileNode_Close(FileNode fn){
delete fn;
}

84
persistence_filenode.go Normal file
View File

@@ -0,0 +1,84 @@
package gocv
/*
#include <stdlib.h>
#include "persistence.h"
*/
import "C"
import "unsafe"
type FileNodeType int
const (
FileNodeTypeNone FileNodeType = 0
FileNodeTypeInt FileNodeType = 1
FileNodeTypeReal FileNodeType = 2
FileNodeTypeFloat FileNodeType = FileNodeTypeReal
FileNodeTypeStr FileNodeType = 3
FileNodeTypeString FileNodeType = FileNodeTypeStr
FileNodeTypeSeq FileNodeType = 4
FileNodeTypeMap FileNodeType = 5
FileNodeTypeTypeMask FileNodeType = 7
FileNodeTypeFlow FileNodeType = 8
FileNodeTypeUniform FileNodeType = 8
FileNodeTypeEmpty FileNodeType = 16
FileNodeTypeNamed FileNodeType = 32
)
// FileNode is a wrapper for the OpenCV FileNode class
//
// Ref: https://docs.opencv.org/4.x/de/dd9/classcv_1_1FileNode.html
type FileNode struct {
p C.FileNode
}
func (fn *FileNode) Empty() bool {
return bool(C.FileNode_Empty(fn.p))
}
func (fn *FileNode) IsInt() bool {
return bool(C.FileNode_IsInt(fn.p))
}
func (fn *FileNode) IsMap() bool {
return bool(C.FileNode_IsMap(fn.p))
}
func (fn *FileNode) IsNamed() bool {
return bool(C.FileNode_IsNamed(fn.p))
}
func (fn *FileNode) IsNone() bool {
return bool(C.FileNode_IsNone(fn.p))
}
func (fn *FileNode) IsReal() bool {
return bool(C.FileNode_IsReal(fn.p))
}
func (fn *FileNode) IsSeq() bool {
return bool(C.FileNode_IsSeq(fn.p))
}
func (fn *FileNode) IsString() bool {
return bool(C.FileNode_IsString(fn.p))
}
func (fn *FileNode) Keys() []string {
c_keys_count := C.FileNode_KeysCount(fn.p)
c_keys := C.FileNode_Keys(fn.p)
defer C.FileNode_KeysFree(c_keys, c_keys_count)
keys := make([]string, int(c_keys_count))
c_keys_slice := unsafe.Slice(c_keys, c_keys_count)
for i := 0; i < int(c_keys_count); i++ {
keys[i] = C.GoString(c_keys_slice[i])
}
return keys
}
func (fn *FileNode) Close() {
C.FileNode_Close(fn.p)
}

113
persistence_filestorage.cpp Normal file
View File

@@ -0,0 +1,113 @@
#include <string.h>
#include "persistence.h"
FileStorage FileStorage_Create(void) {
return new cv::FileStorage();
}
FileStorage FileStorage_CreateWithParams(const char* filename, int flags, const char* encoding) {
return new cv::FileStorage(filename, flags, encoding);
}
const char *FileStorage_ElName(FileStorage fs) {
char* str = new char[fs->elname.length()+1];
strcpy(str, fs->elname.c_str());
return str;
}
int FileStorage_State(FileStorage fs) {
return fs->state;
}
void FileStorage_Close(FileStorage fs) {
fs->release();
delete fs;
}
void FileStorage_EndWriteStruct(FileStorage fs) {
fs->endWriteStruct();
}
int FileStorage_GetFormat(FileStorage fs){
return fs->getFormat();
}
bool FileStorage_IsOpened(FileStorage fs) {
return fs->isOpened();
}
bool FileStorage_Open(FileStorage fs, const char* filename, int flags, const char* encoding) {
return fs->open(filename, flags, encoding);
}
void FileStorage_Release(FileStorage fs) {
fs->release();
delete fs;
}
const char* FileStorage_ReleaseAndGetString(FileStorage fs) {
cv::String s = fs->releaseAndGetString();
char* str = new char[s.length()+1];
strcpy(str, s.c_str());
return str;
}
void FileStorage_StartWriteStruct(FileStorage fs, const char* name, int flags, const char* typeName){
fs->startWriteStruct(name, flags, typeName);
}
void FileStorage_WriteMat(FileStorage fs, const char* name, Mat val){
fs->write(name, *val);
}
void FileStorage_WriteString(FileStorage fs, const char* name, const char* val) {
fs->write(name, val);
}
void FileStorage_WriteStringArray(FileStorage fs, const char* name, const char** val, size_t len) {
std::vector<cv::String> vals;
for(int i = 0; i < len; i++) {
vals.push_back(val[i]);
}
fs->write(name, vals);
}
void FileStorage_WriteDouble(FileStorage fs, const char* name, double val){
fs->write(name, val);
}
void FileStorage_WriteInt(FileStorage fs, const char* name, int val){
fs->write(name, val);
}
void FileStorage_WriteComment(FileStorage fs, const char* comment, bool append){
fs->writeComment(comment, append);
}
void FileStorage_WriteRaw(FileStorage fs, const char* fmt, const void* vec, size_t len){
fs->writeRaw(fmt, vec, len);
}
FileNode FileStorage_GetFirstTopLevelNode(FileStorage fs) {
cv::FileNode node = fs->getFirstTopLevelNode();
FileNode fn = new cv::FileNode(node);
return fn;
}
FileNode FileStorage_GetNode(FileStorage fs, const char* nodename) {
cv::FileNode node = (*fs)[nodename];
FileNode fn = new cv::FileNode(node);
return fn;
}
FileNode FileStorage_Root(FileStorage fs, int streamidx) {
cv::FileNode node = fs->root(streamidx);
FileNode fn = new cv::FileNode(node);
return fn;
}

202
persistence_filestorage.go Normal file
View File

@@ -0,0 +1,202 @@
package gocv
/*
#include <stdlib.h>
#include <stdbool.h>
#include "persistence.h"
*/
import "C"
import "unsafe"
type FileStorageMode int
const (
FileStorageModeRead FileStorageMode = 0
FileStorageModeWrite FileStorageMode = 1
FileStorageModeAppend FileStorageMode = 2
FileStorageModeMemory FileStorageMode = 4
FileStorageModeFormatMask FileStorageMode = (7 << 3)
FileStorageModeFormatAuto FileStorageMode = 0
FileStorageModeFormatXml FileStorageMode = (1 << 3)
FileStorageModeFormatYaml FileStorageMode = (2 << 3)
FileStorageModeFormatJson FileStorageMode = (3 << 3)
FileStorageModeBase64 FileStorageMode = 64
FileStorageModeWriteBase64 FileStorageMode = FileStorageModeBase64 | FileStorageModeWrite
)
type FileStorageState int
const (
FileStorageStateUndefined FileStorageState = 0
FileStorageStateValueExpected FileStorageState = 1
FileStorageStateNameExpected FileStorageState = 2
FileStorageStateInsideMap FileStorageState = 4
)
// FileStorage is a wrapper for the OpenCV FileStorage class
//
// Ref: https://docs.opencv.org/4.x/da/d56/classcv_1_1FileStorage.html
type FileStorage struct {
p C.FileStorage
}
func NewFileStorage() *FileStorage {
return &FileStorage{p: C.FileStorage_Create()}
}
func NewFileStorageWithParams(filename string, flags FileStorageMode, encoding string) *FileStorage {
c_filename := C.CString(filename)
c_encoding := C.CString(encoding)
defer C.free(unsafe.Pointer(c_filename))
defer C.free(unsafe.Pointer(c_encoding))
return &FileStorage{p: C.FileStorage_CreateWithParams(c_filename, C.int(flags), c_encoding)}
}
func (fs *FileStorage) Close() {
fs.Release()
}
func (fs *FileStorage) Release() {
C.FileStorage_Release(fs.p)
}
func (fs *FileStorage) ElName() string {
c_str := C.FileStorage_ElName(fs.p)
defer C.free(unsafe.Pointer(c_str))
str := C.GoString(c_str)
return str
}
func (fs *FileStorage) State() FileStorageState {
state := C.FileStorage_State(fs.p)
return FileStorageState(int(state))
}
func (fs *FileStorage) EndWriteStruct() {
C.FileStorage_EndWriteStruct(fs.p)
}
func (fs *FileStorage) GetFormat() FileStorageMode {
fmt := C.FileStorage_GetFormat(fs.p)
return FileStorageMode(int(fmt))
}
func (fs *FileStorage) IsOpened() bool {
b := C.FileStorage_IsOpened(fs.p)
return bool(b)
}
func (fs *FileStorage) Open(filename string, flags FileStorageMode, encoding string) bool {
c_filename := C.CString(filename)
c_encoding := C.CString(encoding)
defer C.free(unsafe.Pointer(c_filename))
defer C.free(unsafe.Pointer(c_encoding))
b := C.FileStorage_Open(fs.p, c_filename, C.int(flags), c_encoding)
return bool(b)
}
func (fs *FileStorage) ReleaseAndGetString() string {
c_str := C.FileStorage_ReleaseAndGetString(fs.p)
defer C.free(unsafe.Pointer(c_str))
str := C.GoString(c_str)
return str
}
func (fs *FileStorage) StartWriteStruct(name string, flags FileNodeType, typeName string) {
c_name := C.CString(name)
c_typeName := C.CString(typeName)
defer C.free(unsafe.Pointer(c_name))
defer C.free(unsafe.Pointer(c_typeName))
C.FileStorage_StartWriteStruct(fs.p, c_name, C.int(flags), c_typeName)
}
func (fs *FileStorage) WriteMat(name string, mat Mat) {
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
C.FileStorage_WriteMat(fs.p, c_name, mat.p)
}
func (fs *FileStorage) WriteString(name string, val string) {
c_name := C.CString(name)
c_val := C.CString(val)
defer C.free(unsafe.Pointer(c_name))
defer C.free(unsafe.Pointer(c_val))
C.FileStorage_WriteString(fs.p, c_name, c_val)
}
func (fs *FileStorage) WriteStringArray(name string, val []string) {
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
c_val := make([]*C.char, 0, len(val))
for _, v := range val {
c_val = append(c_val, C.CString(v))
}
defer func() {
for _, p := range c_val {
C.free(unsafe.Pointer(p))
}
}()
C.FileStorage_WriteStringArray(fs.p, c_name, &c_val[0], C.size_t(len(val)))
}
func (fs *FileStorage) WriteDouble(name string, val float32) {
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
C.FileStorage_WriteDouble(fs.p, c_name, C.double(val))
}
func (fs *FileStorage) WriteInt(name string, val int) {
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
C.FileStorage_WriteInt(fs.p, c_name, C.int(val))
}
func (fs *FileStorage) WriteComment(comment string, append bool) {
c_comment := C.CString(comment)
defer C.free(unsafe.Pointer(c_comment))
C.FileStorage_WriteComment(fs.p, c_comment, C.bool(append))
}
func (fs *FileStorage) WriteRaw(fmt string, vec []byte) {
c_fmt := C.CString(fmt)
defer C.free(unsafe.Pointer(c_fmt))
c_vec := C.CBytes(vec)
defer C.free(c_vec)
C.FileStorage_WriteRaw(fs.p, c_fmt, c_vec, C.size_t(len(vec)))
}
func (fs *FileStorage) GetFirstTopLevelNode() *FileNode {
node_p := C.FileStorage_GetFirstTopLevelNode(fs.p)
return &FileNode{p: node_p}
}
func (fs *FileStorage) GetNode(name string) *FileNode {
c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))
node_p := C.FileStorage_GetNode(fs.p, c_name)
return &FileNode{p: node_p}
}
func (fs *FileStorage) Root(streamIdx int) *FileNode {
node_p := C.FileStorage_Root(fs.p, C.int(streamIdx))
return &FileNode{p: node_p}
}

57
persistence_test.go Normal file
View File

@@ -0,0 +1,57 @@
package gocv
import (
"os"
"path/filepath"
"testing"
)
func TestFileStorage(t *testing.T) {
fileStorageTestFilename := filepath.Join(os.TempDir(), "filestorage.json")
fs := NewFileStorageWithParams(fileStorageTestFilename, FileStorageModeWrite|FileStorageModeFormatJson, "utf-8")
fs.StartWriteStruct("gocv", FileNodeTypeMap, "person")
fs.ElName()
fs.State()
fs.GetFormat()
fs.IsOpened()
m := NewMat()
defer m.Close()
fs.WriteMat("mat", m)
fs.WriteString("string", "string value")
fs.WriteStringArray("stringArray", []string{"string", "array"})
fs.WriteDouble("double", 3.1415927)
fs.WriteInt("int", 42)
fs.WriteComment("no comments", true)
fs.EndWriteStruct()
fs.StartWriteStruct("gocv2", FileNodeTypeSeq, "int")
fs.WriteRaw("u", []byte{0, 0})
fs.EndWriteStruct()
fs.GetNode("gocv")
fs.Root(0)
fs.ReleaseAndGetString()
fs = NewFileStorage()
fs.Open(fileStorageTestFilename, FileStorageModeRead|FileStorageModeFormatJson, "utf-8")
fn := fs.GetFirstTopLevelNode()
defer fn.Close()
fn.Empty()
fn.IsInt()
fn.IsMap()
fn.IsNamed()
fn.IsNone()
fn.IsReal()
fn.IsSeq()
fn.IsString()
fn.Keys()
fs.Release()
}