support escaped characters with Json & support UTF-8 for HttpClient

minor fixes

minor fixes
This commit is contained in:
Nomango 2019-03-31 23:09:49 +08:00 committed by Nomango
parent 0b7ca8670f
commit 6733757d09
6 changed files with 366 additions and 110 deletions

View File

@ -21,6 +21,7 @@
#include "easy2d-network.h" #include "easy2d-network.h"
#include "curl/curl.h" #include "curl/curl.h"
#include <thread> #include <thread>
#include <codecvt>
#pragma comment(lib, "libcurl.lib") #pragma comment(lib, "libcurl.lib")
@ -41,6 +42,40 @@ namespace
return total; return total;
} }
std::string convert_to_utf8(String const& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
std::string result;
try
{
result = utf8_conv.to_bytes(str.c_str());
}
catch (std::range_error&)
{
// bad conversion
result = str.to_string();
}
return result;
}
String convert_from_utf8(std::string const& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
String result;
try
{
result = utf8_conv.from_bytes(str);
}
catch (std::range_error&)
{
// bad conversion
result = str;
}
return result;
}
class Curl class Curl
{ {
public: public:
@ -277,13 +312,15 @@ namespace easy2d
std::string response_header; std::string response_header;
std::string response_data; std::string response_data;
std::string url = request->GetUrl().to_string();
std::string data = request->GetData().to_string(); std::string url = convert_to_utf8(request->GetUrl());
std::string data = convert_to_utf8(request->GetData());
Array<std::string> headers; Array<std::string> headers;
headers.reserve(request->GetHeaders().size()); headers.reserve(request->GetHeaders().size());
for (const auto& header : request->GetHeaders()) for (const auto& pair : request->GetHeaders())
{ {
headers.push_back(header.to_string()); headers.push_back(pair.first.to_string() + ":" + pair.second.to_string());
} }
switch (request->GetType()) switch (request->GetType())
@ -307,7 +344,7 @@ namespace easy2d
response->SetResponseCode(response_code); response->SetResponseCode(response_code);
response->SetHeader(response_header); response->SetHeader(response_header);
response->SetData(response_data); response->SetData(convert_from_utf8(response_data));
if (!ok) if (!ok)
{ {
response->SetSucceed(false); response->SetSucceed(false);

View File

@ -53,7 +53,7 @@ namespace easy2d
inline void SetUrl(String const& url) inline void SetUrl(String const& url)
{ {
url_ = url.to_string(); url_ = url;
} }
inline String const& GetUrl() const inline String const& GetUrl() const
@ -73,7 +73,13 @@ namespace easy2d
inline void SetData(String const& data) inline void SetData(String const& data)
{ {
data_ = data.to_string(); data_ = data;
}
inline void SetJsonData(Json const& json)
{
SetHeader(L"Content-Type", L"application/json;charset=UTF-8");
data_ = json.dump();
} }
inline String const& GetData() const inline String const& GetData() const
@ -81,16 +87,34 @@ namespace easy2d
return data_; return data_;
} }
inline void SetHeaders(Array<String> const& headers) inline void SetHeaders(Map<String, String> const& headers)
{ {
headers_ = headers; headers_ = headers;
} }
inline Array<String> const& GetHeaders() const inline void SetHeader(String const& field, String const& content)
{
auto iter = headers_.find(field);
if (iter != headers_.end())
{
headers_[field] = content;
}
else
{
headers_.insert(std::make_pair(field, content));
}
}
inline Map<String, String>& GetHeaders()
{ {
return headers_; return headers_;
} }
inline String const& GetHeader(String const& header) const
{
return headers_.at(header);
}
inline void SetResponseCallback(ResponseCallback const& callback) inline void SetResponseCallback(ResponseCallback const& callback)
{ {
response_cb_ = callback; response_cb_ = callback;
@ -105,7 +129,7 @@ namespace easy2d
Type type_; Type type_;
String url_; String url_;
String data_; String data_;
Array<String> headers_; Map<String, String> headers_;
ResponseCallback response_cb_; ResponseCallback response_cb_;
}; };
} }

View File

@ -95,38 +95,40 @@ namespace easy2d
// //
class json_exception class json_exception
: public std::exception : public std::runtime_error
{ {
public: public:
json_exception(const char* message) : std::exception(message) {} json_exception(const char* message)
: std::runtime_error(message)
{}
}; };
class json_type_error class json_type_error
: public json_exception : public json_exception
{ {
public: public:
json_type_error() : json_exception("invalid json type") {} json_type_error(const char* message) : json_exception(message) {}
}; };
class json_invalid_key class json_invalid_key
: public json_exception : public json_exception
{ {
public: public:
json_invalid_key() : json_exception("invalid basic_json key") {} json_invalid_key(const char* message) : json_exception(message) {}
}; };
class json_invalid_iterator class json_invalid_iterator
: public json_exception : public json_exception
{ {
public: public:
json_invalid_iterator() : json_exception("invalid basic_json iterator") {} json_invalid_iterator(const char* message) : json_exception(message) {}
}; };
class json_parse_error class json_parse_error
: public json_exception : public json_exception
{ {
public: public:
json_parse_error() : json_exception("parse json data error") {} json_parse_error(const char* message) : json_exception(message) {}
}; };
@ -457,7 +459,7 @@ namespace easy2d
check_data(); check_data();
check_iterator(); check_iterator();
if (!data_->is_object()) if (!data_->is_object())
throw json_invalid_iterator(); throw json_invalid_iterator("cannot use key() with non-object type");
return it_.object_iter->first; return it_.object_iter->first;
} }
@ -577,7 +579,7 @@ namespace easy2d
{ {
case JsonType::Object: case JsonType::Object:
{ {
throw json_invalid_iterator(); throw json_invalid_iterator("cannot use offsets with object type");
break; break;
} }
case JsonType::Array: case JsonType::Array:
@ -600,8 +602,8 @@ namespace easy2d
check_data(); check_data();
other.check_data(); other.check_data();
if (data_->type() != other.data_->type()) if (data_ != other.data_)
throw json_invalid_iterator(); throw json_invalid_iterator("cannot compare iterators of different objects");
switch (data_->type()) switch (data_->type())
{ {
@ -626,11 +628,15 @@ namespace easy2d
inline bool operator<(iterator_impl const& other) const inline bool operator<(iterator_impl const& other) const
{ {
check_data(); check_data();
other.check_data();
if (data_ != other.data_)
throw json_invalid_iterator("cannot compare iterators of different objects");
switch (data_->type()) switch (data_->type())
{ {
case JsonType::Object: case JsonType::Object:
throw json_invalid_iterator(); throw json_invalid_iterator("cannot compare iterators with object type");
case JsonType::Array: case JsonType::Array:
return it_.array_iter < other.it_.array_iter; return it_.array_iter < other.it_.array_iter;
default: default:
@ -643,7 +649,7 @@ namespace easy2d
{ {
if (data_ == nullptr) if (data_ == nullptr)
{ {
throw json_invalid_iterator(); throw json_invalid_iterator("iterator contains an empty object");
} }
} }
@ -654,19 +660,19 @@ namespace easy2d
case JsonType::Object: case JsonType::Object:
if (it_.object_iter == data_->value_.data.object->end()) if (it_.object_iter == data_->value_.data.object->end())
{ {
throw json_invalid_iterator(); throw std::out_of_range("iterator out of range");
} }
break; break;
case JsonType::Array: case JsonType::Array:
if (it_.array_iter == data_->value_.data.vector->end()) if (it_.array_iter == data_->value_.data.vector->end())
{ {
throw json_invalid_iterator(); throw std::out_of_range("iterator out of range");
} }
break; break;
default: default:
if (it_.original_iter == 1) if (it_.original_iter == 1)
{ {
throw json_invalid_iterator(); throw std::out_of_range("iterator out of range");
} }
break; break;
} }
@ -993,21 +999,63 @@ namespace easy2d
switch (ch) switch (ch)
{ {
case '\t': case '\t':
out->write('\\'); {
out->write('t'); out->write(L"\\t");
break; break;
}
case '\r': case '\r':
out->write('\\'); {
out->write('r'); out->write(L"\\r");
break; break;
}
case '\n': case '\n':
out->write('\\'); {
out->write('n'); out->write(L"\\n");
break; break;
}
case '\b':
{
out->write(L"\\b");
break;
}
case '\f':
{
out->write(L"\\f");
break;
}
case '\"':
{
out->write(L"\\\"");
break;
}
case '\\':
{
out->write(L"\\\\");
break;
}
default: default:
out->write(ch); {
const auto char_byte = static_cast<uint16_t>(ch);
if ((char_byte > 0x1F) && (char_byte < 0x7F))
{
out->write(ch);
}
else
{
wchar_t escaped[7] = { 0 };
::swprintf_s(escaped, 7, L"\\u%04x", char_byte);
out->write(escaped);
}
break; break;
} }
}
} }
} }
@ -1268,38 +1316,149 @@ namespace easy2d
token_type scan_string() token_type scan_string()
{ {
if (current == '\"') if (current != '\"')
return token_type::parse_error;
string_buffer.clear();
while (true)
{ {
string_buffer.clear(); const auto ch = read_next();
switch (ch)
bool must_read_next = false;
while (true)
{ {
const auto ch = read_next(); case char_traits::eof():
{
// unexpected end
return token_type::parse_error;
}
if (must_read_next) case '\"':
{
// skip last `\"`
read_next();
return token_type::value_string;
}
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1E:
case 0x1F:
{
// invalid control character
return token_type::parse_error;
}
case '\\':
{
switch (read_next())
{ {
must_read_next = false; case '\"':
} string_buffer.push_back('\"');
else if (ch == '\\') break;
case '\\':
string_buffer.push_back('\\');
break;
case '/':
string_buffer.push_back('/');
break;
case 'b':
string_buffer.push_back('\b');
break;
case 'f':
string_buffer.push_back('\f');
break;
case 'n':
string_buffer.push_back('\n');
break;
case 'r':
string_buffer.push_back('\r');
break;
case 't':
string_buffer.push_back('\t');
break;
case 'u':
{ {
must_read_next = true; // unicode escapes
} uint16_t byte = 0;
else if (ch == '\"')
{ for (const auto factor : { 12, 8, 4, 0 })
// skip last \" {
read_next(); const auto n = read_next();
if (n >= L'0' && n <= L'9')
{
byte += ((n - L'0') << factor);
}
else if (n >= L'A' && n <= L'F')
{
byte += ((n - L'A' + 10) << factor);
}
else if (n >= L'a' && n <= L'f')
{
byte += ((n - L'a' + 10) << factor);
}
else
{
// '\u' must be followed by 4 hex digits
return token_type::parse_error;
}
}
string_buffer.push_back(char_traits::to_char_type(byte));
break; break;
} }
if (ch == '\0' || ch == char_traits::eof()) default:
{
return token_type::parse_error; return token_type::parse_error;
}
string_buffer.push_back(char_traits::to_char_type(ch)); }
break;
}
default:
{
if (ch > 0x1F && ch < 0x7F)
{
string_buffer.push_back(char_traits::to_char_type(ch));
break;
}
else
{
return token_type::parse_error;
}
}
} }
return token_type::value_string;
} }
return token_type::parse_error;
} }
token_type scan_number() token_type scan_number()
@ -1484,7 +1643,7 @@ namespace easy2d
parse_value(json); parse_value(json);
if (get_token() != token_type::end_of_input) if (get_token() != token_type::end_of_input)
throw json_parse_error(); throw json_parse_error("unexpected token, expect end");
} }
private: private:
@ -1536,7 +1695,7 @@ namespace easy2d
break; break;
} }
if (last_token != token_type::end_array) if (last_token != token_type::end_array)
throw json_parse_error(); throw json_parse_error("unexpected token in array");
break; break;
case token_type::begin_object: case token_type::begin_object:
@ -1559,12 +1718,12 @@ namespace easy2d
break; break;
} }
if (last_token != token_type::end_object) if (last_token != token_type::end_object)
throw json_parse_error(); throw json_parse_error("unexpected token in object");
break; break;
default: default:
// unexpected token // unexpected token
throw json_parse_error(); throw json_parse_error("unexpected token");
break; break;
} }
} }
@ -1594,31 +1753,31 @@ namespace easy2d
static inline void assign(const _BasicJsonTy& json, object_type& value) static inline void assign(const _BasicJsonTy& json, object_type& value)
{ {
if (!json.is_object()) throw json_type_error(); if (!json.is_object()) throw json_type_error("json value type must be object");
value = *json.value_.data.object; value = *json.value_.data.object;
} }
static inline void assign(const _BasicJsonTy& json, array_type& value) static inline void assign(const _BasicJsonTy& json, array_type& value)
{ {
if (!json.is_array()) throw json_type_error(); if (!json.is_array()) throw json_type_error("json value type must be array");
value = *json.value_.data.vector; value = *json.value_.data.vector;
} }
static inline void assign(const _BasicJsonTy& json, string_type& value) static inline void assign(const _BasicJsonTy& json, string_type& value)
{ {
if (!json.is_string()) throw json_type_error(); if (!json.is_string()) throw json_type_error("json value type must be string");
value = *json.value_.data.string; value = *json.value_.data.string;
} }
static inline void assign(const _BasicJsonTy& json, boolean_type& value) static inline void assign(const _BasicJsonTy& json, boolean_type& value)
{ {
if (!json.is_boolean()) throw json_type_error(); if (!json.is_boolean()) throw json_type_error("json value type must be boolean");
value = json.value_.data.boolean; value = json.value_.data.boolean;
} }
static inline void assign(const _BasicJsonTy& json, integer_type& value) static inline void assign(const _BasicJsonTy& json, integer_type& value)
{ {
if (!json.is_integer()) throw json_type_error(); if (!json.is_integer()) throw json_type_error("json value type must be integer");
value = json.value_.data.number_integer; value = json.value_.data.number_integer;
} }
@ -1627,16 +1786,22 @@ namespace easy2d
typename std::enable_if<std::is_integral<_IntegerTy>::value, int>::type = 0> typename std::enable_if<std::is_integral<_IntegerTy>::value, int>::type = 0>
static inline void assign(const _BasicJsonTy& json, _IntegerTy& value) static inline void assign(const _BasicJsonTy& json, _IntegerTy& value)
{ {
if (!json.is_integer()) throw json_type_error(); if (!json.is_integer()) throw json_type_error("json value type must be integer");
value = static_cast<_IntegerTy>(json.value_.data.number_integer); value = static_cast<_IntegerTy>(json.value_.data.number_integer);
} }
static inline void assign(const _BasicJsonTy& json, float_type& value)
{
if (!json.is_float()) throw json_type_error("json value type must be float");
value = json.value_.data.number_float;
}
template < template <
typename _FloatingTy, typename _FloatingTy,
typename std::enable_if<std::is_floating_point<_FloatingTy>::value, int>::type = 0> typename std::enable_if<std::is_floating_point<_FloatingTy>::value, int>::type = 0>
static inline void assign(const _BasicJsonTy& json, _FloatingTy& value) static inline void assign(const _BasicJsonTy& json, _FloatingTy& value)
{ {
if (!json.is_float()) throw json_type_error(); if (!json.is_float()) throw json_type_error("json value type must be float");
value = static_cast<_FloatingTy>(json.value_.data.number_float); value = static_cast<_FloatingTy>(json.value_.data.number_float);
} }
}; };
@ -1878,7 +2043,7 @@ namespace easy2d
{ {
if (!is_object()) if (!is_object())
{ {
throw json_invalid_key(); throw json_invalid_key("cannot use erase() with non-object value");
} }
return value_.data.object->erase(key); return value_.data.object->erase(key);
} }
@ -1887,7 +2052,7 @@ namespace easy2d
{ {
if (!is_array()) if (!is_array())
{ {
throw json_invalid_key(); throw json_invalid_key("cannot use erase() with non-array value");
} }
value_.data.vector->erase(value_.data.vector->begin() + static_cast<difference_type>(index)); value_.data.vector->erase(value_.data.vector->begin() + static_cast<difference_type>(index));
} }
@ -1917,7 +2082,7 @@ namespace easy2d
} }
default: default:
throw json_invalid_iterator(); throw json_invalid_iterator("cannot use erase() with non-object & non-array value");
} }
return result; return result;
@ -1948,7 +2113,7 @@ namespace easy2d
} }
default: default:
throw json_invalid_iterator(); throw json_invalid_iterator("cannot use erase() with non-object & non-array value");
} }
return result; return result;
@ -1958,7 +2123,7 @@ namespace easy2d
{ {
if (!is_null() && !is_array()) if (!is_null() && !is_array())
{ {
throw json_type_error(); throw json_type_error("cannot use push_back() with non-array value");
} }
if (is_null()) if (is_null())
@ -2111,37 +2276,37 @@ namespace easy2d
boolean_type as_bool() const boolean_type as_bool() const
{ {
if (!is_boolean()) throw json_type_error(); if (!is_boolean()) throw json_type_error("json value must be boolean");
return value_.data.boolean; return value_.data.boolean;
} }
integer_type as_int() const integer_type as_int() const
{ {
if (!is_integer()) throw json_type_error(); if (!is_integer()) throw json_type_error("json value must be integer");
return value_.data.number_integer; return value_.data.number_integer;
} }
float_type as_float() const float_type as_float() const
{ {
if (!is_float()) throw json_type_error(); if (!is_float()) throw json_type_error("json value must be float");
return value_.data.number_float; return value_.data.number_float;
} }
const array_type& as_array() const const array_type& as_array() const
{ {
if (!is_array()) throw json_type_error(); if (!is_array()) throw json_type_error("json value must be array");
return *value_.data.vector; return *value_.data.vector;
} }
const string_type& as_string() const const string_type& as_string() const
{ {
if (!is_string()) throw json_type_error(); if (!is_string()) throw json_type_error("json value must be string");
return *value_.data.string; return *value_.data.string;
} }
const object_type& as_object() const const object_type& as_object() const
{ {
if (!is_object()) throw json_type_error(); if (!is_object()) throw json_type_error("json value must be object");
return *value_.data.object; return *value_.data.object;
} }
@ -2186,7 +2351,7 @@ namespace easy2d
if (!is_array()) if (!is_array())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-array object");
} }
if (index >= value_.data.vector->size()) if (index >= value_.data.vector->size())
@ -2203,12 +2368,12 @@ namespace easy2d
{ {
if (!is_array()) if (!is_array())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-array type");
} }
if (index >= value_.data.vector->size()) if (index >= value_.data.vector->size())
{ {
throw json_invalid_key(); throw std::out_of_range("operator[] index out of range");
} }
return (*value_.data.vector)[index]; return (*value_.data.vector)[index];
} }
@ -2222,7 +2387,7 @@ namespace easy2d
if (!is_object()) if (!is_object())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-object type");
} }
return (*value_.data.object)[key]; return (*value_.data.object)[key];
} }
@ -2231,13 +2396,13 @@ namespace easy2d
{ {
if (!is_object()) if (!is_object())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-object object");
} }
auto iter = value_.data.object->find(key); auto iter = value_.data.object->find(key);
if (iter == value_.data.object->end()) if (iter == value_.data.object->end())
{ {
throw json_invalid_key(); throw std::out_of_range("operator[] key out of range");
} }
return iter->second; return iter->second;
} }
@ -2252,7 +2417,7 @@ namespace easy2d
if (!is_object()) if (!is_object())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-object object");
} }
return (*value_.data.object)[key]; return (*value_.data.object)[key];
} }
@ -2262,13 +2427,13 @@ namespace easy2d
{ {
if (!is_object()) if (!is_object())
{ {
throw json_invalid_key(); throw json_invalid_key("operator[] called on a non-object object");
} }
auto iter = value_.data.object->find(key); auto iter = value_.data.object->find(key);
if (iter == value_.data.object->end()) if (iter == value_.data.object->end())
{ {
throw json_invalid_key(); throw std::out_of_range("operator[] key out of range");
} }
return iter->second; return iter->second;
} }

View File

@ -21,9 +21,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <codecvt>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cstdlib>
namespace easy2d namespace easy2d
{ {
@ -431,6 +431,25 @@ namespace easy2d
} }
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
class chs_codecvt
: public std::codecvt_byname<wchar_t, char, std::mbstate_t>
{
public:
chs_codecvt() : codecvt_byname("chs") {}
static inline std::wstring string_to_wide(std::string const& str)
{
std::wstring_convert<chs_codecvt> conv;
return conv.from_bytes(str);
}
static inline std::string wide_to_string(std::wstring const& str)
{
std::wstring_convert<chs_codecvt> conv;
return conv.to_bytes(str);
}
};
} }
inline String::String() inline String::String()
@ -479,16 +498,15 @@ namespace easy2d
{ {
if (cstr && cstr[0]) if (cstr && cstr[0])
{ {
size_t len; try
errno_t ret = ::mbstowcs_s(&len, nullptr, 0, cstr, 0);
if (!ret)
{ {
str_ = allocate(len); std::wstring wide_string = __string_details::chs_codecvt::string_to_wide(cstr);
str_[0] = 0; assign(wide_string);
}
::mbstowcs_s(nullptr, str_, len, cstr, len - 1); catch (std::range_error& e)
{
capacity_ = size_ = static_cast<size_type>(len - 1); // bad conversion
(void)e;
} }
} }
} }
@ -702,7 +720,7 @@ namespace easy2d
wchar_t* const insert_at = new_ptr + index; wchar_t* const insert_at = new_ptr + index;
char_traits::move(new_ptr, old_ptr, index); // (0) - (index) char_traits::move(new_ptr, old_ptr, index); // (0) - (index)
char_traits::move(insert_at, str.begin().base() + off, count); // (index) - (index + count) char_traits::move(insert_at, str.begin().base() + off, count); // (index) - (index + count)
char_traits::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index) char_traits::move(insert_at + count, old_ptr + index, suffix_size); // (index + count) - (old_size - index)
deallocate(str_, old_capacity + 1); deallocate(str_, old_capacity + 1);
@ -979,13 +997,15 @@ namespace easy2d
{ {
if (const_str_ && size_) if (const_str_ && size_)
{ {
size_t len; try
errno_t ret = ::wcstombs_s(&len, nullptr, 0, const_str_, 0);
if (!ret)
{ {
std::string ret(len - 1, '\0'); std::string string = __string_details::chs_codecvt::wide_to_string(const_str_);
::wcstombs_s(nullptr, &ret[0], len, const_str_, len - 1); return string;
return ret; }
catch (std::range_error& e)
{
// bad conversion
(void)e;
} }
} }
return std::string(); return std::string();

View File

@ -59,6 +59,12 @@ namespace
wconsole_output.open("CONOUT$", std::ios::out); wconsole_output.open("CONOUT$", std::ios::out);
wconsole_error.open("CONOUT$", std::ios::out); wconsole_error.open("CONOUT$", std::ios::out);
FILE* dummy;
freopen_s(&dummy, "CONOUT$", "w+t", stdout);
freopen_s(&dummy, "CONIN$", "r+t", stdin);
freopen_s(&dummy, "CONOUT$", "w+t", stderr);
(void)dummy;
std::cin.rdbuf(console_input.rdbuf()); std::cin.rdbuf(console_input.rdbuf());
std::cout.rdbuf(console_output.rdbuf()); std::cout.rdbuf(console_output.rdbuf());
std::cerr.rdbuf(console_error.rdbuf()); std::cerr.rdbuf(console_error.rdbuf());
@ -83,6 +89,10 @@ namespace
std::wcout.rdbuf(wcout_buffer); std::wcout.rdbuf(wcout_buffer);
std::wcerr.rdbuf(wcerr_buffer); std::wcerr.rdbuf(wcerr_buffer);
fclose(stdout);
fclose(stdin);
fclose(stderr);
cin_buffer = nullptr; cin_buffer = nullptr;
cout_buffer = nullptr; cout_buffer = nullptr;
cerr_buffer = nullptr; cerr_buffer = nullptr;

View File

@ -87,19 +87,19 @@ public:
// 创建 JSON 格式的 POST 数据 // 创建 JSON 格式的 POST 数据
Json request_data = { Json request_data = {
{"String", "StringTest"}, {"string", "testÖÐÎÄ"},
{"Boolean", true}, {"boolean", true},
{"Integer", 12}, {"integer", 12},
{"Float", 3.125}, {"float", 3.125},
{"Array", {1, 2, 3, 4, 4.5 }}, {"array", {1, 2, 3, 4, 4.5 }},
{"Object", {"Key", "Value"}}, {"object", {"key", "value"}},
}; };
HttpRequestPtr request = new HttpRequest; HttpRequestPtr request = new HttpRequest;
request->SetUrl(L"http://httpbin.org/post"); request->SetUrl(L"http://httpbin.org/post");
request->SetType(HttpRequest::Type::Post); request->SetType(HttpRequest::Type::Post);
// 设置 POST 请求的数据 // 设置 POST 请求的数据
request->SetData(request_data.dump()); request->SetJsonData(request_data);
request->SetResponseCallback(Closure(this, &Demo5::Complete)); request->SetResponseCallback(Closure(this, &Demo5::Complete));
HttpClient::Instance().Send(request); HttpClient::Instance().Send(request);
@ -119,7 +119,7 @@ public:
request->SetUrl(L"http://httpbin.org/put"); request->SetUrl(L"http://httpbin.org/put");
request->SetType(HttpRequest::Type::Put); request->SetType(HttpRequest::Type::Put);
// 设置 PUT 请求的数据 // 设置 PUT 请求的数据
request->SetData(request_data.dump()); request->SetJsonData(request_data);
request->SetResponseCallback(Closure(this, &Demo5::Complete)); request->SetResponseCallback(Closure(this, &Demo5::Complete));
HttpClient::Instance().Send(request); HttpClient::Instance().Send(request);
@ -156,7 +156,7 @@ public:
} }
catch (json_exception& e) catch (json_exception& e)
{ {
E2D_ERROR_LOG(L"Parse JSON failed: %s", e.what()); std::wcout << L"Parse JSON failed: " << e.what() << std::endl;
} }
} }
else else