bool not_less(CVarRef v1, CVarRef v2) { if (v1.is(KindOfArray) && v2.is(KindOfArray)) { Array a1 = v1.toArray(); Array a2 = v2.toArray(); return a1.more(a2) || a1.equal(a2); } return !less(v1, v2); }
bool more_or_equal(CVarRef v1, CVarRef v2) { // To be PHP-compatible, when comparing two arrays or two objects we // cannot assume that "($x >= $y)" is equivalent to "!($x < $y)". if (v1.is(KindOfArray) && v2.is(KindOfArray)) { Array a1 = v1.toArray(); Array a2 = v2.toArray(); return a1.more(a2) || a1.equal(a2); } if (v1.is(KindOfObject) && v2.is(KindOfObject)) { Object o1 = v1.toObject(); Object o2 = v2.toObject(); return o1.more(o2) || o1.equal(o2); } return !less(v1, v2); }
String f_implode(CVarRef arg1, CVarRef arg2 /* = null_variant */) { Array items; String delim; if (arg1.is(KindOfArray)) { items = arg1.toArray(); delim = arg2.toString(); } else if (arg2.is(KindOfArray)) { items = arg2.toArray(); delim = arg1.toString(); } else { throw_bad_type_exception("arguments need at least one array"); return String(); } return StringUtil::Implode(items, delim); }
bool TestBase::array_value_exists(CVarRef var, CVarRef value) { bool found = !same(f_array_search(value, var.toArray()), false); if (!found) { f_var_dump(var); } return found; }
Variant f_max(int _argc, CVarRef value, CArrRef _argv /* = null_array */) { Variant ret; if (_argv.empty() && value.is(KindOfArray)) { Array v = value.toArray(); if (!v.empty()) { ssize_t pos = v->iter_begin(); if (pos != ArrayData::invalid_index) { ret = v->getValue(pos); while (true) { pos = v->iter_advance(pos); if (pos == ArrayData::invalid_index) break; Variant tmp = v->getValue(pos); if (more(tmp, ret)) { ret = tmp; } } } } } else { ret = value; if (!_argv.empty()) { for (ssize_t pos = _argv->iter_begin(); pos != ArrayData::invalid_index; pos = _argv->iter_advance(pos)) { Variant tmp = _argv->getValue(pos); if (more(tmp, ret)) { ret = tmp; } } } } return ret; }
Variant f_apc_exists(CVarRef key, int64_t cache_id /* = 0 */) { if (!apcExtension::Enable) return false; if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) { throw_invalid_argument("cache_id: %" PRId64, cache_id); return false; } if (key.is(KindOfArray)) { Array keys = key.toArray(); ArrayInit init(keys.size()); for (ArrayIter iter(keys); iter; ++iter) { Variant k = iter.second(); if (!k.isString()) { throw_invalid_argument("apc key: (not a string)"); return false; } String strKey = k.toString(); if (s_apc_store[cache_id].exists(strKey)) { init.set(strKey); } } return init.create(); } return s_apc_store[cache_id].exists(key.toString()); }
static void url_encode_array(StringBuffer &ret, CVarRef varr, std::set<void*> &seen_arrs, CStrRef num_prefix, CStrRef key_prefix, CStrRef key_suffix, CStrRef arg_sep) { void *id = varr.is(KindOfArray) ? (void*)varr.getArrayData() : (void*)varr.getObjectData(); if (!seen_arrs.insert(id).second) { return; // recursive } Array arr = varr.toArray(); for (ArrayIter iter(arr); iter; ++iter) { Variant data = iter.second(); if (data.isNull() || data.isResource()) continue; String key = iter.first(); bool numeric = key.isNumeric(); if (data.is(KindOfArray) || data.is(KindOfObject)) { String encoded; if (numeric) { encoded = key; } else { encoded = StringUtil::UrlEncode(key); } StringBuffer new_prefix(key_prefix.size() + num_prefix.size() + encoded.size() + key_suffix.size() + 4); new_prefix += key_prefix; if (numeric) new_prefix += num_prefix; new_prefix += encoded; new_prefix += key_suffix; new_prefix += "%5B"; url_encode_array(ret, data, seen_arrs, String(), new_prefix.detach(), String("%5D", AttachLiteral), arg_sep); } else { if (!ret.empty()) { ret += arg_sep; } ret += key_prefix; if (numeric) { ret += num_prefix; ret += key; } else { ret += StringUtil::UrlEncode(key); } ret += key_suffix; ret += "="; if (data.isInteger() || data.is(KindOfBoolean)) { ret += String(data.toInt64()); } else if (data.is(KindOfDouble)) { ret += String(data.toDouble()); } else { ret += StringUtil::UrlEncode(data.toString()); } } } }
bool Array::less(CVarRef v2) const { if (m_px == nullptr || v2.isNull()) { return HPHP::less(toBoolean(), v2.toBoolean()); } if (v2.getType() == KindOfArray) { return m_px->compare(v2.toArray().get()) < 0; } return v2.more(*this); }
bool Array::more(CVarRef v2) const { if (m_px == NULL || v2.isNull()) { return HPHP::more(toBoolean(), v2.toBoolean()); } if (v2.getType() == KindOfArray) { return v2.toArray().get()->compare(m_px) < 0; } return v2.less(*this); }
Variant f_strtr(CStrRef str, CVarRef from, CVarRef to /* = null_variant */) { if (str.empty()) { return str; } if (!to.isNull()) { return StringUtil::Translate(str, from.toString(), to.toString()); } if (!from.is(KindOfArray)) { throw_invalid_argument("2nd argument: (not array)"); return false; } int maxlen = 0; int minlen = -1; Array arr = from.toArray(); for (ArrayIter iter(arr); iter; ++iter) { String search = iter.first(); int len = search.size(); if (len < 1) return false; if (maxlen < len) maxlen = len; if (minlen == -1 || minlen > len) minlen = len; } const char *s = str.data(); int slen = str.size(); char *key = (char *)malloc(maxlen+1); StringBuffer result(slen); for (int pos = 0; pos < slen; ) { if ((pos + maxlen) > slen) { maxlen = slen - pos; } bool found = false; memcpy(key, s + pos, maxlen); for (int len = maxlen; len >= minlen; len--) { key[len] = 0; if (arr.exists(key)) { String replace = arr[key].toString(); if (!replace.empty()) { result += replace; } pos += len; found = true; break; } } if (!found) { result += s[pos++]; } } free(key); return result.detach(); }
Array ArrayUtil::Splice(CArrRef input, int offset, int length /* = 0 */, CVarRef replacement /* = null_variant */, Array *removed /* = NULL */) { int num_in = input.size(); if (offset > num_in) { offset = num_in; } else if (offset < 0 && (offset = (num_in + offset)) < 0) { offset = 0; } if (length < 0) { length = num_in - offset + length; } else if (((unsigned)offset + (unsigned)length) > (unsigned)num_in) { length = num_in - offset; } Array out_hash = Array::Create(); int pos = 0; ArrayIter iter(input); for (; pos < offset && iter; ++pos, ++iter) { if (iter.first().isNumeric()) { out_hash.append(iter.second()); } else { out_hash.set(iter.first(), iter.second()); } } for (; pos < offset + length && iter; ++pos, ++iter) { if (removed) { if (iter.first().isNumeric()) { removed->append(iter.second()); } else { removed->set(iter.first(), iter.second()); } } } Array arr = replacement.toArray(); if (!arr.empty()) { for (ArrayIter iter(arr); iter; ++iter) { out_hash.append(iter.second()); } } for (; iter; ++iter) { if (iter.first().isNumeric()) { out_hash.append(iter.second()); } else { out_hash.set(iter.first(), iter.second()); } } return out_hash; }
static Variant str_replace(CVarRef search, CVarRef replace, CStrRef subject, int &count, bool caseSensitive) { if (search.is(KindOfArray)) { String ret = subject; Array searchArr = search.toArray(); if (replace.is(KindOfArray)) { Array replArr = replace.toArray(); ArrayIter replIter(replArr); for (ArrayIter iter(searchArr); iter; ++iter) { TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE); if (replIter) { ret = ret.replace(iter.second().toString(), replIter.second().toString(), count, caseSensitive); ++replIter; } else { ret = ret.replace(iter.second().toString(), "", count, caseSensitive); } } return ret; } TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE); String repl = replace.toString(); for (ArrayIter iter(searchArr); iter; ++iter) { ret = ret.replace(iter.second().toString(), repl, count, caseSensitive); } return ret; } if (replace.is(KindOfArray)) { raise_notice("Array to string conversion"); } TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE); return subject.replace(search.toString(), replace.toString(), count, caseSensitive); }
void c_DebuggerClientCmdUser::t_addcompletion(CVarRef list) { INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClientCmdUser, DebuggerClientCmdUser::addcompletion); if (list.isInteger()) { m_client->addCompletion((DebuggerClient::AutoComplete)list.toInt64()); } else { Array arr = list.toArray(); // handles string, array and iterators std::vector<std::string> items; for (ArrayIter iter(arr); iter; ++iter) { items.push_back(iter.second().toString()->toCPPString()); } m_client->addCompletion(items); } }
Variant f_substr_replace(CVarRef str, CVarRef replacement, CVarRef start, CVarRef length /* = 0x7FFFFFFF */) { if (!str.is(KindOfArray)) { String repl; if (replacement.is(KindOfArray)) { repl = replacement[0].toString(); } else { repl = replacement.toString(); } if (start.is(KindOfArray)) { if (!length.is(KindOfArray)) { throw_invalid_argument("start and length should be of same type - " "numerical or array"); return str; } Array startArr = start.toArray(); Array lengthArr = length.toArray(); if (startArr.size() != lengthArr.size()) { throw_invalid_argument("start and length: (different item count)"); return str; } throw_invalid_argument("start and length as arrays not implemented"); return str; } return str.toString().replace(start.toInt32(), length.toInt32(), repl); } Array ret; Array strArr = str.toArray(); Array startArr = start.toArray(); Array lengthArr = length.toArray(); ArrayIter startIter(startArr); ArrayIter lengthIter(lengthArr); if (replacement.is(KindOfArray)) { Array replArr = replacement.toArray(); ArrayIter replIter(replArr); for (ArrayIter iter(strArr); iter; ++iter, ++startIter, ++lengthIter) { int nStart = startIter.second().toInt32(); int nLength = lengthIter.second().toInt32(); String repl(""); if (replIter) { repl = replIter.second().toString(); ++replIter; } ret.append(iter.second().toString().replace(nStart, nLength, repl)); } } else { String repl = replacement.toString(); for (ArrayIter iter(strArr); iter; ++iter, ++startIter, ++lengthIter) { int nStart = startIter.second().toInt32(); int nLength = lengthIter.second().toInt32(); ret.append(iter.second().toString().replace(nStart, nLength, repl)); } } return ret; }
bool f_is_callable(CVarRef v, bool syntax /* = false */, Variant name /* = null */) { if (v.isString()) { if (!name.isNull()) name = v; if (syntax) return true; string lowered = Util::toLower((const char *)v.toString()); size_t c = lowered.find("::"); if (c != 0 && c != string::npos && c+2 < lowered.size()) { string classname = lowered.substr(0, c); string methodname = lowered.substr(c+2); const ClassInfo *clsInfo = ClassInfo::FindClass(classname.c_str()); if (clsInfo && clsInfo->isDeclared()) { return clsInfo->hasMethod(methodname.c_str()); } return false; } return f_function_exists(v.toString()); } if (v.is(KindOfArray)) { Array arr = v.toArray(); if (arr.size() == 2 && arr.exists(0LL) && arr.exists(1LL)) { Variant v0 = arr.rvalAt(0LL); Variant v1 = arr.rvalAt(1LL); if (v0.is(KindOfObject)) { v0 = v0.toObject()->o_getClassName(); } if (v0.isString() && v1.isString()) { if (!name.isNull()) { name = v0.toString() + "::" + v1.toString(); } if (same(v0, "self") || same(v0, "parent")) { throw NotImplementedException("augmenting class scope info"); } const ClassInfo *clsInfo = ClassInfo::FindClass(v0.toString()); if (clsInfo && clsInfo->isDeclared()) { return clsInfo->hasMethod(v1.toString()); } return false; } } } if (!name.isNull()) { name = v.toString(); } return false; }
static Variant str_replace(CVarRef search, CVarRef replace, CVarRef subject, int &count, bool caseSensitive) { if (subject.is(KindOfArray)) { Array arr = subject.toArray(); Array ret; for (ArrayIter iter(arr); iter; ++iter) { String replaced = str_replace(search, replace, iter.second().toString(), count, caseSensitive); ret.set(iter.first(), replaced); } return ret; } return str_replace(search, replace, subject.toString(), count, caseSensitive); }
Variant list_assign(CVarRef data, ListAssignmentElement *elem, ...) { Array adata = data.toArray(); vector<ListAssignmentElement *> elems; va_list ap; va_start(ap, elem); while (elem) { elems.push_back(elem); elem = va_arg(ap, ListAssignmentElement *); } va_end(ap); for (int i = elems.size() - 1; i >= 0; i--) { elems[i]->assign(adata); delete elems[i]; } return data; }
bool StreamContext::validateOptions(CVarRef options) { if (options.isNull() || !options.isArray()) { return false; } CArrRef arr = options.toArray(); for (ArrayIter it(arr); it; ++it) { if (!it.first().isString() || !it.second().isArray()) { return false; } CArrRef opts = it.second().toArray(); for (ArrayIter it2(opts); it2; ++it2) { if (!it2.first().isString()) { return false; } } } return true; }
bool StreamContext::validateParams(CVarRef params) { if (params.isNull() || !params.isArray()) { return false; } CArrRef arr = params.toArray(); const String& options_key = String::FromCStr("options"); for (ArrayIter it(arr); it; ++it) { if (!it.first().isString()) { return false; } if (it.first().toString() == options_key) { if (!StreamContext::validateOptions(it.second())) { return false; } } } return true; }
Variant f_http_build_query(CVarRef formdata, CStrRef numeric_prefix /* = null_string */, CStrRef arg_separator /* = null_string */) { if (!formdata.is(KindOfArray) && !formdata.is(KindOfObject)) { throw_invalid_argument("formdata: (need Array or Object)"); return false; } String arg_sep; if (arg_separator.isNull()) { arg_sep = f_ini_get("arg_separator.output"); } else { arg_sep = arg_separator; } StringBuffer ret(1024); std::set<void*> seen_arrs; url_encode_array(ret, formdata.toArray(), seen_arrs, numeric_prefix, String(), String(), arg_sep); return String(ret); }
bool PDOSqliteConnection::preparer(const String& sql, sp_PDOStatement *stmt, CVarRef options) { if (options.toArray().exists(PDO_ATTR_CURSOR) && options[PDO_ATTR_CURSOR].toInt64() != PDO_CURSOR_FWDONLY) { m_einfo.errcode = SQLITE_ERROR; handleError(__FILE__, __LINE__); return false; } const char *tail; sqlite3_stmt *rawstmt = NULL; if (sqlite3_prepare(m_db, sql.data(), sql.size(), &rawstmt, &tail) == SQLITE_OK) { PDOSqliteStatement *s = new PDOSqliteStatement(m_db, rawstmt); *stmt = s; return true; } handleError(__FILE__, __LINE__); return false; }
Variant f_apc_fetch(CVarRef key, VRefParam success /* = null */, int64_t cache_id /* = 0 */) { if (!apcExtension::Enable) return false; if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) { throw_invalid_argument("cache_id: %" PRId64, cache_id); return false; } Variant v; if (key.is(KindOfArray)) { bool tmp = false; Array keys = key.toArray(); ArrayInit init(keys.size()); for (ArrayIter iter(keys); iter; ++iter) { Variant k = iter.second(); if (!k.isString()) { throw_invalid_argument("apc key: (not a string)"); return false; } String strKey = k.toString(); if (s_apc_store[cache_id].get(strKey, v)) { tmp = true; init.set(strKey, v, true); } } success = tmp; return init.create(); } if (s_apc_store[cache_id].get(key.toString(), v)) { success = true; } else { success = false; v = false; } return v; }
Variant f_apc_add(CVarRef key_or_array, CVarRef var /* = null_variant */, int64_t ttl /* = 0 */, int64_t cache_id /* = 0 */) { if (!apcExtension::Enable) return false; if (cache_id < 0 || cache_id >= MAX_SHARED_STORE) { throw_invalid_argument("cache_id: %" PRId64, cache_id); return false; } if (key_or_array.is(KindOfArray)) { Array valuesArr = key_or_array.toArray(); // errors stores all keys corresponding to entries that could not be cached ArrayInit errors(valuesArr.size()); for (ArrayIter iter(valuesArr); iter; ++iter) { Variant key = iter.first(); if (!key.isString()) { throw_invalid_argument("apc key: (not a string)"); return false; } Variant v = iter.second(); if (!(s_apc_store[cache_id].store(key.toString(), v, ttl, false))) errors.set(key); } return errors.create(); } if (!key_or_array.isString()) { throw_invalid_argument("apc key: (not a string)"); return false; } String strKey = key_or_array.toString(); return s_apc_store[cache_id].store(strKey, var, ttl, false); }
bool f_stream_context_set_option(CVarRef stream_or_context, CVarRef wrapper_or_options, CVarRef option /* = null_variant */, CVarRef value /* = null_variant */) { StreamContext* context = get_stream_context(stream_or_context); if (!context) { raise_warning("Invalid stream/context parameter"); return false; } if (wrapper_or_options.isArray() && !option.isInitialized() && !value.isInitialized()) { return f_stream_context_set_option0(context, wrapper_or_options.toArray()); } else if (wrapper_or_options.isString() && option.isInitialized() && option.isString() && value.isInitialized()) { return f_stream_context_set_option1(context, wrapper_or_options.toString(), option.toString(), value); } else { raise_warning("called with wrong number or type of parameters; please RTM"); return false; } }
bool TestMessageExchange::fromJson(CVarRef json) { if (json.isNull()) { printf("Not a valid JSON\n"); return false; } if (!json.isArray()) { printf("Invalid format of the message exchange\n"); return false; } for (ArrayIter it(json.toArray()); it; ++it) { if (!it.first().isInteger()) { printf("Invalid format of the message exchange\n"); return false; } int message_key = it.first().toInt32(); TestMessage message; if (!message.fromJson(it.second())) { printf("Invalid message #%d\n", message_key); return false; } m_messages.push_back(message); } return true; }
Array f_getopt(CStrRef options, CVarRef longopts /* = null_variant */) { opt_struct *opts, *orig_opts; int len = parse_opts(options.data(), options.size(), &opts); if (!longopts.isNull()) { Array arropts = longopts.toArray(); int count = arropts.size(); /* the first <len> slots are filled by the one short ops * we now extend our array and jump to the new added structs */ opts = (opt_struct *)realloc(opts, sizeof(opt_struct) * (len + count + 1)); orig_opts = opts; opts += len; memset(opts, 0, count * sizeof(opt_struct)); for (ArrayIter iter(arropts); iter; ++iter) { String entry = iter.second().toString(); opts->need_param = 0; opts->opt_name = strdup(entry.data()); len = strlen(opts->opt_name); if ((len > 0) && (opts->opt_name[len - 1] == ':')) { opts->need_param++; opts->opt_name[len - 1] = '\0'; if ((len > 1) && (opts->opt_name[len - 2] == ':')) { opts->need_param++; opts->opt_name[len - 2] = '\0'; } } opts->opt_char = 0; opts++; } } else { opts = (opt_struct*) realloc(opts, sizeof(opt_struct) * (len + 1)); orig_opts = opts; opts += len; } /* php_getopt want to identify the last param */ opts->opt_char = '-'; opts->need_param = 0; opts->opt_name = NULL; static const StaticString s_argv("argv"); GlobalVariables *g = get_global_variables(); Array vargv = g->get(s_argv).toArray(); int argc = vargv.size(); char **argv = (char **)malloc((argc+1) * sizeof(char*)); vector<String> holders; int index = 0; for (ArrayIter iter(vargv); iter; ++iter) { String arg = iter.second().toString(); holders.push_back(arg); argv[index++] = (char*)arg.data(); } argv[index] = NULL; Array ret = Array::Create(); /* after our pointer arithmetic jump back to the first element */ opts = orig_opts; int o; char *php_optarg = NULL; int php_optind = 1; Variant val; int optchr = 0; int dash = 0; /* have already seen the - */ char opt[2] = { '\0' }; char *optname; int optname_len = 0; int php_optidx; while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1, optchr, dash, php_optidx)) != -1) { /* Skip unknown arguments. */ if (o == '?') { continue; } /* Prepare the option character and the argument string. */ if (o == 0) { optname = opts[php_optidx].opt_name; } else { if (o == 1) { o = '-'; } opt[0] = o; optname = opt; } if (php_optarg != NULL) { /* keep the arg as binary, since the encoding is not known */ val = String(php_optarg, CopyString); } else { val = false; } /* Add this option / argument pair to the result hash. */ optname_len = strlen(optname); if (!(optname_len > 1 && optname[0] == '0') && is_numeric_string(optname, optname_len, NULL, NULL, 0) == KindOfInt64) { /* numeric string */ int optname_int = atoi(optname); if (ret.exists(optname_int)) { Variant &e = ret.lvalAt(optname_int); if (!e.isArray()) { ret.set(optname_int, CREATE_VECTOR2(e, val)); } else { e.append(val); } } else { ret.set(optname_int, val); } } else { /* other strings */ String key(optname, strlen(optname), CopyString); if (ret.exists(key)) { Variant &e = ret.lvalAt(key); if (!e.isArray()) { ret.set(key, CREATE_VECTOR2(e, val)); } else { e.append(val); } } else { ret.set(key, val); } } php_optarg = NULL; } free_longopts(orig_opts); free(orig_opts); free(argv); return ret; }
Variant c_DebuggerClient::t_processcmd(CVarRef cmdName, CVarRef args) { INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::processcmd); if (!m_client || m_client->getClientState() < DebuggerClient::StateReadyForCommand) { raise_warning("client is not initialized"); return null; } if (m_client->getClientState() != DebuggerClient::StateReadyForCommand) { raise_warning("client is not ready to take command"); return null; } if (!cmdName.isString()) { raise_warning("cmdName must be string"); return null; } if (!args.isNull() && !args.isArray()) { raise_warning("args must be null or array"); return null; } static const char *s_allowedCmds[] = { "break", "continue", "down", "exception", "frame", "global", "help", "info", "konstant", "next", "out", "print", "quit", "step", "up", "variable", "where", "bt", "set", "inst", "=", "@", NULL }; bool allowed = false; for (int i = 0; ; i++) { const char *cmd = s_allowedCmds[i]; if (cmd == NULL) { break; } if (cmdName.same(cmd)) { allowed = true; break; } } if (!allowed) { raise_warning("unsupported command %s", cmdName.toString().data()); return null; } m_client->setCommand(cmdName.toString().data()); StringVec *clientArgs = m_client->args(); clientArgs->clear(); if (!args.isNull()) { for (ArrayIter iter(args.toArray()); iter; ++iter) { CStrRef arg = iter.second().toString(); clientArgs->push_back(std::string(arg.data(), arg.size())); } } try { if (!m_client->process()) { raise_warning("command \"%s\" not found", cmdName.toString().data()); } } catch (DebuggerConsoleExitException &e) { // Flow-control command goes here Logger::Info("wait for debugger client to stop"); m_client->setTakingInterrupt(); m_client->setClientState(DebuggerClient::StateBusy); DebuggerCommandPtr cmd = m_client->waitForNextInterrupt(); if (!cmd) { raise_warning("not getting a command"); } else if (cmd->is(DebuggerCommand::KindOfInterrupt)) { CmdInterruptPtr cmdInterrupt = dynamic_pointer_cast<CmdInterrupt>(cmd); cmdInterrupt->onClientD(m_client); } else { // Previous pending commands cmd->handleReply(m_client); cmd->setClientOutput(m_client); } Logger::Info("debugger client ready for command"); } catch (DebuggerClientExitException &e) { const std::string& nameStr = m_client->getNameApi(); Logger::Info("client %s disconnected", nameStr.c_str()); s_dbgCltMap.erase(nameStr); delete m_client; m_client = NULL; return true; } catch (DebuggerProtocolException &e) { raise_warning("DebuggerProtocolException"); return null; } return m_client->getOutputArray(); }
bool setOption(long option, CVarRef value) { if (m_cp == NULL) { return false; } m_error_no = CURLE_OK; switch (option) { case CURLOPT_INFILESIZE: case CURLOPT_VERBOSE: case CURLOPT_HEADER: case CURLOPT_NOPROGRESS: case CURLOPT_NOBODY: case CURLOPT_FAILONERROR: case CURLOPT_UPLOAD: case CURLOPT_POST: case CURLOPT_FTPLISTONLY: case CURLOPT_FTPAPPEND: case CURLOPT_NETRC: case CURLOPT_PUT: case CURLOPT_TIMEOUT: #if LIBCURL_VERSION_NUM >= 0x071002 case CURLOPT_TIMEOUT_MS: #endif case CURLOPT_FTP_USE_EPSV: case CURLOPT_LOW_SPEED_LIMIT: case CURLOPT_SSLVERSION: case CURLOPT_LOW_SPEED_TIME: case CURLOPT_RESUME_FROM: case CURLOPT_TIMEVALUE: case CURLOPT_TIMECONDITION: case CURLOPT_TRANSFERTEXT: case CURLOPT_HTTPPROXYTUNNEL: case CURLOPT_FILETIME: case CURLOPT_MAXREDIRS: case CURLOPT_MAXCONNECTS: case CURLOPT_CLOSEPOLICY: case CURLOPT_FRESH_CONNECT: case CURLOPT_FORBID_REUSE: case CURLOPT_CONNECTTIMEOUT: #if LIBCURL_VERSION_NUM >= 0x071002 case CURLOPT_CONNECTTIMEOUT_MS: #endif case CURLOPT_SSL_VERIFYHOST: case CURLOPT_SSL_VERIFYPEER: //case CURLOPT_DNS_USE_GLOBAL_CACHE: not thread-safe when set to true case CURLOPT_NOSIGNAL: case CURLOPT_PROXYTYPE: case CURLOPT_BUFFERSIZE: case CURLOPT_HTTPGET: case CURLOPT_HTTP_VERSION: case CURLOPT_CRLF: case CURLOPT_DNS_CACHE_TIMEOUT: case CURLOPT_PROXYPORT: case CURLOPT_FTP_USE_EPRT: case CURLOPT_HTTPAUTH: case CURLOPT_PROXYAUTH: case CURLOPT_FTP_CREATE_MISSING_DIRS: case CURLOPT_FTPSSLAUTH: case CURLOPT_FTP_SSL: case CURLOPT_UNRESTRICTED_AUTH: case CURLOPT_PORT: case CURLOPT_AUTOREFERER: case CURLOPT_COOKIESESSION: case CURLOPT_TCP_NODELAY: case CURLOPT_IPRESOLVE: case CURLOPT_FOLLOWLOCATION: m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, value.toInt64()); break; case CURLOPT_RETURNTRANSFER: m_write.method = value.toBoolean() ? PHP_CURL_RETURN : PHP_CURL_STDOUT; break; case CURLOPT_BINARYTRANSFER: m_write.type = value.toBoolean() ? PHP_CURL_BINARY : PHP_CURL_ASCII; break; case CURLOPT_PRIVATE: case CURLOPT_URL: case CURLOPT_PROXY: case CURLOPT_USERPWD: case CURLOPT_PROXYUSERPWD: case CURLOPT_RANGE: case CURLOPT_CUSTOMREQUEST: case CURLOPT_USERAGENT: case CURLOPT_FTPPORT: case CURLOPT_COOKIE: case CURLOPT_REFERER: case CURLOPT_INTERFACE: case CURLOPT_KRB4LEVEL: case CURLOPT_EGDSOCKET: case CURLOPT_CAINFO: case CURLOPT_CAPATH: case CURLOPT_SSL_CIPHER_LIST: case CURLOPT_SSLKEY: case CURLOPT_SSLKEYTYPE: case CURLOPT_SSLKEYPASSWD: case CURLOPT_SSLENGINE: case CURLOPT_SSLENGINE_DEFAULT: case CURLOPT_SSLCERTTYPE: case CURLOPT_ENCODING: case CURLOPT_COOKIEJAR: case CURLOPT_SSLCERT: case CURLOPT_RANDOM_FILE: case CURLOPT_COOKIEFILE: { String svalue = value.toString(); #if LIBCURL_VERSION_NUM >= 0x071100 /* Strings passed to libcurl as 'char *' arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, svalue.c_str()); #else char *copystr = strndup(svalue.data(), svalue.size()); m_to_free->str.push_back(copystr); m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, copystr); #endif if (option == CURLOPT_URL) m_url = value; } break; case CURLOPT_FILE: case CURLOPT_INFILE: case CURLOPT_WRITEHEADER: case CURLOPT_STDERR: { if (!value.is(KindOfObject)) { return false; } Object obj = value.toObject(); if (obj.isNull() || obj.getTyped<File>(true) == NULL) { return false; } switch (option) { case CURLOPT_FILE: m_write.fp = obj; m_write.method = PHP_CURL_FILE; break; case CURLOPT_WRITEHEADER: m_write_header.fp = obj; m_write_header.method = PHP_CURL_FILE; break; case CURLOPT_INFILE: m_read.fp = obj; m_emptyPost = false; break; default: { if (obj.getTyped<PlainFile>(true) == NULL) { return false; } FILE *fp = obj.getTyped<PlainFile>()->getStream(); if (!fp) { return false; } m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, fp); break; } } } break; case CURLOPT_WRITEFUNCTION: m_write.callback = value; m_write.method = PHP_CURL_USER; break; case CURLOPT_READFUNCTION: m_read.callback = value; m_read.method = PHP_CURL_USER; m_emptyPost = false; break; case CURLOPT_HEADERFUNCTION: m_write_header.callback = value; m_write_header.method = PHP_CURL_USER; break; case CURLOPT_POSTFIELDS: m_emptyPost = false; if (value.is(KindOfArray) || value.is(KindOfObject)) { Array arr = value.toArray(); curl_httppost *first = NULL; curl_httppost *last = NULL; for (ArrayIter iter(arr); iter; ++iter) { String key = iter.first().toString(); String val = iter.second().toString(); const char *postval = val.data(); /* The arguments after _NAMELENGTH and _CONTENTSLENGTH * must be explicitly cast to long in curl_formadd * use since curl needs a long not an int. */ if (*postval == '@') { ++postval; m_error_no = (CURLcode)curl_formadd (&first, &last, CURLFORM_COPYNAME, key.data(), CURLFORM_NAMELENGTH, (long)key.size(), CURLFORM_FILE, postval, CURLFORM_END); } else { m_error_no = (CURLcode)curl_formadd (&first, &last, CURLFORM_COPYNAME, key.data(), CURLFORM_NAMELENGTH, (long)key.size(), CURLFORM_COPYCONTENTS, postval, CURLFORM_CONTENTSLENGTH,(long)val.size(), CURLFORM_END); } } if (m_error_no != CURLE_OK) { return false; } m_to_free->post.push_back(first); m_error_no = curl_easy_setopt(m_cp, CURLOPT_HTTPPOST, first); } else { String svalue = value.toString(); #if LIBCURL_VERSION_NUM >= 0x071100 /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */ m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE, svalue.size()); m_error_no = curl_easy_setopt(m_cp, CURLOPT_COPYPOSTFIELDS, svalue.c_str()); #else char *post = strndup(svalue.data(), svalue.size()); m_to_free->str.push_back(post); m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDS, post); m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE, svalue.size()); #endif } break; case CURLOPT_HTTPHEADER: case CURLOPT_QUOTE: case CURLOPT_HTTP200ALIASES: case CURLOPT_POSTQUOTE: if (value.is(KindOfArray) || value.is(KindOfObject)) { Array arr = value.toArray(); curl_slist *slist = NULL; for (ArrayIter iter(arr); iter; ++iter) { String key = iter.first().toString(); String val = iter.second().toString(); slist = curl_slist_append(slist, val.c_str()); if (!slist) { raise_warning("Could not build curl_slist"); return false; } } m_to_free->slist.push_back(slist); m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, slist); } else { raise_warning("You must pass either an object or an array with " "the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, " "CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE " "arguments"); return false; } break; case CURLINFO_HEADER_OUT: if (value.toInt64() == 1) { curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, curl_debug); curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, (void *)this); curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 1); } else { curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, NULL); curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, NULL); curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 0); } break; default: m_error_no = CURLE_FAILED_INIT; throw_invalid_argument("option: %d", option); break; } m_opts.set(int64(option), value); return m_error_no == CURLE_OK; }
Variant c_Memcache::t_get(CVarRef key, VRefParam flags /*= null*/) { if (key.is(KindOfArray)) { std::vector<const char *> real_keys; std::vector<size_t> key_len; Array keyArr = key.toArray(); real_keys.reserve(keyArr.size()); key_len.reserve(keyArr.size()); for (ArrayIter iter(keyArr); iter; ++iter) { real_keys.push_back(const_cast<char *>(iter.second().toString().c_str())); key_len.push_back(iter.second().toString().length()); } if (!real_keys.empty()) { const char *payload = NULL; size_t payload_len = 0; uint32_t flags = 0; const char *res_key = NULL; size_t res_key_len = 0; memcached_result_st result; memcached_return_t ret = memcached_mget(&m_memcache, &real_keys[0], &key_len[0], real_keys.size()); memcached_result_create(&m_memcache, &result); Array return_val; while ((memcached_fetch_result(&m_memcache, &result, &ret)) != NULL) { if (ret != MEMCACHED_SUCCESS) { // should probably notify about errors continue; } payload = memcached_result_value(&result); payload_len = memcached_result_length(&result); flags = memcached_result_flags(&result); res_key = memcached_result_key_value(&result); res_key_len = memcached_result_key_length(&result); return_val.set(String(res_key, res_key_len, CopyString), memcache_fetch_from_storage(payload, payload_len, flags)); } memcached_result_free(&result); return return_val; } } else { char *payload = NULL; size_t payload_len = 0; uint32_t flags = 0; memcached_return_t ret; String skey = key.toString(); if (skey.length() == 0) { return false; } payload = memcached_get(&m_memcache, skey.c_str(), skey.length(), &payload_len, &flags, &ret); /* This is for historical reasons from libmemcached*/ if (ret == MEMCACHED_END) { ret = MEMCACHED_NOTFOUND; } if (ret == MEMCACHED_NOTFOUND) { return false; } Variant retval = memcache_fetch_from_storage(payload, payload_len, flags); free(payload); return retval; } return false; }
Variant c_DebuggerClient::t_init(CVarRef options) { INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::init); if (!m_client) { raise_warning("invalid client"); return false; } if (m_client->getClientState() != DebuggerClient::StateUninit) { return m_client->getClientState() == DebuggerClient::StateReadyForCommand; } if (!options.isArray()) { raise_warning("options must be an array"); return false; } m_client->setClientState(DebuggerClient::StateInitializing); DebuggerClientOptions ops; ops.apiMode = true; Array opsArr = options.toArray(); if (opsArr.exists("user")) { ops.user = opsArr.rvalAtRef("user").toString().data(); } else { raise_warning("must specify user in options"); return false; } if (opsArr.exists("configFName")) { ops.configFName = opsArr.rvalAtRef("configFName").toString().data(); FILE *f = fopen(ops.configFName.c_str(), "r"); if (!f) { raise_warning("cannot access config file %s", ops.configFName.c_str()); return false; } fclose(f); } if (opsArr.exists("host")) { ops.host = opsArr.rvalAtRef("host").toString().data(); } if (opsArr.exists("port")) { ops.port = opsArr.rvalAtRef("port").toInt32(); } if (opsArr.exists("sandbox")) { ops.sandbox = opsArr.rvalAtRef("sandbox").toString().data(); } m_client->init(ops); if (ops.host.empty()) { ops.host = "localhost"; } if (ops.port < 0) { ops.port = RuntimeOption::DebuggerServerPort; } bool ret = m_client->connect(ops.host, ops.port); if (!ret) { raise_warning("failed to connect to hhvm %s:%d", ops.host.c_str(), ops.port); return false; } // To wait for the session start interrupt DebuggerCommandPtr cmd = m_client->waitForNextInterrupt(); if (!cmd->is(DebuggerCommand::KindOfInterrupt) || dynamic_pointer_cast<CmdInterrupt>(cmd)->getInterruptType() != SessionStarted) { raise_warning("failed to load sandbox"); return false; } ret = m_client->initializeMachine(); if (!ret) { raise_warning("failed to initialize machine info"); return false; } // To wait for the machine loading sandbox cmd = m_client->waitForNextInterrupt(); if (!cmd->is(DebuggerCommand::KindOfInterrupt) || dynamic_pointer_cast<CmdInterrupt>(cmd)->getInterruptType() != SessionStarted) { raise_warning("failed to load sandbox"); return false; } m_client->setClientState(DebuggerClient::StateReadyForCommand); return true; }