charParser::get_next_token() { while (std::isspace(m_str[m_idx])) m_idx++; if (m_idx >= m_str.size()) throw std::logic_error("unexpected character in parse json"); //如果是注释,记得跳过 skip_comment(); return m_str[m_idx]; }
JObject Parser::parse_number() { auto pos = m_idx; //整数部分 if (m_str[m_idx] == '-') { m_idx++; } if (isdigit(m_str[m_idx])) while (isdigit(m_str[m_idx])) m_idx++; else { throw std::logic_error("invalid character in number"); }
//小数部分 if (m_str[m_idx] == '.') { m_idx++; if (!std::isdigit(m_str[m_idx])) { throw std::logic_error("at least one digit required in parse float part!"); } while (std::isdigit(m_str[m_idx])) m_idx++; } returnstrtof64(m_str.c_str() + pos, nullptr); }
void *JObject::value() { switch (m_type) { case T_NULL: returnget_if<str_t>(&m_value); case T_BOOL: returnget_if<bool_t>(&m_value); case T_INT: returnget_if<int_t>(&m_value); case T_DOUBLE: returnget_if<double_t>(&m_value); case T_LIST: returnget_if<list_t>(&m_value); case T_DICT: returnget_if<dict_t>(&m_value); case T_STR: return std::get_if<str_t>(&m_value); default: returnnullptr; } } ```
- Value方法: ```c++ #define THROW_GET_ERROR(erron) throw std::logic_error("type error in get "#erron" value!")
template<class V> V &Value() { //添加安全检查 ifconstexpr(IS_TYPE(V, str_t)) { if (m_type != T_STR) THROW_GET_ERROR(string); } elseifconstexpr(IS_TYPE(V, bool_t)) { if (m_type != T_BOOL) THROW_GET_ERROR(BOOL); } elseifconstexpr(IS_TYPE(V, int_t)) { if (m_type != T_INT) THROW_GET_ERROR(INT); } elseifconstexpr(IS_TYPE(V, double_t)) { if (m_type != T_DOUBLE) THROW_GET_ERROR(DOUBLE); } elseifconstexpr(IS_TYPE(V, list_t)) { if (m_type != T_LIST) THROW_GET_ERROR(LIST); } elseifconstexpr(IS_TYPE(V, dict_t)) { if (m_type != T_DICT) THROW_GET_ERROR(DICT); }
void *v = value(); if (v == nullptr) throw std::logic_error("unknown type in JObject::Value()"); return *((V *) v); //强转 }
string JObject::to_string() { void *value = this->value(); std::ostringstream os; switch (m_type) { case T_NULL: os << "null"; break; case T_BOOL: if (GET_VALUE(bool)) os << "true"; else os << "false"; break; case T_INT: os << GET_VALUE(int); break; case T_DOUBLE: os << GET_VALUE(double); break; case T_STR: os << '\"' << GET_VALUE(string) << '\"'; break; case T_LIST: { list_t &list = GET_VALUE(list_t); os << '['; for (auto i = 0; i < list.size(); i++) { if (i != list.size() - 1) { os << ((list[i]).to_string()); os << ','; } else os << ((list[i]).to_string()); } os << ']'; break; } case T_DICT: { dict_t &dict = GET_VALUE(dict_t); os << '{'; for (auto it = dict.begin(); it != dict.end(); ++it) { if (it != dict.begin()) //为了保证最后的json格式正确 os << ','; os << '\"' << it->first << "\":" << it->second.to_string(); } os << '}'; break; } default: return""; } return os.str(); }