Commit 7dbf6903 authored by Pavlo Kushnir's avatar Pavlo Kushnir Committed by Facebook Github Bot 8

Use std::string in folly::dynamic

Summary: Why not kill fbstring entirely? There are some legitimate use cases. For example, `folly::IOBuf` supports `moveToFbstring()` method which is impossible to implement with `std::string`.

Reviewed By: joeg, snarkmaster

Differential Revision: D3189410

fb-gh-sync-id: 9bb9090ca6012ac32ba9fb79041b26ec4888781f
fbshipit-source-id: 9bb9090ca6012ac32ba9fb79041b26ec4888781f
parent 43d56a22
......@@ -243,7 +243,7 @@ struct DynamicConverter<folly::fbstring> {
template <>
struct DynamicConverter<std::string> {
static std::string convert(const dynamic& d) {
return d.asString().toStdString();
return d.asString();
}
};
......
......@@ -20,8 +20,8 @@ namespace folly {
//////////////////////////////////////////////////////////////////////
fbstring codePointToUtf8(char32_t cp) {
fbstring result;
std::string codePointToUtf8(char32_t cp) {
std::string result;
// Based on description from http://en.wikipedia.org/wiki/UTF-8.
......
......@@ -18,7 +18,7 @@
#pragma once
#include <folly/FBString.h>
#include <string>
namespace folly {
......@@ -29,7 +29,7 @@ namespace folly {
*
* Return value is undefined if `cp' is an invalid code point.
*/
fbstring codePointToUtf8(char32_t cp);
std::string codePointToUtf8(char32_t cp);
//////////////////////////////////////////////////////////////////////
......
......@@ -40,18 +40,35 @@ struct hash< ::folly::dynamic> {
// This is a higher-order preprocessor macro to aid going from runtime
// types to the compile time type system.
#define FB_DYNAMIC_APPLY(type, apply) do { \
switch ((type)) { \
case NULLT: apply(void*); break; \
case ARRAY: apply(Array); break; \
case BOOL: apply(bool); break; \
case DOUBLE: apply(double); break; \
case INT64: apply(int64_t); break; \
case OBJECT: apply(ObjectImpl); break; \
case STRING: apply(fbstring); break; \
default: CHECK(0); abort(); \
} \
} while (0)
#define FB_DYNAMIC_APPLY(type, apply) \
do { \
switch ((type)) { \
case NULLT: \
apply(void*); \
break; \
case ARRAY: \
apply(Array); \
break; \
case BOOL: \
apply(bool); \
break; \
case DOUBLE: \
apply(double); \
break; \
case INT64: \
apply(int64_t); \
break; \
case OBJECT: \
apply(ObjectImpl); \
break; \
case STRING: \
apply(std::string); \
break; \
default: \
CHECK(0); \
abort(); \
} \
} while (0)
//////////////////////////////////////////////////////////////////////
......@@ -271,31 +288,23 @@ inline dynamic::dynamic(ObjectMaker (*)())
inline dynamic::dynamic(StringPiece s)
: type_(STRING)
{
new (&u_.string) fbstring(s.data(), s.size());
new (&u_.string) std::string(s.data(), s.size());
}
inline dynamic::dynamic(char const* s)
: type_(STRING)
{
new (&u_.string) fbstring(s);
new (&u_.string) std::string(s);
}
inline dynamic::dynamic(std::string const& s)
: type_(STRING)
{
new (&u_.string) fbstring(s);
new (&u_.string) std::string(s);
}
inline dynamic::dynamic(fbstring const& s)
: type_(STRING)
{
new (&u_.string) fbstring(s);
}
inline dynamic::dynamic(fbstring&& s)
: type_(STRING)
{
new (&u_.string) fbstring(std::move(s));
inline dynamic::dynamic(std::string&& s) : type_(STRING) {
new (&u_.string) std::string(std::move(s));
}
inline dynamic::dynamic(std::initializer_list<dynamic> il)
......@@ -391,7 +400,9 @@ inline dynamic::IterableProxy<dynamic::const_item_iterator> dynamic::items()
return &(get<ObjectImpl>());
}
inline bool dynamic::isString() const { return get_nothrow<fbstring>(); }
inline bool dynamic::isString() const {
return get_nothrow<std::string>();
}
inline bool dynamic::isObject() const { return get_nothrow<ObjectImpl>(); }
inline bool dynamic::isBool() const { return get_nothrow<bool>(); }
inline bool dynamic::isArray() const { return get_nothrow<Array>(); }
......@@ -404,29 +415,49 @@ inline dynamic::Type dynamic::type() const {
return type_;
}
inline fbstring dynamic::asString() const { return asImpl<fbstring>(); }
inline double dynamic::asDouble() const { return asImpl<double>(); }
inline int64_t dynamic::asInt() const { return asImpl<int64_t>(); }
inline bool dynamic::asBool() const { return asImpl<bool>(); }
inline std::string dynamic::asString() const {
return asImpl<std::string>();
}
inline double dynamic::asDouble() const {
return asImpl<double>();
}
inline int64_t dynamic::asInt() const {
return asImpl<int64_t>();
}
inline bool dynamic::asBool() const {
return asImpl<bool>();
}
inline const fbstring& dynamic::getString() const& { return get<fbstring>(); }
inline const std::string& dynamic::getString() const& {
return get<std::string>();
}
inline double dynamic::getDouble() const& { return get<double>(); }
inline int64_t dynamic::getInt() const& { return get<int64_t>(); }
inline bool dynamic::getBool() const& { return get<bool>(); }
inline fbstring& dynamic::getString() & { return get<fbstring>(); }
inline std::string& dynamic::getString()& {
return get<std::string>();
}
inline double& dynamic::getDouble() & { return get<double>(); }
inline int64_t& dynamic::getInt() & { return get<int64_t>(); }
inline bool& dynamic::getBool() & { return get<bool>(); }
inline fbstring dynamic::getString() && { return std::move(get<fbstring>()); }
inline std::string dynamic::getString()&& {
return std::move(get<std::string>());
}
inline double dynamic::getDouble() && { return get<double>(); }
inline int64_t dynamic::getInt() && { return get<int64_t>(); }
inline bool dynamic::getBool() && { return get<bool>(); }
inline const char* dynamic::data() const& { return get<fbstring>().data(); }
inline const char* dynamic::c_str() const& { return get<fbstring>().c_str(); }
inline StringPiece dynamic::stringPiece() const { return get<fbstring>(); }
inline const char* dynamic::data() const& {
return get<std::string>().data();
}
inline const char* dynamic::c_str() const& {
return get<std::string>().c_str();
}
inline StringPiece dynamic::stringPiece() const {
return get<std::string>();
}
template<class T>
struct dynamic::CompareOp {
......@@ -442,7 +473,7 @@ struct dynamic::CompareOp<dynamic::ObjectImpl> {
inline dynamic& dynamic::operator+=(dynamic const& o) {
if (type() == STRING && o.type() == STRING) {
*getAddress<fbstring>() += *o.getAddress<fbstring>();
*getAddress<std::string>() += *o.getAddress<std::string>();
return *this;
}
*this = detail::numericOp<std::plus>(*this, o);
......@@ -646,7 +677,7 @@ inline void dynamic::pop_back() {
FOLLY_DYNAMIC_DEC_TYPEINFO(void*, "null", dynamic::NULLT)
FOLLY_DYNAMIC_DEC_TYPEINFO(bool, "boolean", dynamic::BOOL)
FOLLY_DYNAMIC_DEC_TYPEINFO(fbstring, "string", dynamic::STRING)
FOLLY_DYNAMIC_DEC_TYPEINFO(std::string, "string", dynamic::STRING)
FOLLY_DYNAMIC_DEC_TYPEINFO(dynamic::Array, "array", dynamic::ARRAY)
FOLLY_DYNAMIC_DEC_TYPEINFO(double, "double", dynamic::DOUBLE)
FOLLY_DYNAMIC_DEC_TYPEINFO(int64_t, "int64", dynamic::INT64)
......@@ -660,7 +691,8 @@ T dynamic::asImpl() const {
case INT64: return to<T>(*get_nothrow<int64_t>());
case DOUBLE: return to<T>(*get_nothrow<double>());
case BOOL: return to<T>(*get_nothrow<bool>());
case STRING: return to<T>(*get_nothrow<fbstring>());
case STRING:
return to<T>(*get_nothrow<std::string>());
default:
throw TypeError("int/double/bool/string", type());
}
......@@ -708,8 +740,11 @@ template<> struct dynamic::GetAddrImpl<int64_t> {
template<> struct dynamic::GetAddrImpl<double> {
static double* get(Data& d) noexcept { return &d.doubl; }
};
template<> struct dynamic::GetAddrImpl<fbstring> {
static fbstring* get(Data& d) noexcept { return &d.string; }
template <>
struct dynamic::GetAddrImpl<std::string> {
static std::string* get(Data& d) noexcept {
return &d.string;
}
};
template<> struct dynamic::GetAddrImpl<dynamic::ObjectImpl> {
static_assert(sizeof(ObjectImpl) <= sizeof(Data::objectBuffer),
......@@ -807,7 +842,7 @@ class FormatValue<dynamic> {
FormatValue<int64_t>(val_.asInt()).format(arg, cb);
break;
case dynamic::STRING:
FormatValue<fbstring>(val_.asString()).format(arg, cb);
FormatValue<std::string>(val_.asString()).format(arg, cb);
break;
case dynamic::DOUBLE:
FormatValue<double>(val_.asDouble()).format(arg, cb);
......@@ -816,7 +851,7 @@ class FormatValue<dynamic> {
FormatValue(val_.at(arg.splitIntKey())).format(arg, cb);
break;
case dynamic::OBJECT:
FormatValue(val_.at(arg.splitKey().toFbstring())).format(arg, cb);
FormatValue(val_.at(arg.splitKey().toString())).format(arg, cb);
break;
}
}
......
......@@ -15,6 +15,7 @@
*/
#include <folly/dynamic.h>
#include <folly/Hash.h>
namespace folly {
......@@ -27,7 +28,7 @@ namespace folly {
FOLLY_DYNAMIC_DEF_TYPEINFO(void*)
FOLLY_DYNAMIC_DEF_TYPEINFO(bool)
FOLLY_DYNAMIC_DEF_TYPEINFO(fbstring)
FOLLY_DYNAMIC_DEF_TYPEINFO(std::string)
FOLLY_DYNAMIC_DEF_TYPEINFO(dynamic::Array)
FOLLY_DYNAMIC_DEF_TYPEINFO(double)
FOLLY_DYNAMIC_DEF_TYPEINFO(int64_t)
......@@ -57,18 +58,35 @@ TypeError::~TypeError() = default;
// This is a higher-order preprocessor macro to aid going from runtime
// types to the compile time type system.
#define FB_DYNAMIC_APPLY(type, apply) do { \
switch ((type)) { \
case NULLT: apply(void*); break; \
case ARRAY: apply(Array); break; \
case BOOL: apply(bool); break; \
case DOUBLE: apply(double); break; \
case INT64: apply(int64_t); break; \
case OBJECT: apply(ObjectImpl); break; \
case STRING: apply(fbstring); break; \
default: CHECK(0); abort(); \
} \
} while (0)
#define FB_DYNAMIC_APPLY(type, apply) \
do { \
switch ((type)) { \
case NULLT: \
apply(void*); \
break; \
case ARRAY: \
apply(Array); \
break; \
case BOOL: \
apply(bool); \
break; \
case DOUBLE: \
apply(double); \
break; \
case INT64: \
apply(int64_t); \
break; \
case OBJECT: \
apply(ObjectImpl); \
break; \
case STRING: \
apply(std::string); \
break; \
default: \
CHECK(0); \
abort(); \
} \
} while (0)
bool dynamic::operator<(dynamic const& o) const {
if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) {
......@@ -227,7 +245,7 @@ std::size_t dynamic::size() const {
if (auto* obj = get_nothrow<ObjectImpl>()) {
return obj->size();
}
if (auto* str = get_nothrow<fbstring>()) {
if (auto* str = get_nothrow<std::string>()) {
return str->size();
}
throw TypeError("array/object", type());
......@@ -248,13 +266,16 @@ std::size_t dynamic::hash() const {
case NULLT:
throw TypeError("not null/object/array", type());
case INT64:
return std::hash<int64_t>()(asInt());
return std::hash<int64_t>()(getInt());
case DOUBLE:
return std::hash<double>()(asDouble());
return std::hash<double>()(getDouble());
case BOOL:
return std::hash<bool>()(asBool());
case STRING:
return std::hash<fbstring>()(asString());
return std::hash<bool>()(getBool());
case STRING: {
// keep it compatible with FBString
const auto& str = getString();
return ::folly::hash::fnv32_buf(str.data(), str.size());
}
default:
CHECK(0); abort();
}
......
......@@ -74,7 +74,6 @@
#include <boost/operators.hpp>
#include <folly/FBString.h>
#include <folly/Range.h>
#include <folly/Traits.h>
......@@ -157,8 +156,7 @@ public:
/* implicit */ dynamic(StringPiece val);
/* implicit */ dynamic(char const* val);
/* implicit */ dynamic(std::string const& val);
/* implicit */ dynamic(fbstring const& val);
/* implicit */ dynamic(fbstring&& val);
/* implicit */ dynamic(std::string&& val);
/*
* This is part of the plumbing for array() and object(), above.
......@@ -291,7 +289,7 @@ public:
* since arrays and objects are generally best dealt with as a
* dynamic.
*/
fbstring asString() const;
std::string asString() const;
double asDouble() const;
int64_t asInt() const;
bool asBool() const;
......@@ -301,15 +299,15 @@ public:
*
* These will throw a TypeError if the dynamic has a different type.
*/
const fbstring& getString() const&;
const std::string& getString() const&;
double getDouble() const&;
int64_t getInt() const&;
bool getBool() const&;
fbstring& getString() &;
std::string& getString() &;
double& getDouble() &;
int64_t& getInt() &;
bool& getBool() &;
fbstring getString() &&;
std::string getString() &&;
double getDouble() &&;
int64_t getInt() &&;
bool getBool() &&;
......@@ -566,7 +564,7 @@ private:
bool boolean;
double doubl;
int64_t integer;
fbstring string;
std::string string;
/*
* Objects are placement new'd here. We have to use a char buffer
......
......@@ -125,7 +125,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
// std::string
template <typename Fn> EnableForArgTypes<Fn, std::string>
invokeForKeyValue(Fn fn, const folly::dynamic&, const folly::dynamic& v) {
fn(v.asString().toStdString());
fn(v.asString());
}
//
......@@ -157,7 +157,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
// folly::dynamic, std::string
template <typename Fn> EnableForArgTypes<Fn, folly::dynamic, std::string>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k, v.asString().toStdString());
fn(k, v.asString());
}
// Convert the key to std::string.
......@@ -165,27 +165,27 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
// std::string, folly::dynamic (no conversion of value)
template <typename Fn> EnableForArgTypes<Fn, std::string, folly::dynamic>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asString().toStdString(), v);
fn(k.asString(), v);
}
// std::string, int64_t
template <typename Fn> EnableForArgTypes<Fn, std::string, int64_t>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asString().toStdString(), v.asInt());
fn(k.asString(), v.asInt());
}
// std::string, bool
template <typename Fn> EnableForArgTypes<Fn, std::string, bool>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asString().toStdString(), v.asBool());
fn(k.asString(), v.asBool());
}
// std::string, double
template <typename Fn> EnableForArgTypes<Fn, std::string, double>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asString().toStdString(), v.asDouble());
fn(k.asString(), v.asDouble());
}
// std::string, std::string
template <typename Fn> EnableForArgTypes<Fn, std::string, std::string>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asString().toStdString(), v.asString().toStdString());
fn(k.asString(), v.asString());
}
// Convert the key to int64_t (good for arrays).
......@@ -213,7 +213,7 @@ invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
// int64_t, std::string
template <typename Fn> EnableForArgTypes<Fn, int64_t, std::string>
invokeForKeyValue(Fn fn, const folly::dynamic& k, const folly::dynamic& v) {
fn(k.asInt(), v.asString().toStdString());
fn(k.asInt(), v.asString());
}
} // namespace detail
......
......@@ -97,7 +97,7 @@ namespace folly {
* NB: The key alone should be rarely needed, but these callback styles
* provide it with no conversion overhead, and only minimal verbosity:
* [&](const std::string& k, const folly::dynamic&) {}
* [&]() { auto k = p.key().asString().toStdString(); }
* [&]() { auto k = p.key().asString(); }
*
* == How `releaseErrors()` can make your parse lossless ==
*
......
......@@ -95,7 +95,7 @@ struct SchemaValidatorContext final {
explicit SchemaValidatorContext(const dynamic& s) : schema(s) {}
const dynamic& schema;
std::unordered_map<fbstring, IValidator*> refs;
std::unordered_map<std::string, IValidator*> refs;
};
/**
......@@ -231,7 +231,7 @@ struct SizeValidator final : IValidator {
struct StringPatternValidator final : IValidator {
explicit StringPatternValidator(const dynamic& schema) {
if (schema.isString()) {
regex_ = boost::regex(schema.getString().toStdString());
regex_ = boost::regex(schema.getString());
}
}
......@@ -240,7 +240,7 @@ struct StringPatternValidator final : IValidator {
if (!value.isString() || regex_.empty()) {
return none;
}
if (!boost::regex_search(value.getString().toStdString(), regex_)) {
if (!boost::regex_search(value.getString(), regex_)) {
return makeError("string matching regex", value);
}
return none;
......@@ -360,7 +360,7 @@ struct RequiredValidator final : IValidator {
}
private:
std::vector<fbstring> properties_;
std::vector<std::string> properties_;
};
struct PropertiesValidator final : IValidator {
......@@ -381,7 +381,7 @@ struct PropertiesValidator final : IValidator {
for (const auto& pair : patternProperties->items()) {
if (pair.first.isString()) {
patternPropertyValidators_.emplace_back(
boost::regex(pair.first.getString().toStdString()),
boost::regex(pair.first.getString()),
SchemaValidator::make(context, pair.second));
}
}
......@@ -405,7 +405,7 @@ struct PropertiesValidator final : IValidator {
if (!pair.first.isString()) {
continue;
}
const fbstring& key = pair.first.getString();
const std::string& key = pair.first.getString();
auto it = propertyValidators_.find(key);
bool matched = false;
if (it != propertyValidators_.end()) {
......@@ -415,7 +415,7 @@ struct PropertiesValidator final : IValidator {
matched = true;
}
const std::string& strkey = key.toStdString();
const std::string& strkey = key;
for (const auto& ppv : patternPropertyValidators_) {
if (boost::regex_search(strkey, ppv.first)) {
if (auto se = vc.validate(ppv.second.get(), pair.second)) {
......@@ -440,7 +440,8 @@ struct PropertiesValidator final : IValidator {
return none;
}
std::unordered_map<fbstring, std::unique_ptr<IValidator>> propertyValidators_;
std::unordered_map<std::string, std::unique_ptr<IValidator>>
propertyValidators_;
std::vector<std::pair<boost::regex, std::unique_ptr<IValidator>>>
patternPropertyValidators_;
std::unique_ptr<IValidator> additionalPropertyValidator_;
......@@ -457,7 +458,7 @@ struct DependencyValidator final : IValidator {
continue;
}
if (pair.second.isArray()) {
auto p = make_pair(pair.first.getString(), std::vector<fbstring>());
auto p = make_pair(pair.first.getString(), std::vector<std::string>());
for (const auto& item : pair.second) {
if (item.isString()) {
p.second.push_back(item.getString());
......@@ -496,8 +497,8 @@ struct DependencyValidator final : IValidator {
return none;
}
std::vector<std::pair<fbstring, std::vector<fbstring>>> propertyDep_;
std::vector<std::pair<fbstring, std::unique_ptr<IValidator>>> schemaDep_;
std::vector<std::pair<std::string, std::vector<std::string>>> propertyDep_;
std::vector<std::pair<std::string, std::unique_ptr<IValidator>>> schemaDep_;
};
struct EnumValidator final : IValidator {
......
......@@ -164,6 +164,7 @@ public:
using Base::at;
using Base::find;
using Base::count;
template <class... Args>
std::pair<iterator, bool> emplace(StringPiece key, Args&&... args) {
......
......@@ -49,9 +49,9 @@ static int64_t decodeInt(Cursor& curs) {
}
}
static fbstring decodeString(Cursor& curs) {
static std::string decodeString(Cursor& curs) {
auto len = decodeInt(curs);
folly::fbstring str;
std::string str;
if (len < 0) {
throw std::range_error("string length must not be negative");
......
......@@ -118,13 +118,11 @@ char32_t decodeUtf8(
}
struct Printer {
explicit Printer(fbstring& out,
unsigned* indentLevel,
serialization_opts const* opts)
: out_(out)
, indentLevel_(indentLevel)
, opts_(*opts)
{}
explicit Printer(
std::string& out,
unsigned* indentLevel,
serialization_opts const* opts)
: out_(out), indentLevel_(indentLevel), opts_(*opts) {}
void operator()(dynamic const& v) const {
switch (v.type()) {
......@@ -244,7 +242,7 @@ private:
void newline() const {
if (indentLevel_) {
out_ += to<fbstring>('\n', fbstring(*indentLevel_ * 2, ' '));
out_ += to<std::string>('\n', std::string(*indentLevel_ * 2, ' '));
}
}
......@@ -253,9 +251,9 @@ private:
}
private:
fbstring& out_;
unsigned* const indentLevel_;
serialization_opts const& opts_;
std::string& out_;
unsigned* const indentLevel_;
serialization_opts const& opts_;
};
//////////////////////////////////////////////////////////////////////
......@@ -394,7 +392,7 @@ private:
};
dynamic parseValue(Input& in);
fbstring parseString(Input& in);
std::string parseString(Input& in);
dynamic parseNumber(Input& in);
dynamic parseObject(Input& in) {
......@@ -527,7 +525,7 @@ dynamic parseNumber(Input& in) {
return val;
}
fbstring decodeUnicodeEscape(Input& in) {
std::string decodeUnicodeEscape(Input& in) {
auto hexVal = [&] (char c) -> unsigned {
return c >= '0' && c <= '9' ? c - '0' :
c >= 'a' && c <= 'f' ? c - 'a' + 10 :
......@@ -575,11 +573,11 @@ fbstring decodeUnicodeEscape(Input& in) {
return codePointToUtf8(codePoint);
}
fbstring parseString(Input& in) {
std::string parseString(Input& in) {
assert(*in == '\"');
++in;
fbstring ret;
std::string ret;
for (;;) {
auto range = in.skipWhile(
[] (char c) { return c != '\"' && c != '\\'; }
......@@ -602,8 +600,8 @@ fbstring parseString(Input& in) {
case 'r': ret.push_back('\r'); ++in; break;
case 't': ret.push_back('\t'); ++in; break;
case 'u': ++in; ret += decodeUnicodeEscape(in); break;
default: in.error(to<fbstring>("unknown escape ", *in,
" in string").c_str());
default:
in.error(to<std::string>("unknown escape ", *in, " in string").c_str());
}
continue;
}
......@@ -650,8 +648,8 @@ dynamic parseValue(Input& in) {
//////////////////////////////////////////////////////////////////////
fbstring serialize(dynamic const& dyn, serialization_opts const& opts) {
fbstring ret;
std::string serialize(dynamic const& dyn, serialization_opts const& opts) {
std::string ret;
unsigned indentLevel = 0;
Printer p(ret, opts.pretty_formatting ? &indentLevel : nullptr, &opts);
p(dyn);
......@@ -659,9 +657,10 @@ fbstring serialize(dynamic const& dyn, serialization_opts const& opts) {
}
// Escape a string so that it is legal to print it in JSON text.
void escapeString(StringPiece input,
fbstring& out,
const serialization_opts& opts) {
void escapeString(
StringPiece input,
std::string& out,
const serialization_opts& opts) {
auto hexDigit = [] (int c) -> char {
return c < 10 ? c + '0' : c - 10 + 'a';
};
......@@ -732,8 +731,8 @@ void escapeString(StringPiece input,
out.push_back('\"');
}
fbstring stripComments(StringPiece jsonC) {
fbstring result;
std::string stripComments(StringPiece jsonC) {
std::string result;
enum class State {
None,
InString,
......@@ -813,11 +812,11 @@ dynamic parseJson(
return ret;
}
fbstring toJson(dynamic const& dyn) {
std::string toJson(dynamic const& dyn) {
return json::serialize(dyn, json::serialization_opts());
}
fbstring toPrettyJson(dynamic const& dyn) {
std::string toPrettyJson(dynamic const& dyn) {
json::serialization_opts opts;
opts.pretty_formatting = true;
return json::serialize(dyn, opts);
......
......@@ -41,9 +41,9 @@
#pragma once
#include <iosfwd>
#include <string>
#include <folly/dynamic.h>
#include <folly/FBString.h>
#include <folly/Range.h>
namespace folly {
......@@ -122,21 +122,22 @@ namespace json {
* For the most common use cases there are simpler functions in the
* main folly namespace below.
*/
fbstring serialize(dynamic const&, serialization_opts const&);
std::string serialize(dynamic const&, serialization_opts const&);
/*
* Escape a string so that it is legal to print it in JSON text and
* append the result to out.
*/
void escapeString(StringPiece input,
fbstring& out,
const serialization_opts& opts);
void escapeString(
StringPiece input,
std::string& out,
const serialization_opts& opts);
/*
* Strip all C99-like comments (i.e. // and / * ... * /)
*/
fbstring stripComments(StringPiece jsonC);
std::string stripComments(StringPiece jsonC);
}
//////////////////////////////////////////////////////////////////////
......@@ -151,13 +152,13 @@ dynamic parseJson(StringPiece);
/*
* Serialize a dynamic into a json string.
*/
fbstring toJson(dynamic const&);
std::string toJson(dynamic const&);
/*
* Same as the above, except format the json with some minimal
* indentation.
*/
fbstring toPrettyJson(dynamic const&);
std::string toPrettyJson(dynamic const&);
/*
* Printer for GTest.
......
......@@ -50,7 +50,7 @@ TEST(Dynamic, ObjectBasics) {
EXPECT_EQ(*newObject.keys().begin(), newObject.items().begin()->first);
EXPECT_EQ(*newObject.values().begin(), newObject.items().begin()->second);
std::vector<std::pair<folly::fbstring, dynamic>> found;
std::vector<std::pair<std::string, dynamic>> found;
found.emplace_back(newObject.keys().begin()->asString(),
*newObject.values().begin());
......@@ -353,8 +353,8 @@ TEST(Dynamic, Assignment) {
}
}
folly::fbstring make_long_string() {
return folly::fbstring(100, 'a');
std::string make_long_string() {
return std::string(100, 'a');
}
TEST(Dynamic, GetDefault) {
......
......@@ -155,14 +155,14 @@ TEST(Json, BoolConversion) {
TEST(Json, JavascriptSafe) {
auto badDouble = (1ll << 63ll) + 1;
dynamic badDyn = badDouble;
EXPECT_EQ(folly::toJson(badDouble), folly::to<folly::fbstring>(badDouble));
EXPECT_EQ(folly::toJson(badDouble), folly::to<std::string>(badDouble));
folly::json::serialization_opts opts;
opts.javascript_safe = true;
EXPECT_ANY_THROW(folly::json::serialize(badDouble, opts));
auto okDouble = 1ll << 63ll;
dynamic okDyn = okDouble;
EXPECT_EQ(folly::toJson(okDouble), folly::to<folly::fbstring>(okDouble));
EXPECT_EQ(folly::toJson(okDouble), folly::to<std::string>(okDouble));
}
TEST(Json, Produce) {
......@@ -178,10 +178,8 @@ TEST(Json, Produce) {
// Check Infinity/Nan
folly::json::serialization_opts opts;
opts.allow_nan_inf = true;
EXPECT_EQ("Infinity",
folly::json::serialize(parseJson("Infinity"), opts).toStdString());
EXPECT_EQ("NaN",
folly::json::serialize(parseJson("NaN"), opts).toStdString());
EXPECT_EQ("Infinity", folly::json::serialize(parseJson("Infinity"), opts));
EXPECT_EQ("NaN", folly::json::serialize(parseJson("NaN"), opts));
}
TEST(Json, JsonEscape) {
......@@ -260,10 +258,10 @@ TEST(Json, JsonNonAsciiEncoding) {
TEST(Json, UTF8Retention) {
// test retention with valid utf8 strings
folly::fbstring input = "\u2665";
folly::fbstring jsonInput = folly::toJson(input);
folly::fbstring output = folly::parseJson(jsonInput).asString();
folly::fbstring jsonOutput = folly::toJson(output);
std::string input = "\u2665";
std::string jsonInput = folly::toJson(input);
std::string output = folly::parseJson(jsonInput).asString();
std::string jsonOutput = folly::toJson(output);
EXPECT_EQ(input, output);
EXPECT_EQ(jsonInput, jsonOutput);
......@@ -282,10 +280,10 @@ TEST(Json, UTF8EncodeNonAsciiRetention) {
opts.encode_non_ascii = true;
// test encode_non_ascii valid utf8 strings
folly::fbstring input = "\u2665";
folly::fbstring jsonInput = folly::json::serialize(input, opts);
folly::fbstring output = folly::parseJson(jsonInput).asString();
folly::fbstring jsonOutput = folly::json::serialize(output, opts);
std::string input = "\u2665";
std::string jsonInput = folly::json::serialize(input, opts);
std::string output = folly::parseJson(jsonInput).asString();
std::string jsonOutput = folly::json::serialize(output, opts);
EXPECT_EQ(input, output);
EXPECT_EQ(jsonInput, jsonOutput);
......@@ -402,7 +400,7 @@ TEST(Json, ParseDoubleFallback) {
TEST(Json, ParseNumbersAsStrings) {
folly::json::serialization_opts opts;
opts.parse_numbers_as_strings = true;
auto parse = [&](folly::fbstring number) {
auto parse = [&](std::string number) {
return parseJson(number, opts).asString();
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment