void ParserImpl::handleArray() { json_type tok = json_peek(_pJSON); while (tok != JSON_ARRAY_END && checkError()) { handle(); tok = json_peek(_pJSON); } if (tok == JSON_ARRAY_END) handle(); else throw JSONException("JSON array end not found"); }
bool JSON::hasEscapes() const { Pos pos = ptr_begin + 1; while (pos < ptr_end && *pos != '"' && *pos != '\\') ++pos; if (*pos == '"') return false; else if (*pos == '\\') return true; throw JSONException("JSON: unexpected end of data."); }
JSON JSON::operator[] (size_t n) const { ElementType type = getType(); if (type != TYPE_ARRAY) throw JSONException("JSON: not array when calling operator[](size_t) method."); Pos pos = ptr_begin; ++pos; checkPos(pos); size_t i = 0; const_iterator it = begin(); while (i < n && it != end()) ++it, ++i; if (i != n) throw JSONException("JSON: array index " + Poco::NumberFormatter::format(n) + " out of bounds."); return *it; }
JSON::Pos JSON::skipString() const { //std::cerr << "skipString()\t" << data() << std::endl; Pos pos = ptr_begin; checkPos(pos); if (*pos != '"') throw JSONException(std::string("JSON: expected \", got ") + *pos); ++pos; /// fast path: находим следующую двойную кавычку. Если перед ней нет бэкслеша - значит это конец строки (при допущении корректности JSON). Pos closing_quote = reinterpret_cast<const char *>(memchr(reinterpret_cast<const void *>(pos), '\"', ptr_end - pos)); if (nullptr != closing_quote && closing_quote[-1] != '\\') return closing_quote + 1; /// slow path while (pos < ptr_end && *pos != '"') { if (*pos == '\\') { ++pos; checkPos(pos); if (*pos == 'u') { pos += 4; checkPos(pos); } } ++pos; } checkPos(pos); if (*pos != '"') throw JSONException(std::string("JSON: expected \", got ") + *pos); ++pos; return pos; }
void ParserImpl::handleObject() { json_type tok = json_peek(_pJSON); while (tok != JSON_OBJECT_END && checkError()) { json_next(_pJSON); if (_pHandler) _pHandler->key(std::string(json_get_string(_pJSON, NULL))); handle(); tok = json_peek(_pJSON); } if (tok == JSON_OBJECT_END) handle(); else throw JSONException("JSON object end not found"); }
JSON::Pos JSON::skipNameValuePair() const { //std::cerr << "skipNameValuePair()\t" << data() << std::endl; Pos pos = skipString(); checkPos(pos); if (*pos != ':') throw JSONException("JSON: expected :."); ++pos; return JSON(pos, ptr_end, level + 1).skipElement(); }
bool JSON::hasSpecialChars() const { Pos pos = ptr_begin + 1; while (pos < ptr_end && *pos != '"' && *pos != '\\' && *pos != '\r' && *pos != '\n' && *pos != '\t' && *pos != '\f' && *pos != '\b' && *pos != '\0' && *pos != '\'') ++pos; if (*pos == '"') return false; else if (pos < ptr_end) return true; throw JSONException("JSON: unexpected end of data."); }
void xmm::Label::from_json(JSONNode root) { try { if (root.type() != JSON_NODE) throw JSONException("Wrong type: was expecting 'JSON_NODE'", root.name()); JSONNode::const_iterator root_it = root.begin(); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->name() != "type") throw JSONException("Wrong name: was expecting 'type'", root_it->name()); if (root_it->type() != JSON_STRING) throw JSONException("Wrong type: was expecting 'JSON_STRING'", root_it->name()); if (root_it->as_string() == "INT") type = INT; else type = SYM; ++root_it; if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->name() != "value") throw JSONException("Wrong name: was expecting 'value'", root_it->name()); if (type == INT) { if (root_it->type() != JSON_NUMBER) throw JSONException("Wrong type: was expecting 'JSON_NUMBER'", root_it->name()); intLabel_ = static_cast<int>(root_it->as_int()); } else { if (root_it->type() != JSON_STRING) throw JSONException("Wrong type: was expecting 'JSON_STRING'", root_it->name()); symLabel_ = root_it->as_string(); } } catch (JSONException &e) { throw JSONException(e, root.name()); } catch (std::exception &e) { throw JSONException(e, root.name()); } }
MessageWraper& MessageWraper::getObject(const std::string& key){ CObjIter objIter = innerObjects.find(key); if(objIter!=innerObjects.end()){ return *(objIter->second); } CIter iter = messages.find(key); if(iter!=messages.end()){ MessageWraper* newObj = new MessageWraper; parseJson(iter->second.c_str(),*newObj); innerObjects[key] = newObj; typeMap[key] = JSONObjectType::OBJECT; return *newObj; }else{ throw JSONException("key not exist",-1); } }
JSON::iterator JSON::iterator::begin() const { ElementType type = getType(); if (type != TYPE_ARRAY && type != TYPE_OBJECT) throw JSONException("JSON: not array or object when calling begin() method."); //std::cerr << "begin()\t" << data() << std::endl; Pos pos = ptr_begin + 1; checkPos(pos); if (*pos == '}' || *pos == ']') return end(); return JSON(pos, ptr_end, level + 1); }
JSON::Pos JSON::skipBool() const { //std::cerr << "skipBool()\t" << data() << std::endl; Pos pos = ptr_begin; checkPos(pos); if (*ptr_begin == 't') pos += 4; else if (*ptr_begin == 'f') pos += 5; else throw JSONException("JSON: expected true or false."); return pos; }
/// Прочитать знаковое целое в простом формате из не-0-terminated строки. static Int64 readIntText(const char * buf, const char * end) { bool negative = false; Int64 x = 0; if (buf == end) throw JSONException("JSON: cannot parse signed integer: unexpected end of data."); bool run = true; while (buf != end && run) { switch (*buf) { case '+': break; case '-': negative = true; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': x *= 10; x += *buf - '0'; break; default: run = false; break; } ++buf; } if (negative) x = -x; return x; }
JSON::ElementType JSON::getType() const { switch (*ptr_begin) { case '{': return TYPE_OBJECT; case '[': return TYPE_ARRAY; case 't': case 'f': return TYPE_BOOL; case 'n': return TYPE_NULL; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return TYPE_NUMBER; case '"': { /// Проверим - это просто строка или name-value pair Pos after_string = skipString(); if (after_string < ptr_end && *after_string == ':') return TYPE_NAME_VALUE_PAIR; else return TYPE_STRING; } default: throw JSONException(std::string("JSON: unexpected char ") + *ptr_begin + ", expected one of '{[tfn-0123456789\"'"); } }
/// Прочитать число с плавающей запятой в простом формате, с грубым округлением, из не-0-terminated строки. static double readFloatText(const char * buf, const char * end) { bool negative = false; double x = 0; bool after_point = false; double power_of_ten = 1; if (buf == end) throw JSONException("JSON: cannot parse floating point number: unexpected end of data."); bool run = true; while (buf != end && run) { switch (*buf) { case '+': break; case '-': negative = true; break; case '.': after_point = true; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (after_point) { power_of_ten /= 10; x += (*buf - '0') * power_of_ten; } else { x *= 10; x += *buf - '0'; } break; case 'e': case 'E': { ++buf; Int32 exponent = readIntText(buf, end); x *= exp10(exponent); run = false; break; } default: run = false; break; } ++buf; } if (negative) x = -x; return x; }
std::string JSON::getString() const { Pos s = ptr_begin; if (*s != '"') throw JSONException(std::string("JSON: expected \", got ") + *s); ++s; checkPos(s); std::string buf; do { Pos p = find_first_symbols<'\\','"'>(s, ptr_end); if (p >= ptr_end) { break; } buf.append(s, p); s = p; switch (*s) { case '\\': ++s; checkPos(s); switch(*s) { case '"': buf += '"'; break; case '\\': buf += '\\'; break; case '/': buf += '/'; break; case 'b': buf += '\b'; break; case 'f': buf += '\f'; break; case 'n': buf += '\n'; break; case 'r': buf += '\r'; break; case 't': buf += '\t'; break; case 'u': { Poco::UTF8Encoding utf8; ++s; checkPos(s + 4); std::string hex(s, 4); s += 3; int unicode; try { unicode = Poco::NumberParser::parseHex(hex); } catch (const Poco::SyntaxException & e) { throw JSONException("JSON: incorrect syntax: incorrect HEX code."); } buf.resize(buf.size() + 6); /// максимальный размер UTF8 многобайтовой последовательности int res = utf8.convert(unicode, reinterpret_cast<unsigned char *>(const_cast<char*>(buf.data())) + buf.size() - 6, 6); if (!res) throw JSONException("JSON: cannot convert unicode " + Poco::NumberFormatter::format(unicode) + " to UTF8."); buf.resize(buf.size() - 6 + res); break; } default: buf += *s; break; } ++s; break; case '"': return buf; default: throw JSONException("find_first_symbols<...>() failed in unexpected way"); } } while (s < ptr_end); throw JSONException("JSON: incorrect syntax (expected end of string, found end of JSON)."); }
void xmm::TrainingSet::from_json(JSONNode root) { if (!owns_data) throw std::runtime_error("Cannot read Training Set with Shared memory"); try { if (root.type() != JSON_NODE) throw JSONException("Wrong type: was expecting 'JSON_NODE'", root.name()); JSONNode::const_iterator root_it = root.begin(); // Get Number of modalities root_it = root.find("bimodal"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_BOOL) throw JSONException("Wrong type for node 'bimodal': was expecting 'JSON_BOOL'", root_it->name()); if(bimodal_ != root_it->as_bool()) { if (bimodal_) throw JSONException("Trying to read an unimodal model in a bimodal model.", root.name()); else throw JSONException("Trying to read a bimodal model in an unimodal model.", root.name()); } // Get Dimension root_it = root.find("dimension"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_NUMBER) throw JSONException("Wrong type for node 'dimension': was expecting 'JSON_NUMBER'", root_it->name()); dimension_ = static_cast<unsigned int>(root_it->as_int()); // Get Input Dimension if bimodal_ if (bimodal_){ root_it = root.find("dimension_input"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_NUMBER) throw JSONException("Wrong type for node 'dimension_input': was expecting 'JSON_NUMBER'", root_it->name()); dimension_input_ = static_cast<unsigned int>(root_it->as_int()); } // Get Column Names column_names_.assign(dimension_, ""); root_it = root.find("column_names"); if (root_it != root.end()) { if (root_it->type() != JSON_ARRAY) throw JSONException("Wrong type for node 'column_names': was expecting 'JSON_ARRAY'", root_it->name()); json2vector(*root_it, column_names_, dimension_); } // Get Size: Number of Phrases root_it = root.find("size"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_NUMBER) throw JSONException("Wrong type for node 'size': was expecting 'JSON_NUMBER'", root_it->name()); unsigned int ts_size = static_cast<unsigned int>(root_it->as_int()); // Get Default label root_it = root.find("defaultlabel"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_NODE) throw JSONException("Wrong type for node 'defaultlabel': was expecting 'JSON_NODE'", root_it->name()); defaultLabel_.from_json(*root_it); // Get Phrases phrases.clear(); phraseLabels.clear(); root_it = root.find("phrases"); if (root_it == root.end()) throw JSONException("JSON Node is incomplete", root_it->name()); if (root_it->type() != JSON_ARRAY) throw JSONException("Wrong type for node 'phrases': was expecting 'JSON_ARRAY'", root_it->name()); for (unsigned int i=0 ; i<ts_size ; i++) { JSONNode::const_iterator array_it = (*root_it)[i].end(); // Get Index array_it = (*root_it)[i].find("index"); if (array_it == (*root_it)[i].end()) throw JSONException("JSON Node is incomplete", array_it->name()); if (array_it->type() != JSON_NUMBER) throw JSONException("Wrong type for node 'index': was expecting 'JSON_NUMBER'", array_it->name()); unsigned int phraseIndex = static_cast<unsigned int>(array_it->as_int()); // Get Label array_it = (*root_it)[i].find("label"); if (array_it == (*root_it)[i].end()) throw JSONException("JSON Node is incomplete", array_it->name()); if (array_it->type() != JSON_NODE) throw JSONException("Wrong type for node 'label': was expecting 'JSON_NODE'", array_it->name()); phraseLabels[phraseIndex].from_json(*array_it); updateLabelList(); // Get Phrase Content array_it = (*root_it)[i].find("Phrase"); if (array_it == (*root_it)[i].end()) throw JSONException("JSON Node is incomplete", array_it->name()); if (array_it->type() != JSON_NODE) throw JSONException("Wrong type for node 'Phrase': was expecting 'JSON_NODE'", array_it->name()); phrases[phraseIndex] = new Phrase(flags_, dimension_, dimension_input_); phrases[phraseIndex]->from_json(*array_it); } if (ts_size != phrases.size()) throw JSONException("Number of phrases does not match", root_it->name()); has_changed_ = true; } catch (JSONException &e) { throw JSONException(e, root.name()); } catch (std::exception &e) { throw JSONException(e, root.name()); } }
JSONBase& JSONObject::operator[](const std::string& key) { std::map<std::string, JSONBase*>::const_iterator it = dictionary.find(key); if (it == dictionary.end()) throw JSONException("Key does not exist."); return *(it->second); }
JSONBase& JSONObject::operator[](unsigned int) { throw JSONException("Not a dictionary."); }
void JSON::checkPos(Pos pos) const { if (pos >= ptr_end) throw JSONException("JSON: unexpected end of data."); }
void ParserImpl::handle() { enum json_type type = json_next(_pJSON); switch (type) { case JSON_DONE: return; case JSON_NULL: _pHandler->null(); break; case JSON_TRUE: if (_pHandler) _pHandler->value(true); break; case JSON_FALSE: if (_pHandler) _pHandler->value(false); break; case JSON_NUMBER: { if (_pHandler) { std::string str(json_get_string(_pJSON, NULL)); if (str.find(_decimalPoint) != str.npos || str.find('e') != str.npos || str.find('E') != str.npos) { _pHandler->value(NumberParser::parseFloat(str)); } else { Poco::Int64 val; if (NumberParser::tryParse64(str, val)) _pHandler->value(val); else _pHandler->value(NumberParser::parseUnsigned64(str)); } } break; } case JSON_STRING: if (_pHandler) _pHandler->value(std::string(json_get_string(_pJSON, NULL))); break; case JSON_OBJECT: if (_pHandler) _pHandler->startObject(); handleObject(); break; case JSON_OBJECT_END: if (_pHandler) _pHandler->endObject(); return; case JSON_ARRAY: if (_pHandler) _pHandler->startArray(); handleArray(); break; case JSON_ARRAY_END: if (_pHandler) _pHandler->endArray(); return; case JSON_ERROR: { const char* pErr = json_get_error(_pJSON); std::string err(pErr ? pErr : "JSON parser error."); throw JSONException(err); } } }