add parser unicode

This commit is contained in:
Junior
2024-01-05 14:10:55 +08:00
parent cd80c3b2a0
commit 58efd6e4b3
4 changed files with 176 additions and 2 deletions
+25
View File
@@ -13,6 +13,7 @@
namespace simpleJson {
const std::string_view SYNTAX_ERROR = "Syntax Error";
const std::string_view INVALID_TYPE = "Invalid Type";
const std::string_view FILE_NOT_FOUND = "File Not Found";
class JsonException : public std::exception {
protected:
@@ -23,6 +24,18 @@ namespace simpleJson {
virtual ~JsonException() = default;
};
class FilePathNotValid : public JsonException {
public:
FilePathNotValid(std::string_view str) : JsonException{str} {}
const char *what() {
std::stringstream ss;
ss << "[JsonFileNotFound]File path\"" << message << "\" is not valid";
return ss.str().c_str();
}
};
class JsonTypeError : public JsonException {
protected:
std::string function_name;
@@ -83,6 +96,18 @@ namespace simpleJson {
return ss.str().c_str();
}
};
class JsonInvalidUnicodeSym : public JsonInvalidSym {
public:
JsonInvalidUnicodeSym(int line, int column, char detail) : JsonInvalidSym{line, column, detail} {}
const char *what() {
std::stringstream ss;
ss << "[JsonParseError]" << message << " :invalid unicode symbol " << detail << " at line " << line
<< " column " << column << " detail " << detail;
return ss.str().c_str();
}
};
}
#endif //SIMPLEJSON_EXCEPTION_H
+134 -2
View File
@@ -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);
}
}
}
+3
View File
@@ -194,6 +194,9 @@ namespace simpleJson {
bool save_to_file(const std::string &_file_path, bool _one_line = 0) const;
};
void encode_utf8(long _unicode, std::string &_out);
}
#endif //SIMPLEJSON_JSON_H