mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-05-17 19:31:35 +02:00
Builder::settings_
We use Json::Value to configure the builders so we can maintain binary-compatibility easily.
This commit is contained in:
parent
694dbcb328
commit
a9e1ab302d
@ -92,13 +92,13 @@ features without losing binary-compatibility.
|
|||||||
\code
|
\code
|
||||||
// For convenience, use `writeString()` with a specialized builder.
|
// For convenience, use `writeString()` with a specialized builder.
|
||||||
Json::StreamWriterBuilder wbuilder;
|
Json::StreamWriterBuilder wbuilder;
|
||||||
wbuilder.settings["indentation"] = "\t";
|
wbuilder.settings_["indentation"] = "\t";
|
||||||
std::string document = Json::writeString(wbuilder, root);
|
std::string document = Json::writeString(wbuilder, root);
|
||||||
|
|
||||||
// Here, using a specialized Builder, we discard comments and
|
// Here, using a specialized Builder, we discard comments and
|
||||||
// record errors as we parse.
|
// record errors as we parse.
|
||||||
Json::CharReaderBuilder rbuilder;
|
Json::CharReaderBuilder rbuilder;
|
||||||
rbuilder.settings["collectComments"] = false;
|
rbuilder.settings_["collectComments"] = false;
|
||||||
std::string errs;
|
std::string errs;
|
||||||
bool ok = Json::parseFromStream(rbuilder, std::cin, &root, &errs);
|
bool ok = Json::parseFromStream(rbuilder, std::cin, &root, &errs);
|
||||||
\endcode
|
\endcode
|
||||||
|
@ -270,7 +270,9 @@ public:
|
|||||||
|
|
||||||
class Factory {
|
class Factory {
|
||||||
public:
|
public:
|
||||||
/// \brief Allocate a CharReader via operator new().
|
/** \brief Allocate a CharReader via operator new().
|
||||||
|
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||||
|
*/
|
||||||
virtual CharReader* newCharReader() const = 0;
|
virtual CharReader* newCharReader() const = 0;
|
||||||
}; // Factory
|
}; // Factory
|
||||||
}; // CharReader
|
}; // CharReader
|
||||||
@ -283,29 +285,39 @@ Usage:
|
|||||||
\code
|
\code
|
||||||
using namespace Json;
|
using namespace Json;
|
||||||
CharReaderBuilder builder;
|
CharReaderBuilder builder;
|
||||||
builder.collectComments_ = false;
|
builder.settings_["collectComments"] = false;
|
||||||
Value value;
|
Value value;
|
||||||
std::string errs;
|
std::string errs;
|
||||||
bool ok = parseFromStream(builder, std::cin, &value, &errs);
|
bool ok = parseFromStream(builder, std::cin, &value, &errs);
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
class CharReaderBuilder : public CharReader::Factory {
|
class JSON_API CharReaderBuilder : public CharReader::Factory {
|
||||||
public:
|
public:
|
||||||
/** default: true
|
// Note: We use a Json::Value so that we can add data-members to this class
|
||||||
*
|
// without a major version bump.
|
||||||
* It is possible to "allow" comments but still not "collect" them.
|
/** Configuration of this builder.
|
||||||
|
Available settings (case-sensitive):
|
||||||
|
- "collectComments": false or true (default=true)
|
||||||
|
- TODO: other features ...
|
||||||
|
But don't trust these docs. You can examine 'settings_` yourself
|
||||||
|
to see the defaults. You can also write and read them just like any
|
||||||
|
JSON Value.
|
||||||
*/
|
*/
|
||||||
bool collectComments_;
|
Json::Value settings_;
|
||||||
/** default: all()
|
|
||||||
*
|
|
||||||
* For historical reasons, Features is a separate structure.
|
|
||||||
*/
|
|
||||||
Features features_;
|
|
||||||
|
|
||||||
CharReaderBuilder();
|
CharReaderBuilder();
|
||||||
virtual ~CharReaderBuilder();
|
virtual ~CharReaderBuilder();
|
||||||
|
|
||||||
virtual CharReader* newCharReader() const;
|
virtual CharReader* newCharReader() const;
|
||||||
|
|
||||||
|
/** \return true if 'settings' are illegal and consistent;
|
||||||
|
* otherwise, indicate bad settings via 'invalid'.
|
||||||
|
*/
|
||||||
|
bool validate(Json::Value* invalid) const;
|
||||||
|
/** Called by ctor, but you can use this to reset settings_.
|
||||||
|
* \pre 'settings' != NULL (but Json::null is fine)
|
||||||
|
*/
|
||||||
|
static void setDefaults(Json::Value* settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Consume entire stream and use its begin/end.
|
/** Consume entire stream and use its begin/end.
|
||||||
|
@ -64,7 +64,10 @@ public:
|
|||||||
class JSON_API Factory {
|
class JSON_API Factory {
|
||||||
public:
|
public:
|
||||||
virtual ~Factory();
|
virtual ~Factory();
|
||||||
/// Do not take ownership of sout, but maintain a reference.
|
/** \brief Allocate a CharReader via operator new().
|
||||||
|
* Do not take ownership of sout, but maintain a reference.
|
||||||
|
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||||
|
*/
|
||||||
virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0;
|
virtual StreamWriter* newStreamWriter(std::ostream* sout) const = 0;
|
||||||
}; // Factory
|
}; // Factory
|
||||||
}; // StreamWriter
|
}; // StreamWriter
|
||||||
@ -77,41 +80,49 @@ std::string writeString(StreamWriter::Factory const& factory, Value const& root)
|
|||||||
|
|
||||||
/** \brief Build a StreamWriter implementation.
|
/** \brief Build a StreamWriter implementation.
|
||||||
|
|
||||||
\deprecated This is experimental and will be altered before the next release.
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
\code
|
\code
|
||||||
using namespace Json;
|
using namespace Json;
|
||||||
Value value = ...;
|
Value value = ...;
|
||||||
StreamWriterBuilder builder;
|
StreamWriterBuilder builder;
|
||||||
builder.cs_ = StreamWriter::CommentStyle::None;
|
builder.settings_["commentStyle"] = "None";
|
||||||
builder.indentation_ = " "; // or whatever you like
|
builder.settings_["indentation"] = " "; // or whatever you like
|
||||||
|
std::unique_ptr<Json::StreamWriter> writer(
|
||||||
|
builder.newStreamWriter(&std::cout));
|
||||||
writer->write(value);
|
writer->write(value);
|
||||||
std::cout << std::endl; // add lf and flush
|
std::cout << std::endl; // add lf and flush
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
|
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
|
||||||
public:
|
public:
|
||||||
// Note: We cannot add data-members to this class without a major version bump.
|
// Note: We use a Json::Value so that we can add data-members to this class
|
||||||
// So these might as well be completely exposed.
|
// without a major version bump.
|
||||||
|
/** Configuration of this builder.
|
||||||
/** \brief How to write comments.
|
Available settings (case-sensitive):
|
||||||
* Default: All
|
- "commentStyle": "None", "Some", or "All" (default="All")
|
||||||
|
- "indentation": (default="\t")
|
||||||
|
But don't trust these docs. You can examine 'settings_` yourself
|
||||||
|
to see the defaults. You can also write and read them just like any
|
||||||
|
JSON Value.
|
||||||
*/
|
*/
|
||||||
StreamWriter::CommentStyle::Enum cs_;
|
Json::Value settings_;
|
||||||
/** \brief Write in human-friendly style.
|
|
||||||
|
|
||||||
If "", then skip all indentation and newlines.
|
|
||||||
In that case, you probably want CommentStyle::None also.
|
|
||||||
Default: "\t"
|
|
||||||
*/
|
|
||||||
std::string indentation_;
|
|
||||||
|
|
||||||
StreamWriterBuilder();
|
StreamWriterBuilder();
|
||||||
virtual ~StreamWriterBuilder();
|
virtual ~StreamWriterBuilder();
|
||||||
|
|
||||||
/// Do not take ownership of sout, but maintain a reference.
|
/** Do not take ownership of sout, but maintain a reference.
|
||||||
|
* \throw std::exception if something goes wrong (e.g. invalid settings)
|
||||||
|
*/
|
||||||
virtual StreamWriter* newStreamWriter(std::ostream* sout) const;
|
virtual StreamWriter* newStreamWriter(std::ostream* sout) const;
|
||||||
|
|
||||||
|
/** \return true if 'settings' are illegal and consistent;
|
||||||
|
* otherwise, indicate bad settings via 'invalid'.
|
||||||
|
*/
|
||||||
|
bool validate(Json::Value* invalid) const;
|
||||||
|
/** Called by ctor, but you can use this to reset settings_.
|
||||||
|
* \pre 'settings' != NULL (but Json::null is fine)
|
||||||
|
*/
|
||||||
|
static void setDefaults(Json::Value* settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Build a StreamWriter implementation.
|
/** \brief Build a StreamWriter implementation.
|
||||||
@ -126,6 +137,8 @@ public:
|
|||||||
* w->write(value);
|
* w->write(value);
|
||||||
* delete w;
|
* delete w;
|
||||||
* \endcode
|
* \endcode
|
||||||
|
*
|
||||||
|
* \deprecated Use StreamWriterBuilder
|
||||||
*/
|
*/
|
||||||
class JSON_API OldCompressingStreamWriterBuilder : public StreamWriter::Factory
|
class JSON_API OldCompressingStreamWriterBuilder : public StreamWriter::Factory
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <istream>
|
#include <istream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
|
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@ -912,14 +913,48 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CharReaderBuilder::CharReaderBuilder()
|
CharReaderBuilder::CharReaderBuilder()
|
||||||
: collectComments_(true)
|
{
|
||||||
, features_(Features::all())
|
setDefaults(&settings_);
|
||||||
{}
|
}
|
||||||
CharReaderBuilder::~CharReaderBuilder()
|
CharReaderBuilder::~CharReaderBuilder()
|
||||||
{}
|
{}
|
||||||
CharReader* CharReaderBuilder::newCharReader() const
|
CharReader* CharReaderBuilder::newCharReader() const
|
||||||
{
|
{
|
||||||
return new OldReader(collectComments_, features_);
|
if (!validate(NULL)) throw std::runtime_error("invalid settings");
|
||||||
|
// TODO: Maybe serialize the invalid settings into the exception.
|
||||||
|
|
||||||
|
bool collectComments = settings_["collectComments"].asBool();
|
||||||
|
Features features = Features::all();
|
||||||
|
// TODO: Fill in features.
|
||||||
|
return new OldReader(collectComments, features);
|
||||||
|
}
|
||||||
|
static void getValidReaderKeys(std::set<std::string>* valid_keys)
|
||||||
|
{
|
||||||
|
valid_keys->clear();
|
||||||
|
valid_keys->insert("collectComments");
|
||||||
|
}
|
||||||
|
bool CharReaderBuilder::validate(Json::Value* invalid) const
|
||||||
|
{
|
||||||
|
Json::Value my_invalid;
|
||||||
|
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
|
||||||
|
Json::Value& inv = *invalid;
|
||||||
|
bool valid = true;
|
||||||
|
std::set<std::string> valid_keys;
|
||||||
|
getValidReaderKeys(&valid_keys);
|
||||||
|
Value::Members keys = settings_.getMemberNames();
|
||||||
|
size_t n = keys.size();
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
std::string const& key = keys[i];
|
||||||
|
if (valid_keys.find(key) == valid_keys.end()) {
|
||||||
|
inv[key] = settings_[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
// static
|
||||||
|
void CharReaderBuilder::setDefaults(Json::Value* settings)
|
||||||
|
{
|
||||||
|
(*settings)["collectComments"] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <set>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -950,23 +951,67 @@ StreamWriter::~StreamWriter()
|
|||||||
StreamWriter::Factory::~Factory()
|
StreamWriter::Factory::~Factory()
|
||||||
{}
|
{}
|
||||||
StreamWriterBuilder::StreamWriterBuilder()
|
StreamWriterBuilder::StreamWriterBuilder()
|
||||||
: cs_(StreamWriter::CommentStyle::All)
|
{
|
||||||
, indentation_("\t")
|
setDefaults(&settings_);
|
||||||
{}
|
}
|
||||||
StreamWriterBuilder::~StreamWriterBuilder()
|
StreamWriterBuilder::~StreamWriterBuilder()
|
||||||
{}
|
{}
|
||||||
StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
|
StreamWriter* StreamWriterBuilder::newStreamWriter(std::ostream* stream) const
|
||||||
{
|
{
|
||||||
|
if (!validate(NULL)) throw std::runtime_error("invalid settings");
|
||||||
|
// TODO: Maybe serialize the invalid settings into the exception.
|
||||||
|
|
||||||
|
std::string indentation = settings_["indentation"].asString();
|
||||||
|
std::string cs_str = settings_["commentStyle"].asString();
|
||||||
|
StreamWriter::CommentStyle::Enum cs = StreamWriter::CommentStyle::All;
|
||||||
|
if (cs_str == "All") {
|
||||||
|
cs = StreamWriter::CommentStyle::All;
|
||||||
|
} else if (cs_str == "None") {
|
||||||
|
cs = StreamWriter::CommentStyle::None;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
std::string colonSymbol = " : ";
|
std::string colonSymbol = " : ";
|
||||||
if (indentation_.empty()) {
|
if (indentation.empty()) {
|
||||||
colonSymbol = ":";
|
colonSymbol = ":";
|
||||||
}
|
}
|
||||||
std::string nullSymbol = "null";
|
std::string nullSymbol = "null";
|
||||||
std::string endingLineFeedSymbol = "";
|
std::string endingLineFeedSymbol = "";
|
||||||
return new BuiltStyledStreamWriter(stream,
|
return new BuiltStyledStreamWriter(stream,
|
||||||
indentation_, cs_,
|
indentation, cs,
|
||||||
colonSymbol, nullSymbol, endingLineFeedSymbol);
|
colonSymbol, nullSymbol, endingLineFeedSymbol);
|
||||||
}
|
}
|
||||||
|
static void getValidWriterKeys(std::set<std::string>* valid_keys)
|
||||||
|
{
|
||||||
|
valid_keys->clear();
|
||||||
|
valid_keys->insert("indentation");
|
||||||
|
valid_keys->insert("commentStyle");
|
||||||
|
}
|
||||||
|
bool StreamWriterBuilder::validate(Json::Value* invalid) const
|
||||||
|
{
|
||||||
|
Json::Value my_invalid;
|
||||||
|
if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
|
||||||
|
Json::Value& inv = *invalid;
|
||||||
|
bool valid = true;
|
||||||
|
std::set<std::string> valid_keys;
|
||||||
|
getValidWriterKeys(&valid_keys);
|
||||||
|
Value::Members keys = settings_.getMemberNames();
|
||||||
|
size_t n = keys.size();
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
std::string const& key = keys[i];
|
||||||
|
if (valid_keys.find(key) == valid_keys.end()) {
|
||||||
|
inv[key] = settings_[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
// static
|
||||||
|
void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
||||||
|
{
|
||||||
|
(*settings)["commentStyle"] = "All";
|
||||||
|
(*settings)["indentation"] = "\t";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// This might become public someday.
|
// This might become public someday.
|
||||||
class StreamWriterBuilderFactory {
|
class StreamWriterBuilderFactory {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user