Пример #1
0
QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value,
                                         V8ObjectSet &visitedObjects)
{
    QJsonObject result;
    if (!value->IsObject() || value->IsArray() || value->IsFunction())
        return result;

    v8::Handle<v8::Object> v8object(value.As<v8::Object>());
    if (visitedObjects.contains(v8object)) {
        // Avoid recursion.
        // For compatibility with QVariant{List,Map} conversion, we return an
        // empty object (and no error is thrown).
        return result;
    }

    visitedObjects.insert(v8object);

    v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object);
    uint32_t length = propertyNames->Length();
    for (uint32_t i = 0; i < length; ++i) {
        v8::Local<v8::Value> name = propertyNames->Get(i);
        v8::Local<v8::Value> propertyValue = v8object->Get(name);
        if (!propertyValue->IsFunction())
            result.insert(QJSConverter::toString(name->ToString()),
                          toJsonValue(propertyValue, visitedObjects));
    }

    visitedObjects.remove(v8object);

    return result;
}
Пример #2
0
QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value,
                                       V8ObjectSet &visitedObjects)
{
    QJsonArray result;
    if (!value->IsArray())
        return result;

    v8::Handle<v8::Array> v8array(value.As<v8::Array>());
    if (visitedObjects.contains(v8array)) {
        // Avoid recursion.
        // For compatibility with QVariant{List,Map} conversion, we return an
        // empty array (and no error is thrown).
        return result;
    }

    visitedObjects.insert(v8array);

    uint32_t length = v8array->Length();
    for (uint32_t i = 0; i < length; ++i) {
        v8::Local<v8::Value> element = v8array->Get(i);
        if (!element->IsFunction())
            result.append(toJsonValue(element, visitedObjects));
    }

    visitedObjects.remove(v8array);

    return result;
}
Пример #3
0
static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vector<v8::Handle<v8::Array> >& stack, v8::Isolate* isolate)
{
    if (value->IsNumber() && !std::isnan(value->NumberValue()))
        return IDBKey::createNumber(value->NumberValue());
    if (value->IsString())
        return IDBKey::createString(toCoreString(value.As<v8::String>()));
    if (value->IsDate() && !std::isnan(value->NumberValue()))
        return IDBKey::createDate(value->NumberValue());
    if (value->IsArray()) {
        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);

        if (stack.contains(array))
            return 0;
        if (stack.size() >= maximumDepth)
            return 0;
        stack.append(array);

        IDBKey::KeyArray subkeys;
        uint32_t length = array->Length();
        for (uint32_t i = 0; i < length; ++i) {
            v8::Local<v8::Value> item = array->Get(v8::Int32::New(i, isolate));
            RefPtr<IDBKey> subkey = createIDBKeyFromValue(item, stack, isolate);
            if (!subkey)
                subkeys.append(IDBKey::createInvalid());
            else
                subkeys.append(subkey);
        }

        stack.removeLast();
        return IDBKey::createArray(subkeys);
    }
    return 0;
}
Пример #4
0
	static result_type from_v8(v8::Isolate* isolate, v8::Handle<v8::Value> value)
	{
		v8::HandleScope scope(isolate);

		result_type result;

		if (value->IsArray())
		{
			v8::Local<v8::Array> arr = value.As<v8::Array>();
			v8::Local<v8::Value> x = arr->Get(0), y = arr->Get(1);
			if (arr->Length() != 2 || !x->IsNumber() || !y->IsNumber())
			{
				throw std::invalid_argument("expected [x, y] array");
			}
			result.x = v8pp::from_v8<T>(isolate, x);
			result.y = v8pp::from_v8<T>(isolate, y);
		}
		else if (value->IsObject())
		{
			v8::Local<v8::Object> obj = value.As<v8::Object>();
			if (!get_option(isolate, obj, "x", result.x) || !get_option(isolate, obj, "y", result.y))
			{
				throw std::invalid_argument("expected {x, y} object");
			}
		}
		else
		{
			throw std::invalid_argument("expected [x, y] array or {x, y} object");
		}
		return result;
	}
Пример #5
0
	static result_type from_v8(v8::Isolate* isolate, v8::Handle<v8::Value> value)
	{
		v8::HandleScope scope(isolate);

		result_type result;

		if (value->IsArray())
		{
			v8::Local<v8::Array> arr = value.As<v8::Array>();
			v8::Local<v8::Value> width = arr->Get(0), height = arr->Get(1);
			if (arr->Length() != 2 || !width->IsNumber() || !height->IsNumber())
			{
				throw std::invalid_argument("expected [width, height] array");
			}
			result.width = v8pp::from_v8<T>(isolate, width);
			result.height = v8pp::from_v8<T>(isolate, height);
		}
		else if (value->IsObject())
		{
			v8::Local<v8::Object> obj = value.As<v8::Object>();
			if (!get_option(isolate, obj, "width", result.width) || !get_option(isolate, obj, "height", result.height))
			{
				throw std::invalid_argument("expected {width, height} object");
			}
		}
		else
		{
			throw std::invalid_argument("expected [width, height] array or {width, height} object");
		}
		return result;
	}
Пример #6
0
static PassRefPtr<JSONValue> v8ToJSONValue(v8::Handle<v8::Value> value, int maxDepth, v8::Isolate* isolate)
{
    if (value.IsEmpty()) {
        ASSERT_NOT_REACHED();
        return 0;
    }

    if (!maxDepth)
        return 0;
    maxDepth--;

    if (value->IsNull() || value->IsUndefined())
        return JSONValue::null();
    if (value->IsBoolean())
        return JSONBasicValue::create(value->BooleanValue());
    if (value->IsNumber())
        return JSONBasicValue::create(value->NumberValue());
    if (value->IsString())
        return JSONString::create(toCoreString(value.As<v8::String>()));
    if (value->IsArray()) {
        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
        RefPtr<JSONArray> inspectorArray = JSONArray::create();
        uint32_t length = array->Length();
        for (uint32_t i = 0; i < length; i++) {
            v8::Local<v8::Value> value = array->Get(v8::Int32::New(isolate, i));
            RefPtr<JSONValue> element = v8ToJSONValue(value, maxDepth, isolate);
            if (!element)
                return 0;
            inspectorArray->pushValue(element);
        }
        return inspectorArray;
    }
    if (value->IsObject()) {
        RefPtr<JSONObject> jsonObject = JSONObject::create();
        v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
        v8::Local<v8::Array> propertyNames = object->GetPropertyNames();
        uint32_t length = propertyNames->Length();
        for (uint32_t i = 0; i < length; i++) {
            v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(isolate, i));
            // FIXME(yurys): v8::Object should support GetOwnPropertyNames
            if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name)))
                continue;
            RefPtr<JSONValue> propertyValue = v8ToJSONValue(object->Get(name), maxDepth, isolate);
            if (!propertyValue)
                return 0;
            V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, nameString, name, 0);
            jsonObject->setValue(nameString, propertyValue);
        }
        return jsonObject;
    }
    ASSERT_NOT_REACHED();
    return 0;
}
Пример #7
0
static PassRefPtr<InspectorValue> v8ToInspectorValue(v8::Handle<v8::Value> value, int maxDepth)
{
    if (value.IsEmpty()) {
        ASSERT_NOT_REACHED();
        return 0;
    }

    if (!maxDepth)
        return 0;
    maxDepth--;

    if (value->IsNull() || value->IsUndefined())
        return InspectorValue::null();
    if (value->IsBoolean())
        return InspectorBasicValue::create(value->BooleanValue());
    if (value->IsNumber())
        return InspectorBasicValue::create(value->NumberValue());
    if (value->IsString())
        return InspectorString::create(toWebCoreString(value));
    if (value->IsArray()) {
        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
        RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
        uint32_t length = array->Length();
        for (uint32_t i = 0; i < length; i++) {
            v8::Local<v8::Value> value = array->Get(v8::Int32::New(i));
            RefPtr<InspectorValue> element = v8ToInspectorValue(value, maxDepth);
            if (!element)
                return 0;
            inspectorArray->pushValue(element);
        }
        return inspectorArray;
    }
    if (value->IsObject()) {
        RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
        v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
        v8::Local<v8::Array> propertyNames = object->GetPropertyNames();
        uint32_t length = propertyNames->Length();
        for (uint32_t i = 0; i < length; i++) {
            v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(i));
            // FIXME(yurys): v8::Object should support GetOwnPropertyNames
            if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name)))
                continue;
            RefPtr<InspectorValue> propertyValue = v8ToInspectorValue(object->Get(name), maxDepth);
            if (!propertyValue)
                return 0;
            inspectorObject->setValue(toWebCoreStringWithNullCheck(name), propertyValue);
        }
        return inspectorObject;
    }
    ASSERT_NOT_REACHED();
    return 0;
}
Пример #8
0
// Returns number of bytes written.
ssize_t DecodeWrite(char *buf,
                    size_t buflen,
                    v8::Handle<v8::Value> val,
                    enum encoding encoding) {
  v8::HandleScope scope;

  // XXX
  // A lot of improvement can be made here. See:
  // http://code.google.com/p/v8/issues/detail?id=270
  // http://groups.google.com/group/v8-dev/browse_thread/thread/dba28a81d9215291/ece2b50a3b4022c
  // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611

  if (val->IsArray()) {
    fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
                    "Use 'binary'.\n");
    assert(0);
    return -1;
  }

  v8::Local<v8::String> str = val->ToString();

  if (encoding == UTF8) {
    str->WriteUtf8(buf, buflen);
    return buflen;
  }

  if (encoding == ASCII) {
    str->WriteAscii(buf, 0, buflen);
    return buflen;
  }

  // THIS IS AWFUL!!! FIXME

  assert(encoding == BINARY);

  uint16_t * twobytebuf = new uint16_t[buflen];

  str->Write(twobytebuf, 0, buflen);

  for (size_t i = 0; i < buflen; i++) {
    unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
    assert(b[1] == 0);
    buf[i] = b[0];
  }

  delete [] twobytebuf;

  return buflen;
}
Пример #9
0
// Returns -1 if the handle was not valid for decoding
ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
  v8::HandleScope scope;

  if (val->IsArray()) {
    fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
                    "Use 'binary'.\n");
    assert(0);
    return -1;
  }

  v8::Local<v8::String> str = val->ToString();

  if (encoding == UTF8) return str->Utf8Length();

  return str->Length();
}
Пример #10
0
    Object^ V8Interop::FromV8(v8::Handle<v8::Value> value) 
    {
        if (value->IsString()) 
        {
            return FromV8String(value);
        } 
        else if (value->IsBoolean()) 
        {
            return FromV8Boolean(value);
        } 
        else if (value->IsInt32()) 
        {
            return FromV8Int32(value);
        } 
        else if (value->IsArray()) 
        {
            return FromV8Array(value);
        } 
        else if (value->IsDate()) 
        {
            return FromV8Date(value);
        } 
        else if (value->IsNumber()) 
        {
            return FromV8Double(value);
        } 
        else if (value->IsFunction()) 
        {
            return FromV8Function(value);
        } 
        else if (value->IsExternal()) 
        {
            return FromV8External(value);
        } 
        else if (value->IsObject()) 
        {
            return FromV8Object(value);
        } 
        else if (value->IsUndefined() || value->IsNull()) 
        {
            return nullptr;
        }

        return nullptr;
    }
Пример #11
0
QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value,
                                       V8ObjectSet &visitedObjects)
{
    if (value->IsString())
        return QJsonValue(QJSConverter::toString(value.As<v8::String>()));
    else if (value->IsNumber())
        return QJsonValue(value->NumberValue());
    else if (value->IsBoolean())
        return QJsonValue(value->BooleanValue());
    else if (value->IsArray())
        return toJsonArray(value.As<v8::Array>(), visitedObjects);
    else if (value->IsObject())
        return toJsonObject(value.As<v8::Object>(), visitedObjects);
    else if (value->IsNull())
        return QJsonValue(QJsonValue::Null);
    else
        return QJsonValue(QJsonValue::Undefined);
}
Пример #12
0
bool CJavaFunction::CanConvert(jclass clazz, v8::Handle<v8::Value> value)
{
  jni::V8Env env(m_pEnv);

  if (value->IsTrue() || value->IsFalse() || value->IsBoolean())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Boolean, clazz);
  }
  else if (value->IsInt32() || value->IsUint32())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Long, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Integer, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Short, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Byte, clazz);
  }
  else if (value->IsNumber())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Double, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Float, clazz);
  }
  else if (value->IsString())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.String, clazz);
  }
  else if (value->IsDate())
  {
    return env.IsAssignableFrom(env.buildins.java.util.Date, clazz);
  }
  else if (value->IsArray())
  {
    return env.IsAssignableFrom(env.buildins.lu.flier.script.V8Array, clazz);
  }
  else if (value.IsEmpty() || value->IsNull() || value->IsUndefined() || value->IsObject())
  {
    return true;
  }
  
  return false;
}
Пример #13
0
static Value v8ValueToValue(v8::Handle<v8::Value> v8Value)
{
    v8::HandleScope scope;
    if (v8Value->IsArray()) {
        List<Value> value;
        const v8::Handle<v8::Array> v8Array = v8::Handle<v8::Array>::Cast(v8Value);
        const uint32_t size = v8Array->Length();
        for (uint32_t i = 0; i < size; ++i) {
            if (v8Array->Has(i))
                value.append(v8ValueToValue(v8Array->Get(i)));
            else
                value.append(Value());
        }
        return Value(value);
    } else if (v8Value->IsObject()) {
        Map<String, Value> value;
        const v8::Handle<v8::Object> v8Object = v8Value->ToObject();
        const v8::Handle<v8::Array> props = v8Object->GetPropertyNames();
        const uint32_t size = props->Length();
        for (uint32_t i = 0; i < size; ++i) {
            assert(props->Has(i));
            const v8::Handle<v8::Value> name = props->Get(i);
            value[String(*v8::String::Utf8Value(name))] = v8ValueToValue(v8Object->Get(name));
        }
        return Value(value);
    } else if (v8Value->IsBoolean()) {
        return Value(v8Value->BooleanValue());
    } else if (v8Value->IsInt32() || v8Value->IsUint32()) {
        return Value(v8Value->Int32Value());
    } else if (v8Value->IsNumber()) {
        return Value(v8Value->NumberValue());
    } else if (v8Value->IsString()) {
        return Value(String(*v8::String::Utf8Value(v8Value)));
    } else {
        error() << "Unexpected v8 value type in JSONParser";
    }
    // undefined or null?
    return Value();
}
Пример #14
0
void v8ToMongoElement( BSONObjBuilder & b , v8::Handle<v8::String> name , const string sname , v8::Handle<v8::Value> value ){
        
    if ( value->IsString() ){
        if ( sname == "$where" )
            b.appendCode( sname.c_str() , toSTLString( value ).c_str() );
        else
            b.append( sname.c_str() , toSTLString( value ).c_str() );
        return;
    }
        
    if ( value->IsFunction() ){
        b.appendCode( sname.c_str() , toSTLString( value ).c_str() );
        return;
    }
    
    if ( value->IsNumber() ){
        b.append( sname.c_str() , value->ToNumber()->Value() );
        return;
    }
    
    if ( value->IsArray() ){
        BSONObj sub = v8ToMongo( value->ToObject() );
        b.appendArray( sname.c_str() , sub );
        return;
    }
    
    if ( value->IsDate() ){
        b.appendDate( sname.c_str() , (unsigned long long )(v8::Date::Cast( *value )->NumberValue()) );
        return;
    }
    
    if ( value->IsObject() ){
        string s = toSTLString( value );
        if ( s.size() && s[0] == '/' ){
            s = s.substr( 1 );
            string r = s.substr( 0 , s.find( "/" ) );
            string o = s.substr( s.find( "/" ) + 1 );
            b.appendRegex( sname.c_str() , r.c_str() , o.c_str() );
        }
        else if ( value->ToObject()->GetPrototype()->IsObject() &&
                  value->ToObject()->GetPrototype()->ToObject()->HasRealNamedProperty( String::New( "isObjectId" ) ) ){
            OID oid;
            oid.init( toSTLString( value ) );
            b.appendOID( sname.c_str() , &oid );
        }
        else {
            BSONObj sub = v8ToMongo( value->ToObject() );
            b.append( sname.c_str() , sub );
        }
        return;
    }
    
    if ( value->IsBoolean() ){
        b.appendBool( sname.c_str() , value->ToBoolean()->Value() );
        return;
    }
    
    else if ( value->IsUndefined() ){
        return;
    }
    
    else if ( value->IsNull() ){
        b.appendNull( sname.c_str() );
        return;
    }

    cout << "don't know how to covert to mongo field [" << name << "]\t" << value << endl;
}
Пример #15
0
 bool IsMatrix(v8::Handle<v8::Value> v)
 {
    return (!v.IsEmpty() && v->IsArray() && Handle<Array>::Cast(v)->Length() >= 16);
 }
Пример #16
0
static int FillShapeValueJson (v8::Isolate* isolate,
                               VocShaper* shaper,
                               TRI_shape_value_t* dst,
                               v8::Handle<v8::Value> const json,
                               size_t level,
                               set<int>& seenHashes,
                               vector<v8::Handle<v8::Object>>& seenObjects,
                               bool create) {
  v8::HandleScope scope(isolate);

  if (json->IsRegExp() || json->IsFunction() || json->IsExternal()) {
    LOG_TRACE("shaper failed because regexp/function/external/date object cannot be converted");
    return TRI_ERROR_BAD_PARAMETER;
  }
  
  if (json->IsNull() || json->IsUndefined()) {
    return FillShapeValueNull(shaper, dst);
  }

  if (json->IsBoolean()) {
    return FillShapeValueBoolean(shaper, dst, json->ToBoolean());
  }

  if (json->IsBooleanObject()) {
    return FillShapeValueBoolean(shaper, dst, v8::Handle<v8::BooleanObject>::Cast(json));
  }

  if (json->IsNumber()) {
    return FillShapeValueNumber(shaper, dst, json->ToNumber());
  }

  if (json->IsNumberObject()) {
    return FillShapeValueNumber(shaper, dst, v8::Handle<v8::NumberObject>::Cast(json));
  }

  if (json->IsString()) {
    return FillShapeValueString(shaper, dst, json->ToString());
  }

  if (json->IsStringObject()) {
    return FillShapeValueString(shaper, dst, v8::Handle<v8::StringObject>::Cast(json)->ValueOf());
  }

  else if (json->IsArray()) {
    return FillShapeValueList(isolate, shaper, dst, v8::Handle<v8::Array>::Cast(json), level, seenHashes, seenObjects, create);
  }

  if (json->IsObject()) {
    v8::Handle<v8::Object> o = json->ToObject();
    v8::Handle<v8::String> toJsonString = TRI_V8_PAIR_STRING("toJSON", 6);
    if (o->Has(toJsonString)) {
      v8::Handle<v8::Value> func = o->Get(toJsonString);
      if (func->IsFunction()) {
        v8::Handle<v8::Function> toJson = v8::Handle<v8::Function>::Cast(func);

        v8::Handle<v8::Value> args;
        v8::Handle<v8::Value> result = toJson->Call(o, 0, &args);

        if (! result.IsEmpty()) {
          return FillShapeValueString(shaper, dst, result->ToString());
        }
      }
    }

    // fall-through intentional
  
    // check for cycles
    int hash = o->GetIdentityHash();

    if (seenHashes.find(hash) != seenHashes.end()) {
      for (auto it = seenObjects.begin();  it != seenObjects.end();  ++it) {
        if (json->StrictEquals(*it)) {
          return TRI_ERROR_ARANGO_SHAPER_FAILED;
        }
      }
    }
    else {
      seenHashes.insert(hash);
    }

    seenObjects.push_back(o);
    int res = FillShapeValueArray(isolate, shaper, dst, json->ToObject(), level, seenHashes, seenObjects, create);
    seenObjects.pop_back();
    // cannot remove hash value from seenHashes because multiple objects might have the same
    // hash values (collisions)
    return res;
  }

  LOG_TRACE("shaper failed to convert object");
  return TRI_ERROR_BAD_PARAMETER;
}
Пример #17
0
void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine)
{
    if (v.IsEmpty()) {
    } else if (v->IsUndefined()) {
        push(data, valueheader(WorkerUndefined));
    } else if (v->IsNull()) {
        push(data, valueheader(WorkerNull));
    } else if (v->IsTrue()) {
        push(data, valueheader(WorkerTrue));
    } else if (v->IsFalse()) {
        push(data, valueheader(WorkerFalse));
    } else if (v->IsString()) {
        v8::Handle<v8::String> string = v->ToString();
        int length = string->Length() + 1;
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        int utf16size = ALIGN(length * sizeof(uint16_t));

        reserve(data, utf16size + sizeof(quint32));
        push(data, valueheader(WorkerString, length));
        
        int offset = data.size();
        data.resize(data.size() + utf16size);
        char *buffer = data.data() + offset;

        string->Write((uint16_t*)buffer);
    } else if (v->IsFunction()) {
        // XXX TODO: Implement passing function objects between the main and
        // worker scripts
        push(data, valueheader(WorkerUndefined));
    } else if (v->IsArray()) {
        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(v);
        uint32_t length = array->Length();
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        reserve(data, sizeof(quint32) + length * sizeof(quint32));
        push(data, valueheader(WorkerArray, length));
        for (uint32_t ii = 0; ii < length; ++ii)
            serialize(data, array->Get(ii), engine);
    } else if (v->IsInt32()) {
        reserve(data, 2 * sizeof(quint32));
        push(data, valueheader(WorkerInt32));
        push(data, (quint32)v->Int32Value());
    } else if (v->IsUint32()) {
        reserve(data, 2 * sizeof(quint32));
        push(data, valueheader(WorkerUint32));
        push(data, v->Uint32Value());
    } else if (v->IsNumber()) {
        reserve(data, sizeof(quint32) + sizeof(double));
        push(data, valueheader(WorkerNumber));
        push(data, v->NumberValue());
    } else if (v->IsDate()) {
        reserve(data, sizeof(quint32) + sizeof(double));
        push(data, valueheader(WorkerDate));
        push(data, v8::Handle<v8::Date>::Cast(v)->NumberValue());
    } else if (v->IsRegExp()) {
        v8::Handle<v8::RegExp> regexp = v8::Handle<v8::RegExp>::Cast(v);
        quint32 flags = regexp->GetFlags();
        v8::Local<v8::String> source = regexp->GetSource();

        int length = source->Length() + 1;
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        int utf16size = ALIGN(length * sizeof(uint16_t));

        reserve(data, sizeof(quint32) + utf16size);
        push(data, valueheader(WorkerRegexp, flags));
        push(data, (quint32)length);
        int offset = data.size();
        data.resize(data.size() + utf16size);
        char *buffer = data.data() + offset;

        source->Write((uint16_t*)buffer);
    } else if (v->IsObject() && !v->ToObject()->GetExternalResource()) {
        v8::Handle<v8::Object> object = v->ToObject();
        v8::Local<v8::Array> properties = engine->getOwnPropertyNames(object);
        quint32 length = properties->Length();
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        push(data, valueheader(WorkerObject, length));
        v8::TryCatch tc;
        for (quint32 ii = 0; ii < length; ++ii) {
            v8::Local<v8::String> str = properties->Get(ii)->ToString();
            serialize(data, str, engine);

            v8::Local<v8::Value> val = object->Get(str);
            if (tc.HasCaught()) {
                serialize(data, v8::Undefined(), engine);
                tc.Reset();
            } else {
                serialize(data, val, engine);
            }
        }
    } else if (engine->isQObject(v)) {
        // XXX TODO: Generalize passing objects between the main thread and worker scripts so 
        // that others can trivially plug in their elements.
        QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(engine->toQObject(v));
        if (lm && lm->agent()) {
            QDeclarativeListModelWorkerAgent *agent = lm->agent();
            agent->addref();
            push(data, valueheader(WorkerListModel));
            push(data, (void *)agent);
            return;
        } 
        // No other QObject's are allowed to be sent
        push(data, valueheader(WorkerUndefined));
    } else {
        push(data, valueheader(WorkerUndefined));
    }
}
Пример #18
0
static bool FillShapeValueJson (TRI_shaper_t* shaper,
                                TRI_shape_value_t* dst,
                                v8::Handle<v8::Value> json,
                                set<int>& seenHashes,
                                vector< v8::Handle<v8::Object> >& seenObjects) {
  if (json->IsObject()) {
    v8::Handle<v8::Object> o = json->ToObject();
    int hash = o->GetIdentityHash();

    if (seenHashes.find(hash) != seenHashes.end()) {
      LOG_TRACE("found hash %d", hash);

      for (vector< v8::Handle<v8::Object> >::iterator i = seenObjects.begin();  i != seenObjects.end();  ++i) {
        if (json->StrictEquals(*i)) {
          LOG_TRACE("found duplicate for hash %d", hash);
          return FillShapeValueNull(shaper, dst);
        }
      }

      seenObjects.push_back(o);
    }
    else {
      seenHashes.insert(hash);
      seenObjects.push_back(o);
    }
  }

  if (json->IsNull()) {
    return FillShapeValueNull(shaper, dst);
  }

  if (json->IsBoolean()) {
    return FillShapeValueBoolean(shaper, dst, json->ToBoolean());
  }

  if (json->IsBooleanObject()) {
    v8::Handle<v8::BooleanObject> bo = v8::Handle<v8::BooleanObject>::Cast(json);
    return FillShapeValueBoolean(shaper, dst, bo);
  }

  if (json->IsNumber()) {
    return FillShapeValueNumber(shaper, dst, json->ToNumber());
  }

  if (json->IsNumberObject()) {
    v8::Handle<v8::NumberObject> no = v8::Handle<v8::NumberObject>::Cast(json);
    return FillShapeValueNumber(shaper, dst, no);
  }

  if (json->IsString()) {
    return FillShapeValueString(shaper, dst, json->ToString());
  }

  if (json->IsStringObject()) {
    v8::Handle<v8::StringObject> so = v8::Handle<v8::StringObject>::Cast(json);
    return FillShapeValueString(shaper, dst, so->StringValue());
  }

  if (json->IsArray()) {
    v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(json);
    return FillShapeValueList(shaper, dst, array, seenHashes, seenObjects);
  }

  if (json->IsObject()) {
    return FillShapeValueArray(shaper, dst, json->ToObject(), seenHashes, seenObjects);
  }

  return false;
}
Пример #19
0
static int V8ToVPack(BuilderContext& context,
                     v8::Handle<v8::Value> const parameter,
                     std::string const& attributeName, bool inObject) {
  
  if (parameter->IsNull() || parameter->IsUndefined()) {
    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Null));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsBoolean()) {
    AddValue(context, attributeName, inObject,
             VPackValue(parameter->ToBoolean()->Value()));
    return TRI_ERROR_NO_ERROR;
  }
  
  if (parameter->IsNumber()) {
    if (parameter->IsInt32()) {
      AddValue(context, attributeName, inObject,
               VPackValue(parameter->ToInt32()->Value()));
      return TRI_ERROR_NO_ERROR;
    }
  
    if (parameter->IsUint32()) {
      AddValue(context, attributeName, inObject,
               VPackValue(parameter->ToUint32()->Value()));
      return TRI_ERROR_NO_ERROR;
    }

    AddValue(context, attributeName, inObject,
             VPackValue(parameter->ToNumber()->Value()));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsString()) {
    v8::String::Utf8Value str(parameter->ToString());

    if (*str == nullptr) {
      return TRI_ERROR_OUT_OF_MEMORY;
    }

    AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsArray()) {
    v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(parameter);

    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Array));
    uint32_t const n = array->Length();

    for (uint32_t i = 0; i < n; ++i) {
      v8::Handle<v8::Value> value = array->Get(i);
      if (value->IsUndefined()) {
        // ignore array values which are undefined
        continue;
      }

      if (++context.level > MaxLevels) {
        // too much recursion
        return TRI_ERROR_BAD_PARAMETER;
      }

      int res = V8ToVPack<performAllChecks>(context, value, NoAttribute, false);
      
      --context.level;

      if (res != TRI_ERROR_NO_ERROR) {
        return res;
      }
    }

    if (!context.keepTopLevelOpen || context.level > 0) {
      context.builder.close();
    }
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsObject()) {
    if (performAllChecks) {
      if (parameter->IsBooleanObject()) {
        AddValue(context, attributeName, inObject,
                VPackValue(v8::Handle<v8::BooleanObject>::Cast(parameter)
                                ->BooleanValue()));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsNumberObject()) {
        AddValue(context, attributeName, inObject,
                VPackValue(v8::Handle<v8::NumberObject>::Cast(parameter)
                                ->NumberValue()));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsStringObject()) {
        v8::String::Utf8Value str(parameter->ToString());

        if (*str == nullptr) {
          return TRI_ERROR_OUT_OF_MEMORY;
        }

        AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsRegExp() || parameter->IsFunction() ||
          parameter->IsExternal()) {
        return TRI_ERROR_BAD_PARAMETER;
      }
    }

    v8::Handle<v8::Object> o = parameter->ToObject();

    if (performAllChecks) {
      // first check if the object has a "toJSON" function
      if (o->Has(context.toJsonKey)) {
        // call it if yes
        v8::Handle<v8::Value> func = o->Get(context.toJsonKey);
        if (func->IsFunction()) {
          v8::Handle<v8::Function> toJson = v8::Handle<v8::Function>::Cast(func);

          v8::Handle<v8::Value> args;
          v8::Handle<v8::Value> converted = toJson->Call(o, 0, &args);

          if (!converted.IsEmpty()) {
            // return whatever toJSON returned
            v8::String::Utf8Value str(converted->ToString());

            if (*str == nullptr) {
              return TRI_ERROR_OUT_OF_MEMORY;
            }

            // this passes ownership for the utf8 string to the JSON object
            AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
            return TRI_ERROR_NO_ERROR;
          }
        }

        // fall-through intentional
      }
    }

    v8::Handle<v8::Array> names = o->GetOwnPropertyNames();
    uint32_t const n = names->Length();

    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Object));

    for (uint32_t i = 0; i < n; ++i) {
      // process attribute name
      v8::Handle<v8::Value> key = names->Get(i);
      v8::String::Utf8Value str(key);

      if (*str == nullptr) {
        return TRI_ERROR_OUT_OF_MEMORY;
      }

      v8::Handle<v8::Value> value = o->Get(key);
      if (value->IsUndefined()) {
        // ignore object values which are undefined
        continue;
      }

      if (++context.level > MaxLevels) {
        // too much recursion
        return TRI_ERROR_BAD_PARAMETER;
      }

      int res = V8ToVPack<performAllChecks>(context, value, *str, true);
      
      --context.level;

      if (res != TRI_ERROR_NO_ERROR) {
        return res;
      }
    }

    if (!context.keepTopLevelOpen || context.level > 0) {
      context.builder.close();
    }
    return TRI_ERROR_NO_ERROR;
  }

  return TRI_ERROR_BAD_PARAMETER;
}
Пример #20
0
    void v8ToMongoElement( BSONObjBuilder & b , v8::Handle<v8::String> name , const string sname , v8::Handle<v8::Value> value ){
        
        if ( value->IsString() ){
            b.append( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
        
        if ( value->IsFunction() ){
            b.appendCode( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
    
        if ( value->IsNumber() ){
            if ( value->IsInt32() )
                b.append( sname.c_str(), int( value->ToInt32()->Value() ) );
            else
                b.append( sname.c_str() , value->ToNumber()->Value() );
            return;
        }
    
        if ( value->IsArray() ){
            BSONObj sub = v8ToMongo( value->ToObject() );
            b.appendArray( sname.c_str() , sub );
            return;
        }
    
        if ( value->IsDate() ){
            b.appendDate( sname.c_str() , Date_t(v8::Date::Cast( *value )->NumberValue()) );
            return;
        }

        if ( value->IsExternal() )
            return;
        
        if ( value->IsObject() ){
            // The user could potentially modify the fields of these special objects,
            // wreaking havoc when we attempt to reinterpret them.  Not doing any validation
            // for now...
            Local< v8::Object > obj = value->ToObject();
            if ( obj->InternalFieldCount() && obj->GetInternalField( 0 )->IsNumber() ) {
                switch( obj->GetInternalField( 0 )->ToInt32()->Value() ) { // NOTE Uint32's Value() gave me a linking error, so going with this instead
                    case Timestamp:
                        b.appendTimestamp( sname.c_str(),
                                          Date_t( v8::Date::Cast( *obj->Get( v8::String::New( "time" ) ) )->NumberValue() ),
                                          obj->Get( v8::String::New( "i" ) )->ToInt32()->Value() );
                        return;
                    case MinKey:
                        b.appendMinKey( sname.c_str() );
                        return;
                    case MaxKey:
                        b.appendMaxKey( sname.c_str() );
                        return;
                    default:
                        assert( "invalid internal field" == 0 );
                }
            }
            string s = toSTLString( value );
            if ( s.size() && s[0] == '/' ){
                s = s.substr( 1 );
                string r = s.substr( 0 , s.rfind( "/" ) );
                string o = s.substr( s.rfind( "/" ) + 1 );
                b.appendRegex( sname.c_str() , r.c_str() , o.c_str() );
            }
            else if ( value->ToObject()->GetPrototype()->IsObject() &&
                      value->ToObject()->GetPrototype()->ToObject()->HasRealNamedProperty( v8::String::New( "isObjectId" ) ) ){
                OID oid;
                oid.init( toSTLString( value ) );
                b.appendOID( sname.c_str() , &oid );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__NumberLong" ) ).IsEmpty() ) {
                // TODO might be nice to potentially speed this up with an indexed internal
                // field, but I don't yet know how to use an ObjectTemplate with a
                // constructor.
                unsigned long long val =
                ( (unsigned long long)( value->ToObject()->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
                (unsigned)( value->ToObject()->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
                b.append( sname.c_str(), (long long)val );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) {
                OID oid;
                oid.init( toSTLString( value->ToObject()->Get( v8::String::New( "id" ) ) ) );
                string ns = toSTLString( value->ToObject()->Get( v8::String::New( "ns" ) ) );
                b.appendDBRef( sname.c_str(), ns.c_str(), oid );                
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__BinData" ) ).IsEmpty() ) {
                int len = obj->Get( v8::String::New( "len" ) )->ToInt32()->Value();
                v8::String::Utf8Value data( obj->Get( v8::String::New( "data" ) ) );
                const char *dataArray = *data;
                assert( data.length() == len );
                b.appendBinData( sname.c_str(),
                                len,
                                mongo::BinDataType( obj->Get( v8::String::New( "type" ) )->ToInt32()->Value() ),
                                dataArray );
            } else {
                BSONObj sub = v8ToMongo( value->ToObject() );
                b.append( sname.c_str() , sub );
            }
            return;
        }
    
        if ( value->IsBoolean() ){
            b.appendBool( sname.c_str() , value->ToBoolean()->Value() );
            return;
        }
    
        else if ( value->IsUndefined() ){
            b.appendUndefined( sname.c_str() );
            return;
        }
    
        else if ( value->IsNull() ){
            b.appendNull( sname.c_str() );
            return;
        }

        cout << "don't know how to convert to mongo field [" << name << "]\t" << value << endl;
    }