add parser unicode
This commit is contained in:
+134
-2
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "json.h"
|
||||
#include "exception.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace simpleJson {
|
||||
|
||||
@@ -793,7 +794,20 @@ namespace simpleJson {
|
||||
ch == '\t') {
|
||||
str += ch;
|
||||
} else if (ch == 'u') {
|
||||
//unicode TODO
|
||||
std::string unicode_str;
|
||||
for (int i = 0; i < 4; i ++) {
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F') {
|
||||
unicode_str += ch;
|
||||
} else {
|
||||
throw JsonInvalidUnicodeSym(reader.get_curr_line(), reader.get_curr_col(), ch);
|
||||
}
|
||||
}
|
||||
long unicode = std::stol(unicode_str.data(), nullptr, 16);
|
||||
std::string utf8_str;
|
||||
encode_utf8(unicode, utf8_str);
|
||||
str += utf8_str;
|
||||
} else {
|
||||
throw JsonInvalidEscapedSym(reader.get_curr_line(), reader.get_curr_col(), ch);
|
||||
}
|
||||
@@ -809,7 +823,125 @@ namespace simpleJson {
|
||||
node->set_value(str);
|
||||
}
|
||||
|
||||
void JsonParser::parseNumber(simpleJson::JsonReader &reader, simpleJson::JsonNodePtr &node) {}
|
||||
void JsonParser::parseNumber(simpleJson::JsonReader &reader, simpleJson::JsonNodePtr &node) {
|
||||
node->setValueType(JSON_TYPE_DOUBLE);
|
||||
bool sign = 1;
|
||||
double value = 0;
|
||||
bool exp_sign = 1;
|
||||
int exp_val = 0;
|
||||
int scale = 0, sub_scale = 0;
|
||||
|
||||
char ch = reader.curr_char();
|
||||
if (ch != '-' && !isdigit(ch)) {
|
||||
throw JsonInvalidSym(reader.get_curr_line(), reader.get_curr_col(), ch);
|
||||
}
|
||||
if (ch == '-') {
|
||||
sign = 0;
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
if (isdigit(ch) && ch != '0') {
|
||||
while(isdigit(ch)) {
|
||||
value = value * 10 + (ch - '0');
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
} else if (ch == '0') {
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
if (ch == '.') {
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
if (!isdigit(ch)) {
|
||||
throw JsonInvalidSym(reader.get_curr_line(), reader.get_curr_col(), ch);
|
||||
}
|
||||
while(isdigit(ch)) {
|
||||
sub_scale += 1;
|
||||
value = value + double(ch-'0')*std::pow(0.1, double(sub_scale));
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == 'e' || ch == 'E') {
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
|
||||
if (ch == '-') {
|
||||
exp_sign = 0;
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
} else if (ch == '+') {
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
|
||||
if (!isdigit(ch)) {
|
||||
throw JsonInvalidSym(reader.get_curr_line(), reader.get_curr_col(), ch);
|
||||
}
|
||||
while(isdigit(ch)) {
|
||||
exp_val = exp_val * 10 + (ch - '0');
|
||||
reader.get_char();
|
||||
ch = reader.curr_char();
|
||||
}
|
||||
|
||||
exp_val *= exp_sign ? 1 : -1;
|
||||
}
|
||||
|
||||
value = (value * (sign ? 1 : -1)) * std::pow(10, exp_val);
|
||||
node->set_value(value);
|
||||
}
|
||||
|
||||
|
||||
void JsonParser::to_json_string(std::string &_dst_str, bool _one_line) const {
|
||||
_dst_str.clear();
|
||||
root->to_json_string(_dst_str, false, 0, _one_line);
|
||||
}
|
||||
|
||||
bool JsonParser::save_to_file(const std::string &_file_path, bool _one_line) const {
|
||||
std::ofstream output_file_stream(_file_path);
|
||||
if (!output_file_stream) {
|
||||
throw FilePathNotValid(_file_path);
|
||||
}
|
||||
std::string json_str;
|
||||
to_json_string(json_str, _one_line);
|
||||
output_file_stream << json_str;
|
||||
output_file_stream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************************************/
|
||||
|
||||
void encode_utf8(long _unicode, std::string& _out)
|
||||
{
|
||||
if (_unicode < 0 || _unicode > 0x10FFFF)
|
||||
return;
|
||||
|
||||
_out.clear();
|
||||
if (_unicode <= 0x7F)
|
||||
{
|
||||
_out += static_cast<char>(_unicode);
|
||||
}
|
||||
else if (_unicode >= 0x80 && _unicode <= 0x7FF)
|
||||
{
|
||||
_out += static_cast<char>((_unicode >> 6) | 0xC0);
|
||||
_out += static_cast<char>((_unicode & 0x3F) | 0x80);
|
||||
}
|
||||
else if (_unicode >= 0x800 && _unicode <= 0xFFFF)
|
||||
{
|
||||
_out += static_cast<char>((_unicode >> 12) | 0xE0);
|
||||
_out += static_cast<char>(((_unicode >> 6) & 0x3F) | 0x80);
|
||||
_out += static_cast<char>((_unicode & 0x3F) | 0x80);
|
||||
}
|
||||
else if (_unicode >= 0x10000 && _unicode <= 0x10FFFF)
|
||||
{
|
||||
_out += static_cast<char>((_unicode >> 18) | 0xF0);
|
||||
_out += static_cast<char>(((_unicode >> 12) & 0x3F) | 0x80);
|
||||
_out += static_cast<char>(((_unicode >> 6) & 0x3F) | 0x80);
|
||||
_out += static_cast<char>((_unicode & 0x3F) | 0x80);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user