Exemple #1
0
//--------------------------------------------------------------------------
// KJSValueToCFTypeInternal
//--------------------------------------------------------------------------
// Caller is responsible for releasing the returned CFTypeRef
CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps)
{
    if (!inValue)
        return 0;

    CFTypeRef result = 0;

    JSGlueAPIEntry entry;

        if (inValue.isBoolean())
            {
                result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
                RetainCFType(result);
                return result;
            }

        if (inValue.isString())
            {
                UString uString = inValue.toString(exec);
                result = UStringToCFString(uString);
                return result;
            }

        if (inValue.isNumber())
            {
                double number1 = inValue.toNumber(exec);
                double number2 = (double)inValue.toInteger(exec);
                if (number1 ==  number2)
                {
                    int intValue = (int)number2;
                    result = CFNumberCreate(0, kCFNumberIntType, &intValue);
                }
                else
                {
                    result = CFNumberCreate(0, kCFNumberDoubleType, &number1);
                }
                return result;
            }

        if (inValue.isObject())
            {
                if (inValue.inherits(&UserObjectImp::info)) {
                    UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue));
                    JSUserObject* ptr = userObjectImp->GetJSUserObject();
                    if (ptr)
                    {
                        result = ptr->CopyCFValue();
                    }
                }
                else
                {
                    JSObject *object = inValue.toObject(exec);
                    UInt8 isArray = false;

                    // if two objects reference each
                    JSObject* imp = object;
                    ObjectImpList* temp = inImps;
                    while (temp) {
                        if (imp == temp->imp) {
                            return CFRetain(GetCFNull());
                        }
                        temp = temp->next;
                    }

                    ObjectImpList imps;
                    imps.next = inImps;
                    imps.imp = imp;


//[...] HACK since we do not have access to the class info we use class name instead
#if 0
                    if (object->inherits(&ArrayInstanceImp::info))
#else
                    if (object->className() == "Array")
#endif
                    {
                        isArray = true;
                        JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(exec->dynamicGlobalObject());
                        if (globalObject && (globalObject->Flags() & kJSFlagConvertAssociativeArray)) {
                            PropertyNameArray propNames(exec);
                            object->getPropertyNames(exec, propNames);
                            PropertyNameArray::const_iterator iter = propNames.begin();
                            PropertyNameArray::const_iterator end = propNames.end();
                            while(iter != end && isArray)
                            {
                                Identifier propName = *iter;
                                UString ustr = propName.ustring();
                                const UniChar* uniChars = (const UniChar*)ustr.characters();
                                int size = ustr.length();
                                while (size--) {
                                    if (uniChars[size] < '0' || uniChars[size] > '9') {
                                        isArray = false;
                                        break;
                                    }
                                }
                                iter++;
                            }
                        }
                    }

                    if (isArray)
                    {
                        // This is an KJS array
                        unsigned int length = object->get(exec, Identifier(exec, "length")).toUInt32(exec);
                        result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
                        if (result)
                        {
                            for (unsigned i = 0; i < length; i++)
                            {
                                CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, i), exec, &imps);
                                CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
                                ReleaseCFType(cfValue);
                            }
                        }
                    }
                    else
                    {
                        // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
                        PropertyNameArray propNames(exec);
                        object->getPropertyNames(exec, propNames);
                        {
                            result = CFDictionaryCreateMutable(0,
                                                               0,
                                                               &kCFTypeDictionaryKeyCallBacks,
                                                               &kCFTypeDictionaryValueCallBacks);
                            if (result)
                            {
                                PropertyNameArray::const_iterator iter = propNames.begin();
                                PropertyNameArray::const_iterator end = propNames.end();
                                while(iter != end)
                                {
                                    Identifier propName = *iter;
                                    if (object->hasProperty(exec, propName))
                                    {
                                        CFStringRef cfKey = IdentifierToCFString(propName);
                                        CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, propName), exec, &imps);
                                        if (cfKey && cfValue)
                                        {
                                            CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
                                        }
                                        ReleaseCFType(cfKey);
                                        ReleaseCFType(cfValue);
                                    }
                                    iter++;
                                }
                            }
                        }
                    }
                }
                return result;
            }

    if (inValue.isUndefinedOrNull())
        {
            result = RetainCFType(GetCFNull());
            return result;
        }

    ASSERT_NOT_REACHED();
    return 0;
}
Exemple #2
0
//#ifndef NDEBUG
void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
{
    UString vString;
    if (!o) {
        fprintf(stderr, "KJS: %s: (null)", s);
    } else {
        JSValue *v = o;

        unsigned int arrayLength = 0;
        bool hadExcep = exec->hadException();

        UString name;
        switch (v->type()) {
        case UnspecifiedType:
            name = "Unspecified";
            break;
        case UndefinedType:
            name = "Undefined";
            break;
        case NullType:
            name = "Null";
            break;
        case BooleanType:
            name = "Boolean";
            break;
        case StringType:
            name = "String";
            break;
        case NumberType:
            name = "Number";
            break;
        case ObjectType: {
            JSObject *obj = static_cast<JSObject *>(v);
            name = obj->className();
            if (name.isNull()) {
                name = "(unknown class)";
            }

            if (obj->inherits(&ArrayInstance::info)) {
                arrayLength = obj->get(exec, exec->propertyNames().length)->toUInt32(exec);
            }
            vString = "[object " + name + "]"; // krazy:exclude=doublequote_chars
            break;
        }
        case GetterSetterType:
            name = "GetterSetter";
            break;
        }

        // Avoid calling toString on a huge array (e.g. 4 billion elements, in mozilla/js/js1_5/Array/array-001.js)
        if (arrayLength > 100) {
            vString = UString("[ Array with ") + UString::from(arrayLength) + " elements ]";
        } else if (v->type() != ObjectType) { // Don't want to call a user toString function!
            vString = v->toString(exec);
        }
        if (!hadExcep) {
            exec->clearException();
        }

        if (vString.size() > 350) {
            vString = vString.substr(0, 350) + "...";
        }

        // Can't use two UString::ascii() in the same fprintf call
        CString tempString(vString.cstring());

        fprintf(stderr, "KJS: %s: %s : %s (%p)",
                s, tempString.c_str(), name.ascii(), (void *)v);

        if (lineno >= 0) {
            fprintf(stderr, ", line %d\n", lineno);
        } else {
            fprintf(stderr, "\n");
        }
    }
}