CROW_ROUTE ( app , "/json" )
([]{
- crow :: json :: wvalue x ;
- x [ "message" ] = "Hello, World!" ;
+ crow :: json :: wvalue x {{"({{"}} "message" , "Hello, World!" {{"}});"}}
+ x [ "message2" ] = "Hello, World.. Again!" ;
return x ;
});
diff --git a/docs/overrides/main.html b/docs/overrides/main.html
index e3dfe8716..ab65d693e 100644
--- a/docs/overrides/main.html
+++ b/docs/overrides/main.html
@@ -6,4 +6,6 @@
+
+
{% endblock %}
diff --git a/examples/example.cpp b/examples/example.cpp
index 4b9edbfa8..5070695c0 100644
--- a/examples/example.cpp
+++ b/examples/example.cpp
@@ -63,11 +63,33 @@ int main()
// simple json response
- // To see it in action enter {ip}:18080/json
CROW_ROUTE(app, "/json")
([]{
- crow::json::wvalue x;
- x["message"] = "Hello, World!";
+ crow::json::wvalue x({{"message", "Hello, World!"}});
+ x["message2"] = "Hello, World.. Again!";
+ return x;
+ });
+
+ CROW_ROUTE(app, "/json-initializer-list-constructor")
+ ([] {
+ return crow::json::wvalue({
+ {"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
+ {"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
+ {"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
+ {"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
+ {"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
+ {"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
+ {"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
+ {"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
+ {"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
+ {"tenth", true} /* stores a bool hence json::type::True . */
+ });
+ });
+
+ // json list response
+ CROW_ROUTE(app, "/json_list")
+ ([]{
+ crow::json::wvalue x(crow::json::wvalue::list({1,2,3}));
return x;
});
diff --git a/examples/example_json_map.cpp b/examples/example_json_map.cpp
index 043035146..03b3d9238 100644
--- a/examples/example_json_map.cpp
+++ b/examples/example_json_map.cpp
@@ -11,31 +11,11 @@ int main()
// it shoud show amessage before zmessage despite adding zmessage first.
CROW_ROUTE(app, "/json")
([]{
- crow::json::wvalue x;
- x["zmessage"] = "Hello, World!";
- x["amessage"] = "Hello, World2!";
+ crow::json::wvalue x({{"zmessage", "Hello, World!"},
+ {"amessage", "Hello, World2!"}});
return x;
});
-CROW_ROUTE(app, "/json-initializer-list-constructor")
-([] {
- return crow::json::wvalue({
- {"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
- {"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
- {"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
- {"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
- {"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
- {"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
- {"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
- {"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
- {"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
- {"tenth", true} /* stores a bool hence json::type::True . */
- });
-});
-
-// enables all log
-app.loglevel(crow::LogLevel::Debug);
-
app.port(18080)
.multithreaded()
.run();
diff --git a/examples/example_with_all.cpp b/examples/example_with_all.cpp
index a015e6b3a..2ab5fc8b8 100644
--- a/examples/example_with_all.cpp
+++ b/examples/example_with_all.cpp
@@ -28,8 +28,31 @@ int main()
// simple json response
CROW_ROUTE(app, "/json")
([]{
- crow::json::wvalue x;
- x["message"] = "Hello, World!";
+ crow::json::wvalue x({{"message", "Hello, World!"}});
+ x["message2"] = "Hello, World.. Again!";
+ return x;
+ });
+
+ CROW_ROUTE(app, "/json-initializer-list-constructor")
+ ([] {
+ return crow::json::wvalue({
+ {"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
+ {"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
+ {"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
+ {"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
+ {"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
+ {"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
+ {"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
+ {"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
+ {"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
+ {"tenth", true} /* stores a bool hence json::type::True . */
+ });
+ });
+
+ // json list response
+ CROW_ROUTE(app, "/json_list")
+ ([]{
+ crow::json::wvalue x(crow::json::wvalue::list({1,2,3}));
return x;
});
diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp
index 116f7559c..c12b8c41e 100644
--- a/examples/helloworld.cpp
+++ b/examples/helloworld.cpp
@@ -7,7 +7,7 @@ int main()
CROW_ROUTE(app, "/")
([]() {
- return "Hello world!";
+ return "Hello, world!";
});
app.port(18080).run();
diff --git a/include/crow/json.h b/include/crow/json.h
index 04a6209ae..be7ac8d91 100644
--- a/include/crow/json.h
+++ b/include/crow/json.h
@@ -1216,6 +1216,7 @@ namespace crow
return load(str.data(), str.size());
}
+
/// JSON write value.
///
@@ -1226,14 +1227,16 @@ namespace crow
friend class crow::mustache::template_t;
public:
- using object_type =
+
+ using object =
#ifdef CROW_JSON_USE_MAP
std::map
;
#else
std::unordered_map;
#endif
- public:
+ using list = std::vector;
+
type t() const { return t_; }
private:
type t_{type::Null}; ///< The type of the value.
@@ -1250,12 +1253,8 @@ namespace crow
constexpr number(double value) noexcept : d(value) {}
} num; ///< Value if type is a number.
std::string s; ///< Value if type is a string.
- std::unique_ptr> l; ///< Value if type is a list.
-#ifdef CROW_JSON_USE_MAP
- std::unique_ptr> o;
-#else
- std::unique_ptr> o; ///< Value if type is a JSON object.
-#endif
+ std::unique_ptr l; ///< Value if type is a list.
+ std::unique_ptr o; ///< Value if type is a JSON object.
public:
wvalue() : returnable("application/json") {}
@@ -1282,15 +1281,23 @@ namespace crow
wvalue(std::string const& value) : returnable("application/json"), t_(type::String), s(value) {}
wvalue(std::string&& value) : returnable("application/json"), t_(type::String), s(std::move(value)) {}
- wvalue(std::initializer_list> initializer_list) : returnable("application/json"), t_(type::Object), o(new object_type(initializer_list)) {}
+ wvalue(std::initializer_list> initializer_list) : returnable("application/json"), t_(type::Object), o(new object(initializer_list)) {}
- wvalue(object_type const& value) : returnable("application/json"), t_(type::Object), o(new object_type(value)) {}
- wvalue(object_type&& value) : returnable("application/json"), t_(type::Object), o(new object_type(std::move(value))) {}
+ wvalue(object const& value) : returnable("application/json"), t_(type::Object), o(new object(value)) {}
+ wvalue(object&& value) : returnable("application/json"), t_(type::Object), o(new object(std::move(value))) {}
- wvalue(std::vector& r) : returnable("application/json")
+ wvalue(const list& r) : returnable("application/json")
+ {
+ t_ = type::List;
+ l = std::unique_ptr(new list{});
+ l->reserve(r.size());
+ for(auto it = r.begin(); it != r.end(); ++it)
+ l->emplace_back(*it);
+ }
+ wvalue(list& r) : returnable("application/json")
{
t_ = type::List;
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
l->reserve(r.size());
for(auto it = r.begin(); it != r.end(); ++it)
l->emplace_back(*it);
@@ -1319,17 +1326,13 @@ namespace crow
s = r.s();
return;
case type::List:
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
l->reserve(r.size());
for(auto it = r.begin(); it != r.end(); ++it)
l->emplace_back(*it);
return;
case type::Object:
-#ifdef CROW_JSON_USE_MAP
- o = std::unique_ptr>(new std::map{});
-#else
- o = std::unique_ptr>(new std::unordered_map{});
-#endif
+ o = std::unique_ptr(new object{});
for(auto it = r.begin(); it != r.end(); ++it)
o->emplace(it->key(), *it);
return;
@@ -1358,17 +1361,13 @@ namespace crow
s = r.s;
return;
case type::List:
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
l->reserve(r.size());
for(auto it = r.l->begin(); it != r.l->end(); ++it)
l->emplace_back(*it);
return;
case type::Object:
-#ifdef CROW_JSON_USE_MAP
- o = std::unique_ptr>(new std::map{});
-#else
- o = std::unique_ptr>(new std::unordered_map{});
-#endif
+ o = std::unique_ptr(new object{});
o->insert(r.o->begin(), r.o->end());
return;
}
@@ -1514,13 +1513,13 @@ namespace crow
return *this;
}
- wvalue& operator=(std::vector&& v)
+ wvalue& operator=(list&& v)
{
if (t_ != type::List)
reset();
t_ = type::List;
if (!l)
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
l->clear();
l->resize(v.size());
size_t idx = 0;
@@ -1538,7 +1537,7 @@ namespace crow
reset();
t_ = type::List;
if (!l)
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
l->clear();
l->resize(v.size());
size_t idx = 0;
@@ -1554,31 +1553,31 @@ namespace crow
if (t_ != type::Object) {
reset();
t_ = type::Object;
- o = std::unique_ptr(new object_type(initializer_list));
+ o = std::unique_ptr(new object(initializer_list));
} else {
(*o) = initializer_list;
}
return *this;
}
- wvalue& operator=(object_type const& value)
+ wvalue& operator=(object const& value)
{
if (t_ != type::Object) {
reset();
t_ = type::Object;
- o = std::unique_ptr(new object_type(value));
+ o = std::unique_ptr(new object(value));
} else {
(*o) = value;
}
return *this;
}
- wvalue& operator=(object_type&& value)
+ wvalue& operator=(object&& value)
{
if (t_ != type::Object) {
reset();
t_ = type::Object;
- o = std::unique_ptr(new object_type(std::move(value)));
+ o = std::unique_ptr(new object(std::move(value)));
} else {
(*o) = std::move(value);
}
@@ -1591,7 +1590,7 @@ namespace crow
reset();
t_ = type::List;
if (!l)
- l = std::unique_ptr>(new std::vector{});
+ l = std::unique_ptr(new list{});
if (l->size() < index+1)
l->resize(index+1);
return (*l)[index];
@@ -1612,11 +1611,7 @@ namespace crow
reset();
t_ = type::Object;
if (!o)
-#ifdef CROW_JSON_USE_MAP
- o = std::unique_ptr>(new std::map{});
-#else
- o = std::unique_ptr>(new std::unordered_map{});
-#endif
+ o = std::unique_ptr(new object{});
return (*o)[str];
}
@@ -1706,8 +1701,48 @@ namespace crow
#else
#define MSC_COMPATIBLE_SPRINTF(BUFFER_PTR, FORMAT_PTR, VALUE) sprintf((BUFFER_PTR), (FORMAT_PTR), (VALUE))
#endif
+ enum {
+ start,
+ decp,
+ zero
+ } f_state;
char outbuf[128];
- MSC_COMPATIBLE_SPRINTF(outbuf, "%g", v.num.d);
+ MSC_COMPATIBLE_SPRINTF(outbuf, "%f", v.num.d);
+ char *p = &outbuf[0], *o = nullptr;
+ f_state = start;
+ while (*p != '\0')
+ {
+ //std::cout << *p << std::endl;
+ char ch = *p;
+ switch (f_state){
+ case start:
+ if (ch == '.')
+ {
+ if (p+1 && *(p+1) == '0') p++;
+ f_state = decp;
+ }
+ p++;
+ break;
+ case decp:
+ if (ch == '0')
+ {
+ f_state = zero;
+ o = p;
+ }
+ p++;
+ break;
+ case zero:
+ if (ch != '0')
+ {
+ o = nullptr;
+ f_state = decp;
+ }
+ p++;
+ break;
+ }
+ }
+ if (o != nullptr)
+ *o = '\0';
out += outbuf;
#undef MSC_COMPATIBLE_SPRINTF
}
diff --git a/include/crow/middlewares/utf-8.h b/include/crow/middlewares/utf-8.h
index 909c9a2de..d0cce2498 100644
--- a/include/crow/middlewares/utf-8.h
+++ b/include/crow/middlewares/utf-8.h
@@ -15,7 +15,7 @@ namespace crow
{
}
- void after_handle(request& /*req*/, response& res, context& ctx)
+ void after_handle(request& /*req*/, response& res, context& /*ctx*/)
{
if (get_header_value(res.headers, "Content-Type").empty())
{
diff --git a/tests/unittest.cpp b/tests/unittest.cpp
index ebb15c854..8bc39ae1e 100644
--- a/tests/unittest.cpp
+++ b/tests/unittest.cpp
@@ -746,6 +746,8 @@ TEST_CASE("json_copy_r_to_w_to_w_to_r")
CHECK("other" == x["obj"]["other"].key());
}
+//TODO maybe combine these
+
TEST_CASE("json::wvalue::wvalue(bool)") {
CHECK(json::wvalue(true).t() == json::type::True);
CHECK(json::wvalue(false).t() == json::type::False);
@@ -885,7 +887,7 @@ TEST_CASE("json::wvalue::wvalue(std::[unordered_]map
truth = true;
lie = false;
- json::wvalue::object_type map({
+ json::wvalue::object map({
{"integer", integer},
{"number", number},
{"truth", truth},
@@ -909,7 +911,7 @@ TEST_CASE("json::wvalue::wvalue(std::[unordered_]map&
truth = true;
lie = false;
- json::wvalue::object_type map = {{
+ json::wvalue::object map = {{
{"integer", integer},
{"number", number},
{"truth", truth},
@@ -958,7 +960,7 @@ TEST_CASE("json::wvalue::operator=(std::[unordered_]map