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