[webkit-changes] [60774] trunk/WebCore

Pavel Feldman pfeldman at chromium.org
Tue Jun 8 23:47:33 PDT 2010


We are working on the remote debugging scenario where Web Inspector frontend
(web app) connects to the remote InspectorController instance. Given the
HTML/CSS/JS nature of the frontend, we need messages to be in JSON. As a
result, we need to somehow generate / parse these messages on the backend
side using native code. Neither JSON.stringify/parse nor
SerializedScriptValue work for us: first requires diving into the JS
execution, second uses binary format. So this InspectorValue and its
toJSON/fromJSON seems to be a reasonable compromise. Code is fairly compact,
it is conservative (has been ported from the chromium's base/values) and it
solves our exact needs. We do not aim supporting the full standard since we
control both sides of the interaction, but we'd like to leverage JSON
object's capabilities on the front-end side.

Suggestions / hints are welcome
Pavel

On Wed, Jun 9, 2010 at 3:41 AM, Eric Seidel <eric at webkit.org> wrote:

> On Tue, Jun 8, 2010 at 4:40 PM, Oliver Hunt <oliver at apple.com> wrote:
> > Why do we need this?  why can't we just use the same logic used for
> > postMessage?  Having multiple different functions to do object
> serialisation
> > seems unnecessary.
> > --Oliver
> >
> >
> > On Jun 7, 2010, at 4:33 AM, eric at webkit.org wrote:
> >
> > Revision 60774 Author eric at webkit.org Date 2010-06-07 04:33:11 -0700
> (Mon,
> > 07 Jun 2010)
> >
> > Log Message
> >
> > 2010-06-07  Pavel Podivilov  <podivilov at chromium.org>
> >
> >         Reviewed by Pavel Feldman.
> >
> >         Web Inspector: Implement JSON parsing for InspectorValue.
> >         https://bugs.webkit.org/show_bug.cgi?id=40064
> >
> >         * inspector/InspectorValues.cpp:
> >         (WebCore::):
> >         (WebCore::InspectorValue::asBool):
> >         (WebCore::InspectorValue::asNumber):
> >         (WebCore::InspectorValue::asString):
> >         (WebCore::InspectorValue::asObject):
> >         (WebCore::InspectorValue::asArray):
> >         (WebCore::InspectorValue::readJSON):
> >         (WebCore::InspectorValue::writeJSON):
> >         (WebCore::InspectorBasicValue::asBool):
> >         (WebCore::InspectorBasicValue::asNumber):
> >         (WebCore::InspectorBasicValue::writeJSON):
> >         (WebCore::InspectorString::asString):
> >         (WebCore::InspectorObject::asObject):
> >         (WebCore::InspectorObject::getBool):
> >         (WebCore::InspectorObject::getNumber):
> >         (WebCore::InspectorObject::getString):
> >         (WebCore::InspectorObject::getObject):
> >         (WebCore::InspectorObject::getArray):
> >         (WebCore::InspectorObject::get):
> >         (WebCore::InspectorArray::asArray):
> >         * inspector/InspectorValues.h:
> >         (WebCore::InspectorObject::begin):
> >         (WebCore::InspectorObject::end):
> >
> > Modified Paths
> >
> > trunk/WebCore/ChangeLog
> > trunk/WebCore/inspector/InspectorValues.cpp
> > trunk/WebCore/inspector/InspectorValues.h
> >
> > Diff
> >
> > Modified: trunk/WebCore/ChangeLog (60773 => 60774)
> >
> > --- trunk/WebCore/ChangeLog   2010-06-07 11:24:14 UTC (rev 60773)
> > +++ trunk/WebCore/ChangeLog   2010-06-07 11:33:11 UTC (rev 60774)
> > @@ -1,3 +1,35 @@
> > +2010-06-07  Pavel Podivilov  <podivilov at chromium.org>
> > +
> > +        Reviewed by Pavel Feldman.
> > +
> > +        Web Inspector: Implement JSON parsing for InspectorValue.
> > +        https://bugs.webkit.org/show_bug.cgi?id=40064
> > +
> > +        * inspector/InspectorValues.cpp:
> > +        (WebCore::):
> > +        (WebCore::InspectorValue::asBool):
> > +        (WebCore::InspectorValue::asNumber):
> > +        (WebCore::InspectorValue::asString):
> > +        (WebCore::InspectorValue::asObject):
> > +        (WebCore::InspectorValue::asArray):
> > +        (WebCore::InspectorValue::readJSON):
> > +        (WebCore::InspectorValue::writeJSON):
> > +        (WebCore::InspectorBasicValue::asBool):
> > +        (WebCore::InspectorBasicValue::asNumber):
> > +        (WebCore::InspectorBasicValue::writeJSON):
> > +        (WebCore::InspectorString::asString):
> > +        (WebCore::InspectorObject::asObject):
> > +        (WebCore::InspectorObject::getBool):
> > +        (WebCore::InspectorObject::getNumber):
> > +        (WebCore::InspectorObject::getString):
> > +        (WebCore::InspectorObject::getObject):
> > +        (WebCore::InspectorObject::getArray):
> > +        (WebCore::InspectorObject::get):
> > +        (WebCore::InspectorArray::asArray):
> > +        * inspector/InspectorValues.h:
> > +        (WebCore::InspectorObject::begin):
> > +        (WebCore::InspectorObject::end):
> > +
> >  2010-06-07  Jocelyn Turcotte  <jocelyn.turcotte at nokia.com>
> >
> >          Reviewed by Simon Hausmann.
> >
> > Modified: trunk/WebCore/inspector/InspectorValues.cpp (60773 => 60774)
> >
> > --- trunk/WebCore/inspector/InspectorValues.cpp       2010-06-07 11:24:14
> UTC (rev
> > 60773)
> > +++ trunk/WebCore/inspector/InspectorValues.cpp       2010-06-07 11:33:11
> UTC (rev
> > 60774)
> > @@ -35,6 +35,407 @@
> >
> >  namespace WebCore {
> >
> > +namespace {
> > +
> > +static const int stackLimit = 1000;
> > +
> > +enum Token {
> > +    OBJECT_BEGIN,
> > +    OBJECT_END,
> > +    ARRAY_BEGIN,
> > +    ARRAY_END,
> > +    STRING,
> > +    NUMBER,
> > +    BOOL_TRUE,
> > +    BOOL_FALSE,
> > +    NULL_TOKEN,
> > +    LIST_SEPARATOR,
> > +    OBJECT_PAIR_SEPARATOR,
> > +    INVALID_TOKEN,
> > +};
> > +
> > +const char* const nullString = "null";
> > +const char* const trueString = "true";
> > +const char* const falseString = "false";
> > +
> > +bool parseConstToken(const UChar* start, const UChar* end, const UChar**
> > tokenEnd, const char* token)
> > +{
> > +    while (start < end && *token != '\0' && *start++ == *token++) { }
> > +    if (*token != '\0')
> > +        return false;
> > +    *tokenEnd = start;
> > +    return true;
> > +}
> > +
> > +bool readInt(const UChar* start, const UChar* end, const UChar**
> tokenEnd,
> > bool canHaveLeadingZeros)
> > +{
> > +    if (start == end)
> > +        return false;
> > +    bool haveLeadingZero = '0' == *start;
> > +    int length = 0;
> > +    while (start < end && '0' <= *start && *start <= '9') {
> > +        ++start;
> > +        ++length;
> > +    }
> > +    if (!length)
> > +        return false;
> > +    if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
> > +        return false;
> > +    *tokenEnd = start;
> > +    return true;
> > +}
> > +
> > +bool parseNumberToken(const UChar* start, const UChar* end, const
> UChar**
> > tokenEnd)
> > +{
> > +    // We just grab the number here.  We validate the size in
> DecodeNumber.
> > +    // According   to RFC4627, a valid number is: [minus] int [frac]
> [exp]
> > +    if (start == end)
> > +        return false;
> > +    UChar c = *start;
> > +    if ('-' == c)
> > +        ++start;
> > +
> > +    if (!readInt(start, end, &start, false))
> > +        return false;
> > +    if (start == end) {
> > +        *tokenEnd = start;
> > +        return true;
> > +    }
> > +
> > +    // Optional fraction part
> > +    c = *start;
> > +    if ('.' == c) {
> > +        ++start;
> > +        if (!readInt(start, end, &start, true))
> > +            return false;
> > +        if (start == end) {
> > +            *tokenEnd = start;
> > +            return true;
> > +        }
> > +        c = *start;
> > +    }
> > +
> > +    // Optional exponent part
> > +    if ('e' == c || 'E' == c) {
> > +        ++start;
> > +        if (start == end)
> > +            return false;
> > +        c = *start;
> > +        if ('-' == c || '+' == c) {
> > +            ++start;
> > +            if (start == end)
> > +                return false;
> > +        }
> > +        if (!readInt(start, end, &start, true))
> > +            return false;
> > +    }
> > +
> > +    *tokenEnd = start;
> > +    return true;
> > +}
> > +
> > +bool readHexDigits(const UChar* start, const UChar* end, const UChar**
> > tokenEnd, int digits)
> > +{
> > +    if (end - start < digits)
> > +        return false;
> > +    for (int i = 0; i < digits; ++i) {
> > +        UChar c = *start++;
> > +        if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A'
> <= c
> > && c <= 'F')))
> > +            return false;
> > +    }
> > +    *tokenEnd = start;
> > +    return true;
> > +}
> > +
> > +bool parseStringToken(const UChar* start, const UChar* end, const
> UChar**
> > tokenEnd)
> > +{
> > +    while (start < end) {
> > +        UChar c = *start++;
> > +        if ('\\' == c) {
> > +            c = *start++;
> > +            // Make sure the escaped char is valid.
> > +            switch (c) {
> > +            case 'x':
> > +                if (!readHexDigits(start, end, &start, 2))
> > +                    return false;
> > +                break;
> > +            case 'u':
> > +                if (!readHexDigits(start, end, &start, 4))
> > +                    return false;
> > +                break;
> > +            case '\\':
> > +            case '/':
> > +            case 'b':
> > +            case 'f':
> > +            case 'n':
> > +            case 'r':
> > +            case 't':
> > +            case 'v':
> > +            case '"':
> > +                break;
> > +            default:
> > +                return false;
> > +            }
> > +        } else if ('"' == c) {
> > +            *tokenEnd = start;
> > +            return true;
> > +        }
> > +    }
> > +    return false;
> > +}
> > +
> > +Token parseToken(const UChar* start, const UChar* end, const UChar**
> > tokenEnd)
> > +{
> > +    if (start == end)
> > +        return INVALID_TOKEN;
> > +
> > +    switch (*start) {
> > +    case 'n':
> > +        if (parseConstToken(start, end, tokenEnd, nullString))
> > +            return NULL_TOKEN;
> > +        break;
> > +    case 't':
> > +        if (parseConstToken(start, end, tokenEnd, trueString))
> > +            return BOOL_TRUE;
> > +        break;
> > +    case 'f':
> > +        if (parseConstToken(start, end, tokenEnd, falseString))
> > +            return BOOL_FALSE;
> > +        break;
> > +    case '[':
> > +        *tokenEnd = start + 1;
> > +        return ARRAY_BEGIN;
> > +    case ']':
> > +        *tokenEnd = start + 1;
> > +        return ARRAY_END;
> > +    case ',':
> > +        *tokenEnd = start + 1;
> > +        return LIST_SEPARATOR;
> > +    case '{':
> > +        *tokenEnd = start + 1;
> > +        return OBJECT_BEGIN;
> > +    case '}':
> > +        *tokenEnd = start + 1;
> > +        return OBJECT_END;
> > +    case ':':
> > +        *tokenEnd = start + 1;
> > +        return OBJECT_PAIR_SEPARATOR;
> > +    case '0':
> > +    case '1':
> > +    case '2':
> > +    case '3':
> > +    case '4':
> > +    case '5':
> > +    case '6':
> > +    case '7':
> > +    case '8':
> > +    case '9':
> > +    case '-':
> > +        if (parseNumberToken(start, end, tokenEnd))
> > +            return NUMBER;
> > +        break;
> > +    case '"':
> > +        if (parseStringToken(start + 1, end, tokenEnd))
> > +            return STRING;
> > +        break;
> > +    }
> > +    return INVALID_TOKEN;
> > +}
> > +
> > +inline int hexToInt(UChar c)
> > +{
> > +    if ('0' <= c && c <= '9')
> > +        return c - '0';
> > +    if ('A' <= c && c <= 'F')
> > +        return c - 'A' + 10;
> > +    if ('a' <= c && c <= 'f')
> > +        return c - 'a' + 10;
> > +    ASSERT_NOT_REACHED();
> > +    return 0;
> > +}
> > +
> > +bool decodeString(const UChar* start, const UChar* end, Vector<UChar>*
> > output)
> > +{
> > +    while (start < end) {
> > +        UChar c = *start++;
> > +        if ('\\' != c) {
> > +            output->append(c);
> > +            continue;
> > +        }
> > +        c = *start++;
> > +        switch (c) {
> > +        case '"':
> > +        case '/':
> > +        case '\\':
> > +            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 'v':
> > +            c = '\v';
> > +            break;
> > +        case 'x':
> > +            c = (hexToInt(*start) << 4) +
> > +                hexToInt(*(start + 1));
> > +            start += 2;
> > +            break;
> > +        case 'u':
> > +            c = (hexToInt(*start) << 12) +
> > +                (hexToInt(*(start + 1)) << 8) +
> > +                (hexToInt(*(start + 2)) << 4) +
> > +                hexToInt(*(start + 3));
> > +            start += 4;
> > +            break;
> > +        default:
> > +            return false;
> > +        }
> > +        output->append(c);
> > +    }
> > +    return true;
> > +}
> > +
> > +bool decodeString(const UChar* start, const UChar* end, String* output)
> > +{
> > +    if (start == end) {
> > +        *output = "";
> > +        return true;
> > +    }
> > +    if (start > end)
> > +        return false;
> > +    Vector<UChar> buffer;
> > +    buffer.reserveCapacity(end - start);
> > +    if (!decodeString(start, end, &buffer))
> > +        return false;
> > +    *output = String(buffer.data(), buffer.size());
> > +    return true;
> > +}
> > +
> > +PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar*
> end,
> > const UChar** valueTokenEnd, int depth)
> > +{
> > +    if (depth > stackLimit)
> > +        return 0;
> > +
> > +    RefPtr<InspectorValue> result;
> > +    const UChar* tokenEnd;
> > +    Token token = parseToken(start, end, &tokenEnd);
> > +    switch (token) {
> > +    case INVALID_TOKEN:
> > +        return 0;
> > +    case NULL_TOKEN:
> > +        result = InspectorValue::null();
> > +        break;
> > +    case BOOL_TRUE:
> > +        result = InspectorBasicValue::create(true);
> > +        break;
> > +    case BOOL_FALSE:
> > +        result = InspectorBasicValue::create(false);
> > +        break;
> > +    case NUMBER: {
> > +        bool ok;
> > +        double value = charactersToDouble(start, tokenEnd - start, &ok);
> > +        if (!ok)
> > +            return 0;
> > +        result = InspectorBasicValue::create(value);
> > +        break;
> > +    }
> > +    case STRING: {
> > +        String value;
> > +        bool ok = decodeString(start + 1, tokenEnd - 1, &value);
> > +        if (!ok)
> > +            return 0;
> > +        result = InspectorString::create(value);
> > +        break;
> > +    }
> > +    case ARRAY_BEGIN: {
> > +        RefPtr<InspectorArray> array = InspectorArray::create();
> > +        start = tokenEnd;
> > +        token = parseToken(start, end, &tokenEnd);
> > +        while (token != ARRAY_END) {
> > +            RefPtr<InspectorValue> arrayNode = buildValue(start, end,
> > &tokenEnd, depth + 1);
> > +            if (!arrayNode)
> > +                return 0;
> > +            array->push(arrayNode);
> > +
> > +            // After a list value, we expect a comma or the end of the
> > list.
> > +            start = tokenEnd;
> > +            token = parseToken(start, end, &tokenEnd);
> > +            if (token == LIST_SEPARATOR) {
> > +                start = tokenEnd;
> > +                token = parseToken(start, end, &tokenEnd);
> > +                if (token == ARRAY_END)
> > +                    return 0;
> > +            } else if (token != ARRAY_END) {
> > +                // Unexpected value after list value.  Bail out.
> > +                return 0;
> > +            }
> > +        }
> > +        if (token != ARRAY_END)
> > +            return 0;
> > +        result = array.release();
> > +        break;
> > +    }
> > +    case OBJECT_BEGIN: {
> > +        RefPtr<InspectorObject> object = InspectorObject::create();
> > +        start = tokenEnd;
> > +        token = parseToken(start, end, &tokenEnd);
> > +        while (token != OBJECT_END) {
> > +            if (token != STRING)
> > +                return 0;
> > +            String key;
> > +            if (!decodeString(start + 1, tokenEnd - 1, &key))
> > +                return 0;
> > +            start = tokenEnd;
> > +
> > +            token = parseToken(start, end, &tokenEnd);
> > +            if (token != OBJECT_PAIR_SEPARATOR)
> > +                return 0;
> > +            start = tokenEnd;
> > +
> > +            RefPtr<InspectorValue> value = buildValue(start, end,
> > &tokenEnd, depth + 1);
> > +            if (!value)
> > +                return 0;
> > +            object->set(key, value);
> > +            start = tokenEnd;
> > +
> > +            // After a key/value pair, we expect a comma or the end of
> the
> > +            // object.
> > +            token = parseToken(start, end, &tokenEnd);
> > +            if (token == LIST_SEPARATOR) {
> > +                start = tokenEnd;
> > +                token = parseToken(start, end, &tokenEnd);
> > +                 if (token == OBJECT_END)
> > +                    return 0;
> > +            } else if (token != OBJECT_END) {
> > +                // Unexpected value after last object value.  Bail out.
> > +                return 0;
> > +            }
> > +        }
> > +        if (token != OBJECT_END)
> > +            return 0;
> > +        result = object.release();
> > +        break;
> > +    }
> > +
> > +    default:
> > +        // We got a token that's not a value.
> > +        return 0;
> > +    }
> > +    *valueTokenEnd = tokenEnd;
> > +    return result.release();
> > +}
> > +
> >  inline bool escapeChar(UChar c, Vector<UChar>* dst)
> >  {
> >      switch (c) {
> > @@ -71,6 +472,44 @@
> >      dst->append('"');
> >  }
> >
> > +} // anonymous namespace
> > +
> > +bool InspectorValue::asBool(bool*) const
> > +{
> > +    return false;
> > +}
> > +
> > +bool InspectorValue::asNumber(double*) const
> > +{
> > +    return false;
> > +}
> > +
> > +bool InspectorValue::asString(String*) const
> > +{
> > +    return false;
> > +}
> > +
> > +PassRefPtr<InspectorObject> InspectorValue::asObject()
> > +{
> > +    return 0;
> > +}
> > +
> > +PassRefPtr<InspectorArray> InspectorValue::asArray()
> > +{
> > +    return 0;
> > +}
> > +
> > +PassRefPtr<InspectorValue> InspectorValue::readJSON(const String& json)
> > +{
> > +    const UChar* start = json.characters();
> > +    const UChar* end = json.characters() + json.length();
> > +    const UChar *tokenEnd;
> > +    RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, 0);
> > +    if (!value || tokenEnd != end)
> > +        return 0;
> > +    return value.release();
> > +}
> > +
> >  String InspectorValue::toJSONString() const
> >  {
> >      Vector<UChar> result;
> > @@ -82,29 +521,104 @@
> >  void InspectorValue::writeJSON(Vector<UChar>* output) const
> >  {
> >      ASSERT(m_type == TypeNull);
> > -    output->append("null", 4);
> > +    output->append(nullString, 4);
> >  }
> >
> > +bool InspectorBasicValue::asBool(bool* output) const
> > +{
> > +    if (type() != TypeBoolean)
> > +        return false;
> > +    *output = m_boolValue;
> > +    return true;
> > +}
> > +
> > +bool InspectorBasicValue::asNumber(double* output) const
> > +{
> > +    if (type() != TypeDouble)
> > +        return false;
> > +    *output = m_doubleValue;
> > +    return true;
> > +}
> > +
> >  void InspectorBasicValue::writeJSON(Vector<UChar>* output) const
> >  {
> >      ASSERT(type() == TypeBoolean || type() == TypeDouble);
> >      if (type() == TypeBoolean) {
> >          if (m_boolValue)
> > -            output->append("true", 4);
> > +            output->append(trueString, 4);
> >          else
> > -            output->append("false", 5);
> > +            output->append(falseString, 5);
> >      } else if (type() == TypeDouble) {
> >          String value = String::format("%f", m_doubleValue);
> >          output->append(value.characters(), value.length());
> >      }
> >  }
> >
> > +bool InspectorString::asString(String* output) const
> > +{
> > +    *output = m_stringValue;
> > +    return true;
> > +}
> > +
> >  void InspectorString::writeJSON(Vector<UChar>* output) const
> >  {
> >      ASSERT(type() == TypeString);
> >      doubleQuoteString(m_stringValue, output);
> >  }
> >
> > +PassRefPtr<InspectorObject> InspectorObject::asObject()
> > +{
> > +    return this;
> > +}
> > +
> > +bool InspectorObject::getBool(const String& name, bool* output) const
> > +{
> > +    RefPtr<InspectorValue> value = get(name);
> > +    if (!value)
> > +        return false;
> > +    return value->asBool(output);
> > +}
> > +
> > +bool InspectorObject::getNumber(const String& name, double* output)
> const
> > +{
> > +    RefPtr<InspectorValue> value = get(name);
> > +    if (!value)
> > +        return false;
> > +    return value->asNumber(output);
> > +}
> > +
> > +bool InspectorObject::getString(const String& name, String* output)
> const
> > +{
> > +    RefPtr<InspectorValue> value = get(name);
> > +    if (!value)
> > +        return false;
> > +    return value->asString(output);
> > +}
> > +
> > +PassRefPtr<InspectorObject> InspectorObject::getObject(const String&
> name)
> > const
> > +{
> > +    PassRefPtr<InspectorValue> value = get(name);
> > +    if (!value)
> > +        return false;
> > +    return value->asObject();
> > +}
> > +
> > +PassRefPtr<InspectorArray> InspectorObject::getArray(const String& name)
> > const
> > +{
> > +    PassRefPtr<InspectorValue> value = get(name);
> > +    if (!value)
> > +        return false;
> > +    return value->asArray();
> > +}
> > +
> > +PassRefPtr<InspectorValue> InspectorObject::get(const String& name)
> const
> > +{
> > +    Dictionary::const_iterator it = m_data.find(name);
> > +    if (it == m_data.end())
> > +        return 0;
> > +    return it->second;
> > +}
> > +
> >  void InspectorObject::writeJSON(Vector<UChar>* output) const
> >  {
> >      output->append('{');
> > @@ -120,6 +634,11 @@
> >      output->append('}');
> >  }
> >
> > +PassRefPtr<InspectorArray> InspectorArray::asArray()
> > +{
> > +    return this;
> > +}
> > +
> >  void InspectorArray::writeJSON(Vector<UChar>* output) const
> >  {
> >      output->append('[');
> >
> > Modified: trunk/WebCore/inspector/InspectorValues.h (60773 => 60774)
> >
> > --- trunk/WebCore/inspector/InspectorValues.h 2010-06-07 11:24:14 UTC
> (rev
> > 60773)
> > +++ trunk/WebCore/inspector/InspectorValues.h 2010-06-07 11:33:11 UTC
> (rev
> > 60774)
> > @@ -42,6 +42,8 @@
> >
> >  namespace WebCore {
> >
> > +class InspectorArray;
> > +class InspectorObject;
> >  class String;
> >
> >  class InspectorValue : public RefCounted<InspectorValue> {
> > @@ -65,6 +67,14 @@
> >
> >      Type type() const { return m_type; }
> >
> > +    virtual bool asBool(bool* output) const;
> > +    virtual bool asNumber(double* output) const;
> > +    virtual bool asString(String* output) const;
> > +    virtual PassRefPtr<InspectorObject> asObject();
> > +    virtual PassRefPtr<InspectorArray> asArray();
> > +
> > +    static PassRefPtr<InspectorValue> readJSON(const String& json);
> > +
> >      String toJSONString() const;
> >      virtual void writeJSON(Vector<UChar>* output) const;
> >
> > @@ -93,6 +103,9 @@
> >          return adoptRef(new InspectorBasicValue(value));
> >      }
> >
> > +    virtual bool asBool(bool* output) const;
> > +    virtual bool asNumber(double* output) const;
> > +
> >      virtual void writeJSON(Vector<UChar>* output) const;
> >
> >  private:
> > @@ -117,6 +130,9 @@
> >      {
> >          return adoptRef(new InspectorString(value));
> >      }
> > +
> > +    virtual bool asString(String* output) const;
> > +
> >      virtual void writeJSON(Vector<UChar>* output) const;
> >
> >  private:
> > @@ -127,23 +143,43 @@
> >  };
> >
> >  class InspectorObject : public InspectorValue {
> > +private:
> > +    typedef HashMap<String, RefPtr<InspectorValue> > Dictionary;
> > +
> >  public:
> > +    typedef Dictionary::iterator iterator;
> > +    typedef Dictionary::const_iterator const_iterator;
> > +
> > +public:
> >      static PassRefPtr<InspectorObject> create()
> >      {
> >          return adoptRef(new InspectorObject());
> >      }
> >      ~InspectorObject() { }
> >
> > +    virtual PassRefPtr<InspectorObject> asObject();
> > +
> >      void setBool(const String& name, bool);
> >      void setNumber(const String& name, double);
> >      void setString(const String& name, const String&);
> >      void set(const String& name, PassRefPtr<InspectorValue>);
> >
> > +    bool getBool(const String& name, bool* output) const;
> > +    bool getNumber(const String& name, double* output) const;
> > +    bool getString(const String& name, String* output) const;
> > +    PassRefPtr<InspectorObject> getObject(const String& name) const;
> > +    PassRefPtr<InspectorArray> getArray(const String& name) const;
> > +    PassRefPtr<InspectorValue> get(const String& name) const;
> > +
> >      virtual void writeJSON(Vector<UChar>* output) const;
> >
> > +    iterator begin() { return m_data.begin(); }
> > +    iterator end() { return m_data.end(); }
> > +    const_iterator begin() const { return m_data.begin(); }
> > +    const_iterator end() const { return m_data.end(); }
> > +
> >  private:
> >      InspectorObject() : InspectorValue(TypeObject) { }
> > -    typedef HashMap<String, RefPtr<InspectorValue> > Dictionary;
> >      Dictionary m_data;
> >      Vector<String> m_order;
> >  };
> > @@ -156,6 +192,8 @@
> >      }
> >      ~InspectorArray() { }
> >
> > +    virtual PassRefPtr<InspectorArray> asArray();
> > +
> >      void pushBool(bool);
> >      void pushNumber(double);
> >      void pushString(const String&);
> > @@ -214,4 +252,3 @@
> >
> >  #endif // ENABLE(INSPECTOR)
> >  #endif // !defined(InspectorValues_h)
> > -
> >
> > _______________________________________________
> > webkit-changes mailing list
> > webkit-changes at lists.webkit.org
> > http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-changes/attachments/20100609/ed098255/attachment-0001.html>


More information about the webkit-changes mailing list