Exemple #1
0
std::set<ValueKey> JsonDb::Transaction::Walk()
{
	std::set<ValueKey> keys;

 	// initialize the iterator 
  if(!vlcurfirst(db.get()))
		throw std::runtime_error("Failed to initialize database iterator");

	CharPtr key;
	while((key = CharPtr(vlcurkey(db.get(), NULL))) != NULL)
	{
		keys.insert(*(ValueKey const *)key.get());
		vlcurnext(db.get());
	}

	return keys;
}
Exemple #2
0
ValuePointer JsonDb::Transaction::Retrieve(ValueKey key)
{
	if(key == null_key)
		return null_element;

	// std::cout << "Retrieve: key=" << key << std::endl;

	// Then retrieve the actual data
	int value_size;
	CharPtr val = CharPtr(vlget(db.get(), (char const *)&key, sizeof(ValueKey), &value_size));

	if(val.get() == NULL)
		return ValuePointer();

	if(value_size <= 0)
		throw std::runtime_error((boost::format("Element has an invalid size: %d") % key).str().c_str());

	std::string val_str(val.get(), value_size);
	std::istringstream input(val_str);
	ValuePointer result = Value::Unserialize(key, input);	

	return result;
}
JSONParserBase::Token
JSONParser<CharT>::readNumber()
{
    MOZ_ASSERT(current < end);
    MOZ_ASSERT(JS7_ISDEC(*current) || *current == '-');

    /*
     * JSONNumber:
     *   /^-?(0|[1-9][0-9]+)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?$/
     */

    bool negative = *current == '-';

    /* -? */
    if (negative && ++current == end) {
        error("no number after minus sign");
        return token(Error);
    }

    const CharPtr digitStart = current;

    /* 0|[1-9][0-9]+ */
    if (!JS7_ISDEC(*current)) {
        error("unexpected non-digit");
        return token(Error);
    }
    if (*current++ != '0') {
        for (; current < end; current++) {
            if (!JS7_ISDEC(*current))
                break;
        }
    }

    /* Fast path: no fractional or exponent part. */
    if (current == end || (*current != '.' && *current != 'e' && *current != 'E')) {
        mozilla::Range<const CharT> chars(digitStart.get(), current - digitStart);
        if (chars.length() < strlen("9007199254740992")) {
            // If the decimal number is shorter than the length of 2**53, (the
            // largest number a double can represent with integral precision),
            // parse it using a decimal-only parser.  This comparison is
            // conservative but faster than a fully-precise check.
            double d = ParseDecimalNumber(chars);
            return numberToken(negative ? -d : d);
        }

        double d;
        const CharT* dummy;
        if (!GetPrefixInteger(cx, digitStart.get(), current.get(), 10, &dummy, &d))
            return token(OOM);
        MOZ_ASSERT(current == dummy);
        return numberToken(negative ? -d : d);
    }

    /* (\.[0-9]+)? */
    if (current < end && *current == '.') {
        if (++current == end) {
            error("missing digits after decimal point");
            return token(Error);
        }
        if (!JS7_ISDEC(*current)) {
            error("unterminated fractional number");
            return token(Error);
        }
        while (++current < end) {
            if (!JS7_ISDEC(*current))
                break;
        }
    }

    /* ([eE][\+\-]?[0-9]+)? */
    if (current < end && (*current == 'e' || *current == 'E')) {
        if (++current == end) {
            error("missing digits after exponent indicator");
            return token(Error);
        }
        if (*current == '+' || *current == '-') {
            if (++current == end) {
                error("missing digits after exponent sign");
                return token(Error);
            }
        }
        if (!JS7_ISDEC(*current)) {
            error("exponent part is missing a number");
            return token(Error);
        }
        while (++current < end) {
            if (!JS7_ISDEC(*current))
                break;
        }
    }

    double d;
    const CharT* finish;
    if (!js_strtod(cx, digitStart.get(), current.get(), &finish, &d))
        return token(OOM);
    MOZ_ASSERT(current == finish);
    return numberToken(negative ? -d : d);
}
JSONParserBase::Token
JSONParser<CharT>::readString()
{
    MOZ_ASSERT(current < end);
    MOZ_ASSERT(*current == '"');

    /*
     * JSONString:
     *   /^"([^\u0000-\u001F"\\]|\\(["/\\bfnrt]|u[0-9a-fA-F]{4}))*"$/
     */

    if (++current == end) {
        error("unterminated string literal");
        return token(Error);
    }

    /*
     * Optimization: if the source contains no escaped characters, create the
     * string directly from the source text.
     */
    CharPtr start = current;
    for (; current < end; current++) {
        if (*current == '"') {
            size_t length = current - start;
            current++;
            JSFlatString* str = (ST == JSONParser::PropertyName)
                                ? AtomizeChars(cx, start.get(), length)
                                : NewStringCopyN<CanGC>(cx, start.get(), length);
            if (!str)
                return token(OOM);
            return stringToken(str);
        }

        if (*current == '\\')
            break;

        if (*current <= 0x001F) {
            error("bad control character in string literal");
            return token(Error);
        }
    }

    /*
     * Slow case: string contains escaped characters.  Copy a maximal sequence
     * of unescaped characters into a temporary buffer, then an escaped
     * character, and repeat until the entire string is consumed.
     */
    StringBuffer buffer(cx);
    do {
        if (start < current && !buffer.append(start.get(), current.get()))
            return token(OOM);

        if (current >= end)
            break;

        char16_t c = *current++;
        if (c == '"') {
            JSFlatString* str = (ST == JSONParser::PropertyName)
                                ? buffer.finishAtom()
                                : buffer.finishString();
            if (!str)
                return token(OOM);
            return stringToken(str);
        }

        if (c != '\\') {
            --current;
            error("bad character in string literal");
            return token(Error);
        }

        if (current >= end)
            break;

        switch (*current++) {
          case '"':  c = '"';  break;
          case '/':  c = '/';  break;
          case '\\': c = '\\'; break;
          case 'b':  c = '\b'; break;
          case 'f':  c = '\f'; break;
          case 'n':  c = '\n'; break;
          case 'r':  c = '\r'; break;
          case 't':  c = '\t'; break;

          case 'u':
            if (end - current < 4 ||
                !(JS7_ISHEX(current[0]) &&
                  JS7_ISHEX(current[1]) &&
                  JS7_ISHEX(current[2]) &&
                  JS7_ISHEX(current[3])))
            {
                // Point to the first non-hexadecimal character (which may be
                // missing).
                if (current == end || !JS7_ISHEX(current[0]))
                    ; // already at correct location
                else if (current + 1 == end || !JS7_ISHEX(current[1]))
                    current += 1;
                else if (current + 2 == end || !JS7_ISHEX(current[2]))
                    current += 2;
                else if (current + 3 == end || !JS7_ISHEX(current[3]))
                    current += 3;
                else
                    MOZ_CRASH("logic error determining first erroneous character");

                error("bad Unicode escape");
                return token(Error);
            }
            c = (JS7_UNHEX(current[0]) << 12)
              | (JS7_UNHEX(current[1]) << 8)
              | (JS7_UNHEX(current[2]) << 4)
              | (JS7_UNHEX(current[3]));
            current += 4;
            break;

          default:
            current--;
            error("bad escaped character");
            return token(Error);
        }
        if (!buffer.append(c))
            return token(OOM);

        start = current;
        for (; current < end; current++) {
            if (*current == '"' || *current == '\\' || *current <= 0x001F)
                break;
        }
    } while (current < end);

    error("unterminated string");
    return token(Error);
}