CJsonNode CJsonNode::GuessType(const CTempString& value) { const char* ch = value.begin(); const char* end = value.end(); switch (*ch) { case '"': case '\'': return NewStringNode(NStr::ParseQuoted(value)); case '-': if (++ch >= end || !isdigit(*ch)) return NewStringNode(value); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do if (++ch >= end) return NewIntegerNode(NStr::StringToInt8(value)); while (isdigit(*ch)); switch (*ch) { case '.': if (++ch == end || !isdigit(*ch)) return NewStringNode(value); for (;;) { if (++ch == end) return NewDoubleNode(NStr::StringToDouble(value)); if (!isdigit(*ch)) { if (*ch == 'E' || *ch == 'e') break; return NewStringNode(value); } } /* FALL THROUGH */ case 'E': case 'e': if (++ch < end && (*ch == '-' || *ch == '+' ? ++ch < end && isdigit(*ch) : isdigit(*ch))) do if (++ch == end) return NewDoubleNode(NStr::StringToDouble(value)); while (isdigit(*ch)); /* FALL THROUGH */ default: return NewStringNode(value); } } return NStr::CompareNocase(value, "false") == 0 ? NewBooleanNode(false) : NStr::CompareNocase(value, "true") == 0 ? NewBooleanNode(true) : NStr::CompareNocase(value, "none") == 0 ? NewNullNode() : NewStringNode(value); }
static bool IsInteger(const CTempString& value) { if (value.empty()) return false; const char* digit = value.end(); while (--digit > value.begin()) if (!isdigit(*digit)) return false; return isdigit(*digit) || (*digit == '-' && value.length() > 1); }
string CDBParamVariant::MakePlainName(const CTempString& name) { // Do not make copy of name to process it ... CTempString plain_name; CTempString::const_iterator begin_str = NULL, c = name.data(); for (; c != NULL && c != name.end(); ++c) { char ch = *c; if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { if (begin_str == NULL) { // Remove whitespaces ... continue; } else { // Look forward for non-space characters. bool space_chars_only = true; for (const char* tc = c; tc != NULL && *tc != '\0'; ++tc) { char tch = *tc; if (tch == ' ' || tch == '\t' || tch == '\n' || tch == '\r') { continue; } else { space_chars_only = false; break; } } if (space_chars_only) { // Remove trailing whitespace ... break; } } } // Check for leading symbol ... if (begin_str == NULL) { begin_str = c; if (ch == ':' || ch == '@' || ch == '$' || ch == '%') { // Skip leading symbol ... ++begin_str; } } } if (begin_str != NULL) { plain_name.assign(begin_str, c - begin_str); } return plain_name; }
CTempString CDBParamVariant::MakeName(const CTempString& name, CDBParamVariant::ENameFormat& format) { // Do not make copy of name to process it ... CTempString new_name; CTempString::const_iterator begin_str = NULL, c = name.data(); format = ePlainName; for (; c != NULL && c != name.end(); ++c) { char ch = *c; if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { if (begin_str == NULL) { // Remove whitespace ... continue; } else { // Look forward for non-space characters. bool space_chars_only = true; for (const char* tc = c; tc != NULL && *tc != '\0'; ++tc) { char tch = *tc; if (tch == ' ' || tch == '\t' || tch == '\n' || tch == '\r') { continue; } else { space_chars_only = false; break; } } if (space_chars_only) { // Remove trailing whitespace ... break; } } } // Check for leading symbol ... if (begin_str == NULL) { begin_str = c; switch (ch) { case '?' : format = eQMarkName; break; case ':' : if (*(c + 1)) { if (isdigit(*(c + 1))) { format = eNumericName; } else { format = eNamedName; } } else { DATABASE_DRIVER_ERROR("Invalid parameter format.", 1); } break; case '@' : format = eSQLServerName; break; case '%' : format = eFormatName; break; case '$' : // !!!! format = eFormatName; break; } } } if (begin_str != NULL) { new_name.assign(begin_str, c - begin_str); } return new_name; }