| 1469 | } |
| 1470 | |
| 1471 | JSBool jsval_to_ccdictionary(JSContext* cx, jsval v, CCDictionary** ret) { |
| 1472 | |
| 1473 | if(JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) |
| 1474 | { |
| 1475 | *ret = NULL; |
| 1476 | return JS_TRUE; |
| 1477 | } |
| 1478 | |
| 1479 | JSObject* tmp = JSVAL_TO_OBJECT(v); |
| 1480 | if (!tmp) { |
| 1481 | LOGD("jsval_to_ccdictionary: the jsval is not an object."); |
| 1482 | return JS_FALSE; |
| 1483 | } |
| 1484 | |
| 1485 | JSObject* it = JS_NewPropertyIterator(cx, tmp); |
| 1486 | CCDictionary* dict = NULL; |
| 1487 | |
| 1488 | while (true) |
| 1489 | { |
| 1490 | jsid idp; |
| 1491 | jsval key; |
| 1492 | if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key)) { |
| 1493 | return JS_FALSE; // error |
| 1494 | } |
| 1495 | |
| 1496 | if (key == JSVAL_VOID) { |
| 1497 | break; // end of iteration |
| 1498 | } |
| 1499 | |
| 1500 | if (!JSVAL_IS_STRING(key)) { |
| 1501 | continue; // ignore integer properties |
| 1502 | } |
| 1503 | |
| 1504 | JSStringWrapper keyWrapper(JSVAL_TO_STRING(key), cx); |
| 1505 | if(!dict) { |
| 1506 | dict = CCDictionary::create(); |
| 1507 | } |
| 1508 | |
| 1509 | jsval value; |
| 1510 | JS_GetPropertyById(cx, tmp, idp, &value); |
| 1511 | if (value.isObject()) |
| 1512 | { |
| 1513 | js_proxy_t *proxy; |
| 1514 | JSObject *tmp = JSVAL_TO_OBJECT(value); |
| 1515 | proxy = jsb_get_js_proxy(tmp); |
| 1516 | CAObject* cobj = (CAObject *)(proxy ? proxy->ptr : NULL); |
| 1517 | // Don't test it. |
| 1518 | //TEST_NATIVE_OBJECT(cx, cobj) |
| 1519 | if (cobj) { |
| 1520 | // It's a native <-> js glue object. |
| 1521 | dict->setObject(cobj, keyWrapper.get()); |
| 1522 | } |
| 1523 | else if (!JS_IsArrayObject(cx, tmp)){ |
| 1524 | // It's a normal js object. |
| 1525 | CCDictionary* dictVal = NULL; |
| 1526 | JSBool ok = jsval_to_ccdictionary(cx, value, &dictVal); |
| 1527 | if (ok) { |
| 1528 | dict->setObject(dictVal, keyWrapper.get()); |
no test coverage detected