add PIJSON, yet without doc
This commit is contained in:
340
libs/main/core/pijson.cpp
Normal file
340
libs/main/core/pijson.cpp
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
JSON class
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "pijson.h"
|
||||||
|
|
||||||
|
|
||||||
|
//! \~\class PIJSON pijson.h
|
||||||
|
//! \~\details
|
||||||
|
//! \~english \section PIJSON_sec0 Synopsis
|
||||||
|
//! \~russian \section PIJSON_sec0 Краткий обзор
|
||||||
|
//! \~english
|
||||||
|
//!
|
||||||
|
//! \~russian
|
||||||
|
//!
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::newObject() {
|
||||||
|
PIJSON ret;
|
||||||
|
ret.c_type = Object;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::newArray() {
|
||||||
|
PIJSON ret;
|
||||||
|
ret.c_type = Array;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIJSON::setValue(const PIVariant & v) {
|
||||||
|
c_value = v;
|
||||||
|
switch (v.type()) {
|
||||||
|
case PIVariant::pivBool: c_type = Boolean; break;
|
||||||
|
case PIVariant::pivUChar:
|
||||||
|
case PIVariant::pivShort:
|
||||||
|
case PIVariant::pivUShort:
|
||||||
|
case PIVariant::pivInt:
|
||||||
|
case PIVariant::pivUInt:
|
||||||
|
case PIVariant::pivLLong:
|
||||||
|
case PIVariant::pivULLong:
|
||||||
|
case PIVariant::pivFloat:
|
||||||
|
case PIVariant::pivDouble:
|
||||||
|
case PIVariant::pivLDouble: c_type = Number; break;
|
||||||
|
case PIVariant::pivString: c_type = String; break;
|
||||||
|
default: c_type = Invalid; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIJSON::clear() {
|
||||||
|
c_type = Invalid;
|
||||||
|
c_value = PIVariant();
|
||||||
|
c_name.clear();
|
||||||
|
c_object.clear();
|
||||||
|
c_array.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIJSON::size() const {
|
||||||
|
if (!isArray())
|
||||||
|
return 0;
|
||||||
|
return c_array.size_s();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIJSON::contains(const PIString & key) const {
|
||||||
|
if (!isObject()) return false;
|
||||||
|
return c_object.contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIJSON::resize(int new_size) {
|
||||||
|
c_array.resize(new_size);
|
||||||
|
c_type = Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PIJSON & PIJSON::operator[](int index) const {
|
||||||
|
if (!isArray())
|
||||||
|
return nullEntry();
|
||||||
|
return c_array[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON & PIJSON::operator[](int index) {
|
||||||
|
c_type = Array;
|
||||||
|
PIJSON & ret(c_array[index]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON & PIJSON::operator=(const PIJSON & v) {
|
||||||
|
c_type = v.c_type;
|
||||||
|
c_value = v.c_value;
|
||||||
|
c_object = v.c_object;
|
||||||
|
c_array = v.c_array;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::operator[](const PIString & key) const {
|
||||||
|
if (!isObject())
|
||||||
|
return nullEntry();
|
||||||
|
if (!c_object.contains(key))
|
||||||
|
return nullEntry();
|
||||||
|
return c_object.value(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON & PIJSON::operator[](const PIString & key) {
|
||||||
|
c_type = Object;
|
||||||
|
PIJSON & ret(c_object[key]);
|
||||||
|
ret.c_name = key;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIJSON::toJSON() const {
|
||||||
|
PIString ret;
|
||||||
|
print(ret, *this, "", true);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::fromJSON(PIString str) {
|
||||||
|
return parseValue(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON & PIJSON::nullEntry() {
|
||||||
|
static PIJSON ret;
|
||||||
|
ret.clear();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIJSON::parseName(PIString & s) {
|
||||||
|
//piCout << "\n\n\n parseName" << s;
|
||||||
|
PIString ret;
|
||||||
|
ret = s.takeRange('"', '"');
|
||||||
|
s.trim();
|
||||||
|
if (s.isEmpty()) return PIString();
|
||||||
|
if (s[0] != ':') return PIString();
|
||||||
|
s.remove(0).trim();
|
||||||
|
return PIJSON::stringUnmask(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::parseValue(PIString & s) {
|
||||||
|
PIJSON ret;
|
||||||
|
//piCout << "\n\n\n parseValue" << s;
|
||||||
|
s.trim();
|
||||||
|
if (s.isEmpty()) return ret;
|
||||||
|
if (s[0] == '{')
|
||||||
|
ret = parseObject(s.takeRange('{', '}'));
|
||||||
|
else if (s[0] == '[')
|
||||||
|
ret = parseArray(s.takeRange('[', ']'));
|
||||||
|
else {
|
||||||
|
s.trim();
|
||||||
|
if (s.startsWith('"')) {
|
||||||
|
ret.c_type = PIJSON::String;
|
||||||
|
ret.c_value = PIJSON::stringUnmask(s.takeRange('"', '"'));
|
||||||
|
} else {
|
||||||
|
PIString value;
|
||||||
|
int ind = s.find(',');
|
||||||
|
if (ind >= 0) {
|
||||||
|
value = s.takeLeft(ind).trim().toLowerCase();
|
||||||
|
} else {
|
||||||
|
value = s;
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
|
//piCout << "\n\n\n parseValue value = \"" << value << "\"";
|
||||||
|
if (value == "null") {
|
||||||
|
ret.c_type = PIJSON::Null;
|
||||||
|
} else if (value == "true") {
|
||||||
|
ret.c_type = PIJSON::Boolean;
|
||||||
|
ret.c_value = true;
|
||||||
|
} else if (value == "false") {
|
||||||
|
ret.c_type = PIJSON::Boolean;
|
||||||
|
ret.c_value = false;
|
||||||
|
} else {
|
||||||
|
ret.c_type = PIJSON::Number;
|
||||||
|
ret.c_value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::parseObject(PIString s) {
|
||||||
|
//piCout << "\n\n\n parseObject" << s;
|
||||||
|
PIJSON ret;
|
||||||
|
ret.c_type = PIJSON::Object;
|
||||||
|
while (s.isNotEmpty()) {
|
||||||
|
PIString name = PIJSON::stringUnmask(parseName(s));
|
||||||
|
PIJSON value = parseValue(s);
|
||||||
|
auto & child(ret.c_object[name]);
|
||||||
|
child = value;
|
||||||
|
child.c_name = name;
|
||||||
|
s.trim();
|
||||||
|
if (s.isEmpty()) break;
|
||||||
|
if (s[0] != ',') break;
|
||||||
|
s.remove(0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIJSON PIJSON::parseArray(PIString s) {
|
||||||
|
//piCout << "\n\n\n parseArray" << s;
|
||||||
|
PIJSON ret;
|
||||||
|
ret.c_type = PIJSON::Array;
|
||||||
|
while (s.isNotEmpty()) {
|
||||||
|
PIJSON value = parseValue(s);
|
||||||
|
ret.c_array << value;
|
||||||
|
s.trim();
|
||||||
|
if (s.isEmpty()) break;
|
||||||
|
if (s[0] != ',') break;
|
||||||
|
s.remove(0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIJSON::stringMask(const PIString & s) {
|
||||||
|
PIString ret;
|
||||||
|
for (auto c: s) {
|
||||||
|
if (!c.isAscii()) {
|
||||||
|
ret += "\\u" + PIString::fromNumber(c.unicode16Code(), 16).expandLeftTo(4, '0');
|
||||||
|
} else {
|
||||||
|
char ca = c.toAscii();
|
||||||
|
switch (ca) {
|
||||||
|
case '"' : ret += "\\\""; break;
|
||||||
|
case '\\': ret += "\\\\"; break;
|
||||||
|
case '/' : ret += "\\/" ; break;
|
||||||
|
case '\b': ret += "\\b" ; break;
|
||||||
|
case '\f': ret += "\\f" ; break;
|
||||||
|
case '\n': ret += "\\n" ; break;
|
||||||
|
case '\r': ret += "\\r" ; break;
|
||||||
|
case '\t': ret += "\\t" ; break;
|
||||||
|
default: ret += ca;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIJSON::stringUnmask(const PIString & s) {
|
||||||
|
PIString ret;
|
||||||
|
for (int i = 0; i < s.size_s(); ++i) {
|
||||||
|
char ca = s[i].toAscii();
|
||||||
|
if (ca == '\\') {
|
||||||
|
if (i == s.size_s() - 1) continue;
|
||||||
|
++i;
|
||||||
|
char na = s[i].toAscii();
|
||||||
|
switch (na) {
|
||||||
|
case '"' : ret += '\"'; break;
|
||||||
|
case '\\': ret += '\\'; break;
|
||||||
|
case '/' : ret += '/' ; break;
|
||||||
|
case 'b' : ret += '\b'; break;
|
||||||
|
case 'f' : ret += '\f'; break;
|
||||||
|
case 'n' : ret += '\n'; break;
|
||||||
|
case 'r' : ret += '\r'; break;
|
||||||
|
case 't' : ret += '\t'; break;
|
||||||
|
case 'u' :
|
||||||
|
ret += PIChar(s.mid(i + 1, 4).toUShort(16));
|
||||||
|
i += 4;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret += s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIJSON::print(PIString & s, const PIJSON & v, PIString tab, bool transform, bool comma) {
|
||||||
|
s += tab;
|
||||||
|
/*
|
||||||
|
switch (v.c_type) {
|
||||||
|
case JSONEntry::Invalid: s << "(Invalid)"; break;
|
||||||
|
case JSONEntry::Null: s << "(Null)"; break;
|
||||||
|
case JSONEntry::Boolean: s << "(Boolean)"; break;
|
||||||
|
case JSONEntry::Number: s << "(Number)"; break;
|
||||||
|
case JSONEntry::String: s << "(String)"; break;
|
||||||
|
case JSONEntry::Object: s << "(Object)"; break;
|
||||||
|
case JSONEntry::Array: s << "(Array)"; break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (v.name().isNotEmpty()) s += '"' + (transform ? stringMask(v.name()) : v.name()) + "\": ";
|
||||||
|
switch (v.c_type) {
|
||||||
|
case PIJSON::Invalid: break;
|
||||||
|
case PIJSON::Null: s += "null"; break;
|
||||||
|
case PIJSON::Boolean: s += PIString::fromBool(v.c_value.toBool()); break;
|
||||||
|
case PIJSON::Number: s += v.c_value.toString(); break;
|
||||||
|
case PIJSON::String: s += '"' + (transform ? stringMask(v.c_value.toString()) : v.c_value.toString()) + '"'; break;
|
||||||
|
case PIJSON::Object:
|
||||||
|
s += "{\n";
|
||||||
|
{
|
||||||
|
PIString ntab = tab + " ";
|
||||||
|
auto it = v.c_object.makeIterator();
|
||||||
|
int cnt = 0;
|
||||||
|
while (it.next())
|
||||||
|
print(s, it.value(), ntab, transform, ++cnt < v.c_object.size_s());
|
||||||
|
}
|
||||||
|
s += tab + "}";
|
||||||
|
break;
|
||||||
|
case PIJSON::Array:
|
||||||
|
s += "[\n";
|
||||||
|
{
|
||||||
|
PIString ntab = tab + " ";
|
||||||
|
for (int i = 0; i < v.c_array.size_s(); ++i)
|
||||||
|
print(s, v.c_array[i], ntab, transform, i < v.c_array.size_s() - 1);
|
||||||
|
}
|
||||||
|
s += tab + "]";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (comma) s += ',';
|
||||||
|
s += "\n";
|
||||||
|
}
|
||||||
122
libs/main/core/pijson.h
Normal file
122
libs/main/core/pijson.h
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/*! \file pijson.h
|
||||||
|
* \ingroup Core
|
||||||
|
* \brief
|
||||||
|
* \~english JSON class
|
||||||
|
* \~russian Класс JSON
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
JSON class
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIJSON_H
|
||||||
|
#define PIJSON_H
|
||||||
|
|
||||||
|
#include "pivariant.h"
|
||||||
|
|
||||||
|
|
||||||
|
//! \ingroup Core
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english JSON class.
|
||||||
|
//! \~russian Класс JSON.
|
||||||
|
class PIP_EXPORT PIJSON {
|
||||||
|
friend PICout operator <<(PICout s, const PIJSON & v);
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Invalid,
|
||||||
|
Null,
|
||||||
|
Boolean,
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
Object,
|
||||||
|
Array
|
||||||
|
};
|
||||||
|
enum PrintType {
|
||||||
|
Compact,
|
||||||
|
Tree
|
||||||
|
};
|
||||||
|
PIJSON() {}
|
||||||
|
PIJSON(const PIJSON & o) = default;
|
||||||
|
|
||||||
|
static PIJSON newObject();
|
||||||
|
static PIJSON newArray();
|
||||||
|
|
||||||
|
const PIString & name() const {return c_name;}
|
||||||
|
const PIVector<PIJSON> & array() const {return c_array;}
|
||||||
|
const PIMap<PIString, PIJSON> & object() const {return c_object;}
|
||||||
|
const PIVariant & value() const {return c_value;}
|
||||||
|
bool toBool() const {return c_value.toBool();}
|
||||||
|
int toInt() const {return c_value.toInt();}
|
||||||
|
double toDouble() const {return c_value.toDouble();}
|
||||||
|
PIString toString() const {return c_value.toString();}
|
||||||
|
Type type() const {return c_type;}
|
||||||
|
bool isValid() const {return c_type != Invalid;}
|
||||||
|
bool isObject() const {return c_type == Object;}
|
||||||
|
bool isArray() const {return c_type == Array;}
|
||||||
|
void setValue(const PIVariant & v);
|
||||||
|
void clear();
|
||||||
|
int size() const;
|
||||||
|
bool contains(const PIString & key) const;
|
||||||
|
void resize(int new_size);
|
||||||
|
|
||||||
|
const PIJSON & operator[](int index) const;
|
||||||
|
PIJSON & operator[](int index);
|
||||||
|
PIJSON & operator=(const PIVariant & v) {setValue(v); return *this;}
|
||||||
|
PIJSON & operator=(const PIJSON & v);
|
||||||
|
|
||||||
|
PIJSON operator[](const PIString & key) const;
|
||||||
|
PIJSON & operator[](const PIString & key);
|
||||||
|
PIJSON operator[](const char * key) const {return (*this)[PIString::fromUTF8(key)];}
|
||||||
|
PIJSON & operator[](const char * key) {return (*this)[PIString::fromUTF8(key)];}
|
||||||
|
|
||||||
|
PIString toJSON() const;
|
||||||
|
static PIJSON fromJSON(PIString str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PIJSON & nullEntry();
|
||||||
|
static PIString parseName(PIString & s);
|
||||||
|
static PIJSON parseValue(PIString & s);
|
||||||
|
static PIJSON parseObject(PIString s);
|
||||||
|
static PIJSON parseArray(PIString s);
|
||||||
|
static PIString stringMask(const PIString & s);;
|
||||||
|
static PIString stringUnmask(const PIString & s);;
|
||||||
|
static void print(PIString & s, const PIJSON & v, PIString tab, bool transform = false, bool comma = false);
|
||||||
|
|
||||||
|
PIString c_name;
|
||||||
|
PIVariant c_value;
|
||||||
|
PIVector<PIJSON> c_array;
|
||||||
|
PIMap<PIString, PIJSON> c_object;
|
||||||
|
Type c_type = Invalid;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PICout
|
||||||
|
//! \~english Output operator to \a PICout.
|
||||||
|
//! \~russian Оператор вывода в \a PICout.
|
||||||
|
inline PICout operator <<(PICout s, const PIJSON & v) {
|
||||||
|
s.space();
|
||||||
|
s.saveAndSetControls(0);
|
||||||
|
PIString str;
|
||||||
|
PIJSON::print(str, v, "");
|
||||||
|
s << str;
|
||||||
|
s.restoreControls();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PICONSTCHARS_H
|
||||||
217
main.cpp
217
main.cpp
@@ -2,178 +2,61 @@
|
|||||||
#include "piiostream.h"
|
#include "piiostream.h"
|
||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
#include "pimathbase.h"
|
#include "pimathbase.h"
|
||||||
|
#include "pijson.h"
|
||||||
|
|
||||||
using namespace PICoutManipulators;
|
using namespace PICoutManipulators;
|
||||||
|
|
||||||
template <typename T>
|
typedef PIMap<PIString, PIVariant> PIVariantMap;
|
||||||
T toDecimal(const PIString & s) {
|
typedef PIVector<PIVariant> PIVariantVector;
|
||||||
int part = 0, exp = 0;
|
|
||||||
bool negative = false, negative_exp = false, err = false, has_digit = false;
|
REGISTER_VARIANT(PIVariantMap);
|
||||||
T ret = 0., frac = 0., frac_delim = 1.;
|
REGISTER_VARIANT(PIVariantVector);
|
||||||
for (const PIChar pc: s) {
|
|
||||||
char c = pc.toAscii();
|
const char J[] =
|
||||||
switch (part) {
|
"[ \n"
|
||||||
case 0: // sign
|
"{ \n"
|
||||||
if (pc.isSpace()) continue;
|
" \"idFligth\":\"456123\", \n"
|
||||||
if (c >= '0' && c <= '9') {
|
" \"FligthPath\": \"d:/orders/nicirt/BSK-52(BBR)/219031.001/EBN-NM-BBR.IMG\",\n"
|
||||||
has_digit = true;
|
" \"FligthDataPath\": \"\", \n"
|
||||||
ret = c - '0';
|
" \"Passport\": \n"
|
||||||
part = 1;
|
" { \n"
|
||||||
continue;
|
" \"id\": \"\", \n"
|
||||||
}
|
" \"TypePlane\": \"\", \n"
|
||||||
if (c == '+') {
|
" \"FA_PLANEBORT\": \"Ka52-10\" \n"
|
||||||
part = 1;
|
" } \n"
|
||||||
continue;
|
" }, [1.1,2,3,4,{\"a\":null},{\"bool\":true,\"bool2\":false}] \n"
|
||||||
}
|
"] \n"
|
||||||
if (c == '-') {
|
;
|
||||||
negative = true;
|
|
||||||
part = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '.' || c == ',') {
|
|
||||||
part = 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = true;
|
|
||||||
break;
|
|
||||||
case 1: // integer
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
has_digit = true;
|
|
||||||
ret = ret * 10 + (c - '0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '.' || c == ',') {
|
|
||||||
part = 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((c == 'e' || c == 'E') && has_digit) {
|
|
||||||
part = 3;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = true;
|
|
||||||
break;
|
|
||||||
case 2: // fractional
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
has_digit = true;
|
|
||||||
frac = frac * 10 + (c - '0');
|
|
||||||
frac_delim *= 10.;
|
|
||||||
//piCout << frac << frac_delim;
|
|
||||||
//printf("%.20f %.20f\n", frac, T(c - '0') / frac_delim);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((c == 'e' || c == 'E') && has_digit) {
|
|
||||||
part = 3;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = true;
|
|
||||||
break;
|
|
||||||
case 3: // exponent with sign
|
|
||||||
if (c == '+') {
|
|
||||||
part = 4;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '-') {
|
|
||||||
negative_exp = true;
|
|
||||||
part = 4;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case 4: // exponent
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
exp = (exp * 10) + (c - '0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (err) break;
|
|
||||||
}
|
|
||||||
frac /= frac_delim;
|
|
||||||
ret += frac;
|
|
||||||
if (negative && has_digit) ret = -ret;
|
|
||||||
if (exp > 0) {
|
|
||||||
if (negative_exp) ret /= pow10((T)exp);
|
|
||||||
else ret *= pow10((T)exp);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void test(const PIString & s) {
|
|
||||||
double av = atof(s.dataAscii());
|
|
||||||
double v = toDecimal<double>(s);
|
|
||||||
printf("\n");
|
|
||||||
piCout << s << "=" << v << av;
|
|
||||||
printf("atof = %.20f\n", av);
|
|
||||||
printf(" PIP = %.20f\n", v);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
/*test(" 123 ");
|
PIString s;
|
||||||
test("\n123 ");
|
s = PIString::fromUTF8(J).trim();
|
||||||
test("\t123 ");
|
s = PIString::fromUTF8("{\"st\\u0426r\":\"\\\\ \\\" \\u0425\\u0430\\n\"}");
|
||||||
test(" +123 ");
|
//s = PIString::fromUTF8("{\"str\":\"Ха\"}");
|
||||||
test(" ++123 ");
|
PIJSON json = PIJSON::fromJSON(s);
|
||||||
test(" + 123 ");
|
piCout << json;
|
||||||
test(" -123 ");
|
piCout << json.toJSON();
|
||||||
test(" --123 ");
|
//json.resize(3);
|
||||||
test(" - 123 ");
|
//json["0"].setValue(123);
|
||||||
test("123.1");
|
//json["1"].setValue("sec");
|
||||||
test("123 .1");
|
//json["2"]["f"].setValue(true);
|
||||||
test("123 . 1");
|
//json["2"]["s"].setValue(-1);*/
|
||||||
test("123.+1");
|
//json[0]["Passport"]["id"] = 0xFF;
|
||||||
test("123.-1");
|
//piCout << json;
|
||||||
test("123E2");
|
json = PIJSON::newObject();
|
||||||
test("123E+2");
|
json["num"] = 123;
|
||||||
test("123E +2");
|
json["str__"] = PIString::fromUTF8("string русский ℃ 😆 ");
|
||||||
test("123E+ 2");
|
json["obj"]["b"] = true;
|
||||||
test("123E + 2");
|
json["obj"]["i"] = -1;
|
||||||
test("123 E+2");
|
auto & arr(json["obj"]["arr"]);
|
||||||
test("123 E +2");
|
arr.resize(3);
|
||||||
test("123 E+ 2");
|
arr[0] = 10;
|
||||||
test("123 E + 2");
|
arr[1] = 11.2E-1;
|
||||||
test("123E+2.5");
|
arr[2] = "!!!";
|
||||||
test("123.4E+2");
|
json["obj2"] = json["obj"];
|
||||||
test("123.4.5E+2");
|
//piCout << json;
|
||||||
test("123EE+2");
|
piCout << json.toJSON();
|
||||||
test("123e+2");
|
piCout << json["str__"].toString().toUTF8();
|
||||||
test("123e++2");
|
|
||||||
test("E+2");
|
|
||||||
test("1E+2");
|
|
||||||
test("1.E+2");
|
|
||||||
test(".E+2");
|
|
||||||
test(".1E-2");
|
|
||||||
test("+E2");
|
|
||||||
test("nan");
|
|
||||||
test("inf");*/
|
|
||||||
test("-");
|
|
||||||
test("-0");
|
|
||||||
test("-.");
|
|
||||||
test("-.0");
|
|
||||||
test(".23456123456789987654");
|
|
||||||
test("-E+100");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
PITimeMeasurer tm;
|
|
||||||
PIString s("1.23456789");
|
|
||||||
int cnt = 10000000;
|
|
||||||
int el_o = 0, el_n = 0;
|
|
||||||
double v = 0.;
|
|
||||||
NO_UNUSED(v);
|
|
||||||
|
|
||||||
tm.reset();
|
|
||||||
piForTimes (cnt) {
|
|
||||||
v = s.toDouble();
|
|
||||||
}
|
|
||||||
el_o = tm.elapsed_u();
|
|
||||||
piCout << v << el_o;
|
|
||||||
|
|
||||||
tm.reset();
|
|
||||||
piForTimes (cnt) {
|
|
||||||
v = toDecimal<double>(s);
|
|
||||||
}
|
|
||||||
el_n = tm.elapsed_u();
|
|
||||||
piCout << v << el_n;
|
|
||||||
|
|
||||||
piCout << (double)el_o / el_n;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user