unqlite_value* VirtualMachine::createUnqlite(const QVariant& var) { unqlite_value* retval = NULL; QVariant::Type type = var.type(); if (type == QVariant::Map) { retval = unqlite_vm_new_array(m_pVm); QMap<QString, QVariant> map = var.toMap(); QMapIterator<QString, QVariant> it(map); while (it.hasNext()) { it.next(); unqlite_value* pVal = createUnqlite(it.value()); if (pVal) { QString key = it.key(); const char* pKey = key.toUtf8().data(); unqlite_array_add_strkey_elem(retval, pKey, pVal); unqlite_vm_release_value(m_pVm, pVal); } else { qDebug() << "Could not create unqlite value for map"; } } } else if (type == QVariant::List) { retval = unqlite_vm_new_array(m_pVm); QList<QVariant> list = var.toList(); QListIterator<QVariant> it(list); while (it.hasNext()) { unqlite_value* pVal = createUnqlite(it.next()); if (pVal) { unqlite_array_add_elem(retval, NULL, pVal); unqlite_vm_release_value(m_pVm, pVal); } else { qDebug() << "Could not create unqlite value for list"; } } } else { retval = unqlite_vm_new_scalar(m_pVm); if (type == QVariant::Int || type == QVariant::UInt) { unqlite_value_int(retval, var.toInt()); } else if (type == QVariant::Double) { unqlite_value_double(retval, var.toDouble()); } else if (type == QVariant::Bool) { unqlite_value_bool(retval, var.toBool()); } else if (type == QVariant::String) { QByteArray bytes = var.toString().toUtf8(); unqlite_value_string(retval, bytes.data(), bytes.length()); } else { qDebug() << "Could not determine type of the given QVariant" << var; } } return retval; }
Producer::Config::Config( const string& file, uint32_t id ) { // set default values prefix = Name("unnamed"); sigverif_delay = NanoSeconds( 30345 ); bloom_delay = NanoSeconds( 2535 ); // database and vm structs unqlite* db; unqlite_vm* vm; // initialize database int rc = unqlite_open( &db, ":mem:", UNQLITE_OPEN_READONLY ); if( rc != UNQLITE_OK ) { // something went wrong const char* err; int errlen; unqlite_config( db, UNQLITE_CONFIG_JX9_ERR_LOG, &err, &errlen ); cout << "Error: creating unqlite database: " << err << endl; exit(1); } // initialize unqlite vm rc = unqlite_compile_file( db, file.c_str(), &vm ); if( rc != UNQLITE_OK ) { // something went wrong const char* err; int errlen; unqlite_config( db, UNQLITE_CONFIG_JX9_ERR_LOG, &err, &errlen ); cout << "Error: compiling config script: " << err << endl; exit(1); } unqlite_value* id_val = unqlite_vm_new_scalar( vm ); unqlite_value_int64( id_val, id ); rc = unqlite_vm_config( vm, UNQLITE_VM_CONFIG_CREATE_VAR, "ID", id_val ); if( rc != UNQLITE_OK ) { // something went wrong const char* err; int errlen; unqlite_config( db, UNQLITE_CONFIG_JX9_ERR_LOG, &err, &errlen ); cout << "Error: exporting ID to config: " << err << endl; exit(1); } unqlite_vm_release_value( vm, id_val ); // execute config script rc = unqlite_vm_exec( vm ); if( rc != UNQLITE_OK ) { // something went wrong const char* err; int errlen; unqlite_config( db, UNQLITE_CONFIG_JX9_ERR_LOG, &err, &errlen ); cout << "Error: executing config script: " << err << endl; exit(1); } // retrieve config values const char* str; int len; unqlite_value* val; val = unqlite_vm_extract_variable( vm, "prefix" ); if( val ) { str = unqlite_value_to_string( val, &len ); prefix = string(str, len ); } val = unqlite_vm_extract_variable( vm, "sigverif_delay" ); if( unqlite_value_is_float( val ) ) sigverif_delay = Seconds( unqlite_value_to_double( val ) ); if( unqlite_value_is_int( val ) ) sigverif_delay = Seconds( unqlite_value_to_int64( val ) ); val = unqlite_vm_extract_variable( vm, "bloom_delay" ); if( unqlite_value_is_float( val ) ) bloom_delay = Seconds( unqlite_value_to_double( val ) ); if( unqlite_value_is_int( val ) ) bloom_delay = Seconds( unqlite_value_to_int64( val ) ); val = unqlite_vm_extract_variable( vm, "contents" ); if( val && unqlite_value_is_json_array( val ) ) { size_t count = unqlite_array_count( val ); for( size_t i = 0 ; i < count ; i++ ) { stringstream ss; string key; ss << i; ss >> key; unqlite_value* elem = unqlite_array_fetch ( val, key.c_str(), key.size() ); if( elem && unqlite_value_is_json_object( elem ) ) { unqlite_value* name_val = unqlite_array_fetch ( elem, "name", -1 ); unqlite_value* size_val = unqlite_array_fetch ( elem, "size", -1 ); unqlite_value* access_val = unqlite_array_fetch( elem, "access_level", -1 ); if( name_val && size_val && access_val && unqlite_value_is_string( name_val ) && unqlite_value_is_int( size_val ) && unqlite_value_is_int( access_val ) ) { str = unqlite_value_to_string( name_val, &len ); size_t size = unqlite_value_to_int( size_val ); uint8_t access_level = unqlite_value_to_int ( access_val ); contents.emplace( string( str, len ), Config::Content { size, access_level } ); } } } }