libcamera: yaml_parser: Switch from FILE to File
THe FILE object isn't very user-friendly as it requires manual close. Replace it with File to provide RAII-style resource management in the YamlParser API. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
27fb47f70b
commit
d6d0a675bf
4 changed files with 47 additions and 30 deletions
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -18,6 +17,7 @@
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
|
class File;
|
||||||
class YamlParserContext;
|
class YamlParserContext;
|
||||||
|
|
||||||
class YamlObject
|
class YamlObject
|
||||||
|
@ -82,7 +82,7 @@ private:
|
||||||
class YamlParser final
|
class YamlParser final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<YamlObject> parse(std::FILE *fh);
|
static std::unique_ptr<YamlObject> parse(File &file);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <libcamera/base/file.h>
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
|
|
||||||
#include "libcamera/internal/yaml_parser.h"
|
#include "libcamera/internal/yaml_parser.h"
|
||||||
|
@ -27,7 +28,7 @@ class CameraHalConfig::Private : public Extensible::Private
|
||||||
public:
|
public:
|
||||||
Private();
|
Private();
|
||||||
|
|
||||||
int parseConfigFile(FILE *fh, std::map<std::string, CameraConfigData> *cameras);
|
int parseConfigFile(File &file, std::map<std::string, CameraConfigData> *cameras);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int parseCameraConfigData(const std::string &cameraId, const YamlObject &);
|
int parseCameraConfigData(const std::string &cameraId, const YamlObject &);
|
||||||
|
@ -41,7 +42,7 @@ CameraHalConfig::Private::Private()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int CameraHalConfig::Private::parseConfigFile(FILE *fh,
|
int CameraHalConfig::Private::parseConfigFile(File &file,
|
||||||
std::map<std::string, CameraConfigData> *cameras)
|
std::map<std::string, CameraConfigData> *cameras)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -65,7 +66,7 @@ int CameraHalConfig::Private::parseConfigFile(FILE *fh,
|
||||||
|
|
||||||
cameras_ = cameras;
|
cameras_ = cameras;
|
||||||
|
|
||||||
std::unique_ptr<YamlObject> root = YamlParser::parse(fh);
|
std::unique_ptr<YamlObject> root = YamlParser::parse(file);
|
||||||
if (!root)
|
if (!root)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -169,9 +170,9 @@ int CameraHalConfig::parseConfigurationFile()
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fh = fopen(filePath.c_str(), "r");
|
File file(filePath);
|
||||||
if (!fh) {
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||||
int ret = -errno;
|
int ret = file.error();
|
||||||
LOG(HALConfig, Error) << "Failed to open configuration file "
|
LOG(HALConfig, Error) << "Failed to open configuration file "
|
||||||
<< filePath << ": " << strerror(-ret);
|
<< filePath << ": " << strerror(-ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -179,8 +180,7 @@ int CameraHalConfig::parseConfigurationFile()
|
||||||
|
|
||||||
exists_ = true;
|
exists_ = true;
|
||||||
|
|
||||||
int ret = _d()->parseConfigFile(fh, &cameras_);
|
int ret = _d()->parseConfigFile(file, &cameras_);
|
||||||
fclose(fh);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <libcamera/base/file.h>
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
|
|
||||||
#include <yaml.h>
|
#include <yaml.h>
|
||||||
|
@ -345,7 +346,7 @@ public:
|
||||||
YamlParserContext();
|
YamlParserContext();
|
||||||
~YamlParserContext();
|
~YamlParserContext();
|
||||||
|
|
||||||
int init(std::FILE *fh);
|
int init(File &file);
|
||||||
int parseContent(YamlObject &yamlObject);
|
int parseContent(YamlObject &yamlObject);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -358,6 +359,9 @@ private:
|
||||||
};
|
};
|
||||||
using EventPtr = std::unique_ptr<yaml_event_t, EventDeleter>;
|
using EventPtr = std::unique_ptr<yaml_event_t, EventDeleter>;
|
||||||
|
|
||||||
|
static int yamlRead(void *data, unsigned char *buffer, size_t size,
|
||||||
|
size_t *sizeRead);
|
||||||
|
|
||||||
EventPtr nextEvent();
|
EventPtr nextEvent();
|
||||||
|
|
||||||
void readValue(std::string &value, EventPtr event);
|
void readValue(std::string &value, EventPtr event);
|
||||||
|
@ -399,13 +403,13 @@ YamlParserContext::~YamlParserContext()
|
||||||
* \param[in] fh The YAML file to parse
|
* \param[in] fh The YAML file to parse
|
||||||
*
|
*
|
||||||
* Prior to parsing the YAML content, the YamlParserContext must be initialized
|
* Prior to parsing the YAML content, the YamlParserContext must be initialized
|
||||||
* with an opened FILE to create an internal parser. The FILE needs to stay
|
* with a file to create an internal parser. The file needs to stay valid until
|
||||||
* valid during the process.
|
* parsing completes.
|
||||||
*
|
*
|
||||||
* \return 0 on success or a negative error code otherwise
|
* \return 0 on success or a negative error code otherwise
|
||||||
* \retval -EINVAL The parser has failed to initialize
|
* \retval -EINVAL The parser has failed to initialize
|
||||||
*/
|
*/
|
||||||
int YamlParserContext::init(std::FILE *fh)
|
int YamlParserContext::init(File &file)
|
||||||
{
|
{
|
||||||
/* yaml_parser_initialize returns 1 when it succeededs */
|
/* yaml_parser_initialize returns 1 when it succeededs */
|
||||||
if (!yaml_parser_initialize(&parser_)) {
|
if (!yaml_parser_initialize(&parser_)) {
|
||||||
|
@ -413,11 +417,25 @@ int YamlParserContext::init(std::FILE *fh)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
parserValid_ = true;
|
parserValid_ = true;
|
||||||
yaml_parser_set_input_file(&parser_, fh);
|
yaml_parser_set_input(&parser_, &YamlParserContext::yamlRead, &file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int YamlParserContext::yamlRead(void *data, unsigned char *buffer, size_t size,
|
||||||
|
size_t *sizeRead)
|
||||||
|
{
|
||||||
|
File *file = static_cast<File *>(data);
|
||||||
|
|
||||||
|
Span<unsigned char> buf{ buffer, size };
|
||||||
|
ssize_t ret = file->read(buf);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*sizeRead = ret;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn YamlParserContext::nextEvent()
|
* \fn YamlParserContext::nextEvent()
|
||||||
* \brief Get the next event
|
* \brief Get the next event
|
||||||
|
@ -655,21 +673,20 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn YamlParser::parse()
|
|
||||||
* \brief Parse a YAML file as a YamlObject
|
* \brief Parse a YAML file as a YamlObject
|
||||||
* \param[in] fh The YAML file to parse
|
* \param[in] file The YAML file to parse
|
||||||
*
|
*
|
||||||
* The YamlParser::parse() function takes an open FILE, parses its contents, and
|
* The YamlParser::parse() function takes a file, parses its contents, and
|
||||||
* returns a pointer to a YamlObject corresponding to the root node of the YAML
|
* returns a pointer to a YamlObject corresponding to the root node of the YAML
|
||||||
* document. The caller is responsible for closing the file.
|
* document.
|
||||||
*
|
*
|
||||||
* \return Pointer to result YamlObject on success or nullptr otherwise
|
* \return Pointer to result YamlObject on success or nullptr otherwise
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<YamlObject> YamlParser::parse(std::FILE *fh)
|
std::unique_ptr<YamlObject> YamlParser::parse(File &file)
|
||||||
{
|
{
|
||||||
YamlParserContext context;
|
YamlParserContext context;
|
||||||
|
|
||||||
if (context.init(fh))
|
if (context.init(file))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
std::unique_ptr<YamlObject> root(new YamlObject());
|
std::unique_ptr<YamlObject> root(new YamlObject());
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <libcamera/base/file.h>
|
||||||
|
|
||||||
#include "libcamera/internal/yaml_parser.h"
|
#include "libcamera/internal/yaml_parser.h"
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
@ -69,29 +71,27 @@ protected:
|
||||||
int run()
|
int run()
|
||||||
{
|
{
|
||||||
/* Test invalid YAML file */
|
/* Test invalid YAML file */
|
||||||
FILE *fh = fopen(invalidYamlFile_.c_str(), "r");
|
File file{ invalidYamlFile_ };
|
||||||
if (!fh) {
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||||
cerr << "Fail to open invalid YAML file" << std::endl;
|
cerr << "Fail to open invalid YAML file" << std::endl;
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<YamlObject> root = YamlParser::parse(fh);
|
std::unique_ptr<YamlObject> root = YamlParser::parse(file);
|
||||||
fclose(fh);
|
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
cerr << "Invalid YAML file parse successfully" << std::endl;
|
cerr << "Invalid YAML file parse successfully" << std::endl;
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test YAML file */
|
/* Test YAML file */
|
||||||
fh = fopen(testYamlFile_.c_str(), "r");
|
file.close();
|
||||||
if (!fh) {
|
file.setFileName(testYamlFile_);
|
||||||
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||||
cerr << "Fail to open test YAML file" << std::endl;
|
cerr << "Fail to open test YAML file" << std::endl;
|
||||||
return TestFail;
|
return TestFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
root = YamlParser::parse(fh);
|
root = YamlParser::parse(file);
|
||||||
fclose(fh);
|
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
cerr << "Fail to parse test YAML file: " << std::endl;
|
cerr << "Fail to parse test YAML file: " << std::endl;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue