void Calc::Minimum(const ValueList& args, KValueRef result) { if (args.at(0)->IsList()) { KListRef list = args.at(0)->ToList(); double *arr = NULL; arr = new double[list->Size()]; for (unsigned int c = 0; c < list->Size(); c++) { KValueRef d = list->At(c); arr[c] = d->ToDouble(); } double low = Min(arr, list->Size()); result->SetDouble(low); delete [] arr; } else { throw ValueException::FromString("Minimum takes an array"); } }
void Bytes::_Split(const ValueList& args, KValueRef result) { // This method now follows the spec located at: // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/split // Except support for regular expressions args.VerifyException("Bytes.split", "?s,i"); KListRef list = new StaticBoundList(); result->SetList(list); std::string target = ""; if (this->size > 0) { target = this->buffer; } else { list->Append(Value::NewString(target)); return; } if (args.size() <= 0) { list->Append(Value::NewString(target)); return; } std::string separator = args.GetString(0); int limit = args.GetInt(1, INT_MAX); // We could use Poco's tokenizer here, but it doesn't split strings // like "abc,def,," -> ['abc', 'def', '', ''] correctly. It produces // ['abc', 'def', ''] which is a different behavior than the JS split. // So we roll our own for now -- it's not very efficient right now, but // it should be correct. size_t next = target.find(separator); while (target.size() > 0 && next != std::string::npos) { std::string token; if (separator.size() == 0) { token = target.substr(0, 1); } else { token = target.substr(0, next); } target = target.substr(next + 1); next = target.find(separator); if ((int) list->Size() >= limit) return; list->Append(Value::NewString(token)); } if ((int) list->Size() < limit && separator.size() != 0) list->Append(Value::NewString(target)); }
void Properties::SetList(const ValueList& args, KValueRef result) { args.VerifyException("setList", "s l"); std::string property = args.at(0)->ToString(); KListRef list = args.at(1)->ToList(); std::string value = ""; for (unsigned int i = 0; i < list->Size(); i++) { KValueRef arg = list->At(i); if (arg->IsString()) { value += list->At(i)->ToString(); if (i < list->Size() - 1) { value += ","; } } else { logger->Warn("Skipping list entry %ui, not a string", i); } } config->setString(property, value); this->SaveConfig(); }
void PropertiesBinding::SetList(const ValueList& args, KValueRef result) { if (args.size() >= 2 && args.at(0)->IsString() && args.at(1)->IsList()) { std::string property = args.at(0)->ToString(); KListRef list = args.at(1)->ToList(); std::string value = ""; for (unsigned int i = 0; i < list->Size(); i++) { KValueRef arg = list->At(i); if (arg->IsString()) { value += list->At(i)->ToString(); if (i < list->Size() - 1) { value += ","; } } else { std::cerr << "skipping object: " << arg->GetType() << std::endl; } } config->setString(property, value); if (file_path.size() > 0) { config->save(file_path); } } }
void FilesystemBinding::ResolveFileName(const ValueList& args, std::string& filename) { if (args.at(0)->IsList()) { // you can pass in an array of parts to join KListRef list = args.at(0)->ToList(); for (size_t c = 0; c < list->Size(); c++) { std::string arg = list->At(c)->ToString(); filename = kroll::FileUtils::Join(filename.c_str(), arg.c_str(), NULL); } } else { // you can pass in vararg of strings which acts like a join for (size_t c = 0; c < args.size(); c++) { std::string arg = FileSystemUtils::GetFileName(args.at(c))->c_str(); filename = kroll::FileUtils::Join(filename.c_str(), arg.c_str(), NULL); } } if (filename.empty()) { throw ValueException::FromString("invalid file type"); } }
void KObject::GetStringList(const char *name, std::vector<std::string> &list) { KValueRef prop = this->Get(name); if(!prop->IsUndefined() && prop->IsList()) { KListRef values = prop->ToList(); if (values->Size() > 0) { for (unsigned int c = 0; c < values->Size(); c++) { KValueRef v = values->At(c); if (v->IsString()) { const char *s = v->ToString(); list.push_back(s); } } } } }
/* Inspired by python's os.list2cmdline, ported to C++ by Marshall Culpepper Translate a sequence of arguments into a command line string, using the same rules as the MS C runtime: 1) Arguments are delimited by white space, which is either a space or a tab. 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. 4) Backslashes are interpreted literally, unless they immediately precede a double quotation mark. 5) If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule 3. See http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp */ std::string ProcessWin::ArgListToString(KListRef argList) { std::string result = ""; bool needQuote = false; for (int i = 0; i < argList->Size(); i++) { std::string arg = argList->At(i)->ToString(); std::string backspaceBuf = ""; // Add a space to separate this argument from the others if (result.size() > 0) { result += ' '; } needQuote = (arg.find_first_of(" \t") != std::string::npos) || arg == ""; if (needQuote) { result += '"'; } for (int j = 0; j < arg.size(); j++) { char c = arg[j]; if (c == '\\') { // Don't know if we need to double yet. backspaceBuf += c; } else if (c == '"') { // Double backspaces. result.append(backspaceBuf.size()*2, '\\'); backspaceBuf = ""; result.append("\\\""); } else { // Normal char if (backspaceBuf.size() > 0) { result.append(backspaceBuf); backspaceBuf = ""; } result += c; } } // Add remaining backspaces, if any. if (backspaceBuf.size() > 0) { result.append(backspaceBuf); } if (needQuote) { result.append(backspaceBuf); result += '"'; } } return result; }
void FilesystemBinding::ExecuteAsyncCopy(const ValueList& args, KValueRef result) { if (args.size()!=3) { throw ValueException::FromString("invalid arguments - this method takes 3 arguments"); } std::vector<std::string> files; if (args.at(0)->IsString()) { files.push_back(args.at(0)->ToString()); } else if (args.at(0)->IsList()) { KListRef list = args.at(0)->ToList(); for (unsigned int c = 0; c < list->Size(); c++) { KValueRef v = list->At(c); files.push_back(FileSystemUtils::GetFileName(v)->c_str()); } } else { files.push_back(FileSystemUtils::GetFileName(args.at(0))->c_str()); } KValueRef v = args.at(1); std::string destination(FileSystemUtils::GetFileName(v)->c_str()); KMethodRef method = args.at(2)->ToMethod(); KObjectRef copier = new ti::AsyncCopy(this,host,files,destination,method); result->SetObject(copier); asyncOperations.push_back(copier); // we need to create a timer thread that can cleanup operations if (timer==NULL) { this->SetMethod("_invoke",&FilesystemBinding::DeletePendingOperations); timer = new Poco::Timer(100,100); Poco::TimerCallback<FilesystemBinding> cb(*this, &FilesystemBinding::OnAsyncOperationTimer); timer->start(cb); } else { this->timer->restart(100); } }
void APIBinding::_InstallDependencies(const ValueList& args, KValueRef result) { args.VerifyException("installDependencies", "l,m"); KListRef dependenciesList = args.GetList(0); KMethodRef callback = args.GetMethod(1, 0); vector<SharedDependency> dependencies; for (unsigned int i = 0; i < dependenciesList->Size(); i++) { if (!dependenciesList->At(i)->IsObject()) { continue; } AutoPtr<DependencyBinding> d = dependenciesList->At(i)->ToObject().cast<DependencyBinding>(); if (!d.isNull()) { dependencies.push_back(d->GetDependency()); } } if (dependencies.size() > 0) { if (!this->installerMutex.tryLock()) { throw ValueException::FromString( "Tried to launch more than one instance of the installer"); } if (this->installerThread) { delete this->installerThread; } this->installerDependencies = dependencies; this->installerCallback = callback; this->installerThread = new Poco::Thread(); this->installerThread->start(*this->installerThreadAdapter); } }
static void GetBytes(KValueRef value, std::vector<BytesRef>& blobs) { if (value->IsObject()) { blobs.push_back(value->ToObject().cast<Bytes>()); } else if (value->IsString()) { blobs.push_back(new Bytes(value->ToString())); } else if (value->IsList()) { KListRef list = value->ToList(); for (size_t j = 0; j < list->Size(); j++) { GetBytes(list->At((int)j), blobs); } } else if (value->IsNumber()) { blobs.push_back(new Bytes(value->ToInt())); } }
void Database::Execute(const ValueList& args, KValueRef result) { args.VerifyException("execute", "s"); if (!session) throw ValueException::FromString("Tried to call execute, but database was closed."); std::string sql(args.GetString(0)); GetLogger()->Debug("Execute called with %s", sql.c_str()); Statement select(*this->session); try { ValueBinding binding; select << sql; if (args.size()>1) { for (size_t c=1;c<args.size();c++) { KValueRef anarg = args.at(c); if (anarg->IsList()) { KListRef list = anarg->ToList(); for (size_t a=0;a<list->Size();a++) { KValueRef arg = list->At(a); binding.convert(select,arg); } } else { binding.convert(select,anarg); } } } Poco::UInt32 count = select.execute(); GetLogger()->Debug("sql returned: %d rows for result",count); this->SetInt("rowsAffected",count); // get the row insert id Statement ss(*this->session); ss << "select last_insert_rowid()", now; RecordSet rr(ss); Poco::DynamicAny value = rr.value(0); int i; value.convert(i); this->SetInt("lastInsertRowId",i); if (count > 0) { RecordSet rs(select); KObjectRef r = new ResultSet(rs); result->SetObject(r); } else { KObjectRef r = new ResultSet(); result->SetObject(r); } } catch (Poco::Data::DataException &e) { GetLogger()->Error("Exception executing: %s, Error was: %s", sql.c_str(), e.what()); throw ValueException::FromString(e.what()); } }