string ParseString() { size_t len; string str(NStr::ParseQuoted(CTempString(m_Ch, GetRemainder()), &len)); m_Ch += len; return str; }
CJsonNode CNetScheduleStructuredOutputParser::ParseObject(char closing_char) { CJsonNode result(CJsonNode::NewObjectNode()); while (isspace((unsigned char) *m_Ch)) ++m_Ch; if (*m_Ch == closing_char) { ++m_Ch; return result; } while (*m_Ch == '\'' || *m_Ch == '"') { // New attribute/value pair string attr_name(ParseString(GetRemainder())); while (isspace((unsigned char) *m_Ch)) ++m_Ch; if (*m_Ch == ':' || *m_Ch == '=') while (isspace((unsigned char) *++m_Ch)) ; result.SetByKey(attr_name, ParseValue()); if (!MoreNodes()) { if (*m_Ch != closing_char) break; ++m_Ch; return result; } } INVALID_FORMAT_ERROR(); }
CJsonNode CExecAndParseStructuredOutput::ParseNode() { switch (*m_Ch) { case '[': ++m_Ch; return ParseArray(); case '{': ++m_Ch; return ParseObject(false); case '\'': case '"': return CJsonNode::NewStringNode(ParseString()); } size_t max_len = GetRemainder(); size_t len = 1; switch (*m_Ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': while (len <= max_len && isdigit(m_Ch[len])) ++len; { CJsonNode::TNumber val(NStr::StringToInt8(CTempString(m_Ch, len))); m_Ch += len; return CJsonNode::NewNumberNode(val); } case 'F': case 'f': case 'N': case 'n': case 'T': case 't': case 'Y': case 'y': while (len <= max_len && isalpha(m_Ch[len])) ++len; { bool val(NStr::StringToBool(CTempString(m_Ch, len))); m_Ch += len; return CJsonNode::NewBooleanNode(val); } } return CJsonNode(); }
CJsonNode CNetScheduleStructuredOutputParser::ParseValue() { size_t max_len = GetRemainder(); size_t len = 0; switch (*m_Ch) { /* Array */ case '[': ++m_Ch; return ParseArray(']'); /* Object */ case '{': ++m_Ch; return ParseObject('}'); /* String */ case '\'': case '"': return CJsonNode::NewStringNode(ParseString(max_len)); /* Number */ case '-': // Check that there's at least one digit after the minus sign. if (max_len <= 1 || !isdigit((unsigned char) m_Ch[1])) { ++m_Ch; break; } len = 1; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // Skim through the integer part. do if (++len >= max_len) return CJsonNode::NewIntegerNode(ParseInt(len)); while (isdigit((unsigned char) m_Ch[len])); // Stumbled upon a non-digit character -- check // if it's a fraction part or an exponent part. switch (m_Ch[len]) { case '.': if (++len == max_len || !isdigit((unsigned char) m_Ch[len])) { NCBI_THROW2(CStringException, eFormat, "At least one digit after the decimal " "point is required", GetPosition()); } for (;;) { if (++len == max_len) return CJsonNode::NewDoubleNode(ParseDouble(len)); if (!isdigit((unsigned char) m_Ch[len])) { if (m_Ch[len] == 'E' || m_Ch[len] == 'e') break; return CJsonNode::NewDoubleNode(ParseDouble(len)); } } /* FALL THROUGH */ case 'E': case 'e': if (++len == max_len || (m_Ch[len] == '-' || m_Ch[len] == '+' ? ++len == max_len || !isdigit((unsigned char) m_Ch[len]) : !isdigit((unsigned char) m_Ch[len]))) { m_Ch += len; NCBI_THROW2(CStringException, eFormat, "Invalid exponent specification", GetPosition()); } while (++len < max_len && isdigit((unsigned char) m_Ch[len])) ; return CJsonNode::NewDoubleNode(ParseDouble(len)); default: return CJsonNode::NewIntegerNode(ParseInt(len)); } /* Constant */ case 'F': case 'f': case 'N': case 'n': case 'T': case 't': case 'Y': case 'y': while (len <= max_len && isalpha((unsigned char) m_Ch[len])) ++len; { CTempString val(m_Ch, len); m_Ch += len; return val == "null" ? CJsonNode::NewNullNode() : CJsonNode::NewBooleanNode(NStr::StringToBool(val)); } } INVALID_FORMAT_ERROR(); }