fxos: more BSON utilities
This commit is contained in:
parent
c0820b59f0
commit
6edbd1dba1
|
@ -6,8 +6,8 @@
|
|||
//---------------------------------------------------------------------------//
|
||||
// fxos/util/bson: Binary serialization (BSON format)
|
||||
//
|
||||
// This header implementats a subset of the BSON format [1], which fxos uses
|
||||
// to save project and configuration files. The few aspects of note of this
|
||||
// This header implements a subset of the BSON format [1], which fxos uses to
|
||||
// save project and configuration files. The few aspects of note of this
|
||||
// implementation are:
|
||||
//
|
||||
// - Values and fields are immutable with RAII semantics. The only type of
|
||||
|
@ -84,6 +84,12 @@ struct BSON
|
|||
recursive context for the error, which helps with analysis. */
|
||||
static BSON parseDocumentFromFile(FILE *fp, bool *error, bool log);
|
||||
|
||||
/* Load a file. The file should be a document. If a `expectedType` is
|
||||
provided, the document should have a field "*" with that value. Return
|
||||
a Null value in case of error. */
|
||||
static BSON loadDocumentFromFile(std::string path, bool log, bool mustExist,
|
||||
char const *expectedType = nullptr);
|
||||
|
||||
/* Constructors */
|
||||
|
||||
static BSON mkDouble(double d)
|
||||
|
@ -140,6 +146,8 @@ struct BSON
|
|||
in the heap. */
|
||||
static BSON mkDocumentFromFieldArray(BSONField *fields, size_t count);
|
||||
|
||||
/* Construct an array with count null values (which can be assigned). */
|
||||
static BSON mkArray(size_t count);
|
||||
/* Construct an array by moving every value from the array without taking
|
||||
ownership of the array. */
|
||||
static BSON mkArrayFromValues(BSON *values, size_t count);
|
||||
|
@ -153,9 +161,10 @@ struct BSON
|
|||
region, which must be in the heap. */
|
||||
static BSON mkBinaryMove(int subtype, u8 *data, size_t size);
|
||||
|
||||
/* Construct a string by copying the input. */
|
||||
static BSON mkString(std::string const &str);
|
||||
/* Construct a string by copying the input. */
|
||||
static BSON mkStringCopy(char const *str, int len = -1);
|
||||
static BSON mkStringCopy(std::string const &str);
|
||||
/* Construct a string by taking ownership of the provided buffer, which
|
||||
must be NUL-terminated and in the heap. */
|
||||
static BSON mkStringMove(char *str);
|
||||
|
@ -255,6 +264,11 @@ struct BSON
|
|||
char const *getStringReadOnly() const;
|
||||
/* Get a copy of the NUL-terminated string, malloc() allocated */
|
||||
char *getStringCopy() const;
|
||||
/* Get a copy of the NUL-terminated string */
|
||||
std::string getString() const
|
||||
{
|
||||
return std::string(getStringReadOnly());
|
||||
}
|
||||
|
||||
/* Document/array size */
|
||||
uint size() const
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
//---
|
||||
|
||||
#include <fxos/util/bson.h>
|
||||
#include <fxos/util/log.h>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
@ -445,6 +446,43 @@ BSON BSON::parseDocumentFromFile(FILE *fp, bool *error, bool log)
|
|||
return v;
|
||||
}
|
||||
|
||||
BSON BSON::loadDocumentFromFile(
|
||||
std::string path, bool log, bool mustExist, char const *expectedType)
|
||||
{
|
||||
FILE *fp = fopen(path.c_str(), "r");
|
||||
if(!fp) {
|
||||
if(mustExist && log)
|
||||
FxOS_log(ERR, "Cannot read '%s': %m", path.c_str());
|
||||
return mkNull();
|
||||
}
|
||||
|
||||
bool e;
|
||||
BSON v = parseDocumentFromFile(fp, &e, log);
|
||||
fclose(fp);
|
||||
if(!e) {
|
||||
if(log)
|
||||
FxOS_log(ERR, "Failed to parse '%s'", path.c_str());
|
||||
return mkNull();
|
||||
}
|
||||
|
||||
if(!v.isDocument()) {
|
||||
if(log)
|
||||
FxOS_log(ERR, "Contents of '%s' is not a document", path.c_str());
|
||||
return mkNull();
|
||||
}
|
||||
|
||||
if(expectedType
|
||||
&& !(v.hasField("*") && v["*"].isString()
|
||||
&& v["*"].getString() == std::string(expectedType))) {
|
||||
if(log)
|
||||
FxOS_log(ERR, "Contents of '%s' do not have expected type %s",
|
||||
path.c_str(), expectedType);
|
||||
return mkNull();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#undef LOG
|
||||
|
||||
BSON BSON::mkDocument(
|
||||
|
@ -486,6 +524,18 @@ BSON BSON::mkDocumentFromFieldArray(BSONField *fields, size_t count)
|
|||
return v;
|
||||
}
|
||||
|
||||
BSON BSON::mkArray(size_t count)
|
||||
{
|
||||
BSON *values = static_cast<BSON *>(malloc(count * sizeof *values));
|
||||
if(!values)
|
||||
throw std::bad_alloc {};
|
||||
|
||||
for(uint i = 0; i < count; i++)
|
||||
values[i] = mkNull();
|
||||
|
||||
return mkArrayFromValueArray(values, count);
|
||||
}
|
||||
|
||||
BSON BSON::mkArrayFromValues(BSON *values_ro, size_t count)
|
||||
{
|
||||
BSON *values = static_cast<BSON *>(malloc(count * sizeof *values));
|
||||
|
@ -546,7 +596,7 @@ BSON BSON::mkStringCopy(char const *str, int len)
|
|||
return v;
|
||||
}
|
||||
|
||||
BSON BSON::mkStringCopy(std::string const &str)
|
||||
BSON BSON::mkString(std::string const &str)
|
||||
{
|
||||
BSON v;
|
||||
v.m_type = Type::String;
|
||||
|
|
Loading…
Reference in New Issue