static Variant HHVM_METHOD(IntlDateFormatter, localtime, const String& value, VRefParam position) { DATFMT_GET(data, this_, uninit_null()); int32_t parse_pos = -1; if (!position.isNull()) { parse_pos = position.toInt64(); if (parse_pos > value.size()) { return false; } } UErrorCode error = U_ZERO_ERROR; String uValue(u16(value, error)); if (U_FAILURE(error)) { data->setError(error, "Error converting timezone to UTF-16"); return false; } error = U_ZERO_ERROR; UCalendar *cal = const_cast<UCalendar*>(udat_getCalendar(data->datefmt())); udat_parseCalendar(data->datefmt(), cal, (UChar*)uValue.c_str(), uValue.size() / sizeof(UChar), &parse_pos, &error); Array ret = Array::Create(); error = U_ZERO_ERROR; add_to_localtime_arr(ret, cal, UCAL_SECOND, s_tm_sec, error); add_to_localtime_arr(ret, cal, UCAL_MINUTE, s_tm_min, error); add_to_localtime_arr(ret, cal, UCAL_HOUR_OF_DAY, s_tm_hour, error); add_to_localtime_arr(ret, cal, UCAL_YEAR, s_tm_year, error, -1900); add_to_localtime_arr(ret, cal, UCAL_DAY_OF_MONTH, s_tm_mday, error); add_to_localtime_arr(ret, cal, UCAL_DAY_OF_WEEK, s_tm_wday, error, -1); add_to_localtime_arr(ret, cal, UCAL_DAY_OF_YEAR, s_tm_yday, error); add_to_localtime_arr(ret, cal, UCAL_MONTH, s_tm_mon, error); if (U_FAILURE(error)) { data->setError(error, "Date parsing - localtime failed : " "could not get a field from calendar"); return false; } error = U_ZERO_ERROR; auto isDST = ucal_inDaylightTime(cal, &error); if (U_FAILURE(error)) { data->setError(error, "Date parsing - localtime failed : " "while checking if currently in DST."); return false; } ret.set(s_tm_isdst, isDST ? 1 : 0); position = (int64_t)parse_pos; return ret; }
String HHVM_FUNCTION(pagelet_server_task_result, const Resource& task, VRefParam headers, VRefParam code, int64_t timeout_ms /* = 0 */) { Array rheaders; int rcode; String response = PageletServer::TaskResult(task, rheaders, rcode, timeout_ms); headers.assignIfRef(rheaders); code.assignIfRef(rcode); return response; }
static void walk_func(VRefParam value, CVarRef key, CVarRef userdata, const void *data) { CallCtx* ctx = (CallCtx*)data; Variant sink; TypedValue args[3] = { *value->asRef(), *key.asCell(), *userdata.asCell() }; g_vmContext->invokeFuncFew(sink.asTypedValue(), *ctx, 3, args); }
bool f_msg_send(CResRef queue, int64_t msgtype, CVarRef message, bool serialize /* = true */, bool blocking /* = true */, VRefParam errorcode /* = null */) { MessageQueue *q = queue.getTyped<MessageQueue>(); if (!q) { raise_warning("Invalid message queue was specified"); return false; } struct msgbuf *buffer = NULL; String data; if (serialize) { data = f_serialize(message); } else { data = message.toString(); } int len = data.length(); buffer = (struct msgbuf *)calloc(len + sizeof(struct msgbuf), 1); ScopedMem deleter(buffer); MSGBUF_MTYPE(buffer) = msgtype; memcpy(MSGBUF_MTEXT(buffer), data.c_str(), len + 1); int result = msgsnd(q->id, buffer, len, blocking ? 0 : IPC_NOWAIT); if (result < 0) { int err = errno; raise_warning("Unable to send message: %s", folly::errnoStr(err).c_str()); if (!errorcode.isNull()) { errorcode = err; } return false; } return true; }
String HHVM_FUNCTION(system, const String& command, VRefParam return_var /* = null */) { ShellExecContext ctx; FILE *fp = ctx.exec(command); if (!fp) return empty_string(); StringBuffer sbuf; if (fp) { sbuf.read(fp); } Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray(); int ret = ctx.exit(); if (WIFEXITED(ret)) ret = WEXITSTATUS(ret); return_var.assignIfRef(ret); int count = lines.size(); if (count > 0 && lines[count - 1].toString().empty()) { count--; // remove explode()'s last empty line } auto& ectx = *g_context; for (int i = 0; i < count; i++) { ectx.write(lines[i].toString()); ectx.write("\n"); } if (!count || lines.empty()) { return String(); } return HHVM_FN(rtrim)(lines[count - 1].toString()); }
static Variant HHVM_METHOD(NumberFormatter, parse, const String& value, int64_t type, VRefParam position) { NUMFMT_GET(obj, this_, false); UErrorCode error = U_ZERO_ERROR; icu::UnicodeString val(u16(value, error)); NUMFMT_CHECK(obj, error, false); Variant ret; int32_t pos = position.toInt64(); error = U_ZERO_ERROR; switch (type) { case UNUM(TYPE_INT32): ret = unum_parse(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; case UNUM(TYPE_INT64): ret = unum_parseInt64(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; case UNUM(TYPE_DOUBLE): ret = unum_parseDouble(obj->formatter(), val.getBuffer(), val.length(), &pos, &error); break; default: obj->setError(U_UNSUPPORTED_ERROR); return false; } NUMFMT_CHECK(obj, error, false); position = pos; return ret; }
static Variant HHVM_METHOD(IntlDateFormatter, parse, const String& value, VRefParam position) { DATFMT_GET(data, this_, 0); int32_t pos = position.toInt64(); if (pos > value.size()) { return false; } UErrorCode error = U_ZERO_ERROR; String str(u16(value, error)); if (U_FAILURE(error)) { data->setError(error, "Error converting timezone to UTF-16"); return false; } error = U_ZERO_ERROR; UDate timestamp = udat_parse(data->datefmt(), (UChar*)str.c_str(), str.size() / sizeof(UChar), &pos, &error); position = (int64_t)pos; if (U_FAILURE(error)) { data->setError(error, "Date parsing failed"); return false; } double result = (double)timestamp / U_MILLIS_PER_SECOND; if ((result > LONG_MAX) || (result < -LONG_MAX)) { return (double)((result > 0) ? ceil(result) : floor(result)); } else { return (int64_t)result; } }
void ArrayUtil::Walk(VRefParam input, PFUNC_WALK walk_function, const void *data, bool recursive /* = false */, PointerSet *seen /* = NULL */, CVarRef userdata /* = null_variant */) { assert(walk_function); Variant k; Variant v; for (MutableArrayIter iter = input->begin(&k, v); iter.advance(); ) { if (recursive && v.is(KindOfArray)) { assert(seen); ArrayData *arr = v.getArrayData(); if (v.isReferenced()) { if (seen->find((void*)arr) != seen->end()) { raise_warning("array_walk_recursive(): recursion detected"); return; } seen->insert((void*)arr); } Walk(directRef(v), walk_function, data, recursive, seen, userdata); if (v.isReferenced()) { seen->erase((void*)arr); } } else { walk_function(directRef(v), k, userdata, data); } } }
String HHVM_FUNCTION(exec, const String& command, VRefParam output /* = null */, VRefParam return_var /* = null */) { ShellExecContext ctx; FILE *fp = ctx.exec(command); if (!fp) return empty_string(); StringBuffer sbuf; sbuf.read(fp); Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray(); int ret = ctx.exit(); if (WIFEXITED(ret)) ret = WEXITSTATUS(ret); return_var = ret; int count = lines.size(); if (count > 0 && lines[count - 1].toString().empty()) { count--; // remove explode()'s last empty line } PackedArrayInit pai(count); for (int i = 0; i < count; i++) { pai.append(lines[i]); } output.wrapped() = pai.toArray(); if (!count || lines.empty()) { return String(); } return HHVM_FN(rtrim)(lines[count - 1].toString()); }
Variant HHVM_FUNCTION(preg_match, const String& pattern, const String& subject, VRefParam matches /* = null */, int flags /* = 0 */, int offset /* = 0 */) { return preg_match(pattern, subject, matches.getVariantOrNull(), flags, offset); }
Variant f_preg_match_all(CStrRef pattern, CStrRef subject, VRefParam matches, int flags /* = 0 */, int offset /* = 0 */) { if (matches.isReferenced()) { return preg_match_all(pattern, subject, matches, flags, offset); } else { return preg_match_all(pattern, subject, flags, offset); } }
bool f_shuffle(VRefParam array) { if (!array.isArray()) { throw_bad_array_exception(); return false; } array = ArrayUtil::Shuffle(array); return true; }
Variant HHVM_FUNCTION(preg_match, const String& pattern, const String& subject, VRefParam matches /* = null */, int flags /* = 0 */, int offset /* = 0 */) { if (matches.isReferenced()) { return preg_match(pattern, subject, matches, flags, offset); } else { return preg_match(pattern, subject, flags, offset); } }
bool f_msg_receive(CResRef queue, int64_t desiredmsgtype, VRefParam msgtype, int64_t maxsize, VRefParam message, bool unserialize /* = true */, int64_t flags /* = 0 */, VRefParam errorcode /* = null */) { MessageQueue *q = queue.getTyped<MessageQueue>(); if (!q) { raise_warning("Invalid message queue was specified"); return false; } if (maxsize <= 0) { raise_warning("Maximum size of the message has to be greater than zero"); return false; } int64_t realflags = 0; if (flags != 0) { #if !defined(__APPLE__) && !defined(__FreeBSD__) if (flags & k_MSG_EXCEPT) realflags |= MSG_EXCEPT; #endif if (flags & k_MSG_NOERROR) realflags |= MSG_NOERROR; if (flags & k_MSG_IPC_NOWAIT) realflags |= IPC_NOWAIT; } struct msgbuf *buffer = (struct msgbuf *)calloc(maxsize + sizeof(struct msgbuf), 1); ScopedMem deleter(buffer); int result = msgrcv(q->id, buffer, maxsize, desiredmsgtype, realflags); if (result < 0) { int err = errno; raise_warning("Unable to receive message: %s", folly::errnoStr(err).c_str()); if (!errorcode.isNull()) { errorcode = err; } return false; } msgtype = (int)MSGBUF_MTYPE(buffer); if (unserialize) { const char *bufText = (const char *)MSGBUF_MTEXT(buffer); uint bufLen = strlen(bufText); VariableUnserializer vu(bufText, bufLen, VariableUnserializer::Type::Serialize); try { message = vu.unserialize(); } catch (Exception &e) { raise_warning("Message corrupted"); return false; } } else { message = String((const char *)MSGBUF_MTEXT(buffer)); } return true; }
static void parse_str_impl(const String& str, VRefParam arr) { Array result = Array::Create(); HttpProtocol::DecodeParameters(result, str.data(), str.size()); if (!arr.isReferenced()) { HHVM_FN(SystemLib_extract)(result); return; } arr = result; }
int ZMQPollData::poll(int64_t timeout, VRefParam readable, VRefParam writable) { errors.clear(); auto rVar = readable.getVariantOrNull(); Array rArr; if (rVar && rVar->isArray()) { rArr = rVar->asArrRef(); rArr.clear(); } auto wVar = writable.getVariantOrNull(); Array wArr; if (wVar && wVar->isArray()) { wArr = wVar->asArrRef(); wArr.clear(); } assert(items.size() == php_items.size()); int rc = zmq_poll(items.data(), items.size(), timeout); if (rc == -1) { return -1; } if (rc > 0) { for (size_t i = 0; i < items.size(); i++) { if (rVar && (items[i].revents & ZMQ_POLLIN)) { rArr.append(php_items[i].entry); } if (wVar && (items[i].revents & ZMQ_POLLOUT)) { wArr.append(php_items[i].entry); } if (items[i].revents & ZMQ_POLLERR) { errors.append(php_items[i].key); } } } readable.assignIfRef(rArr); writable.assignIfRef(wArr); return rc; }
Variant c_Memcached::t_getbykey(CStrRef server_key, CStrRef key, CVarRef cache_cb /*= null_variant*/, VRefParam cas_token /*= null_variant*/) { INSTANCE_METHOD_INJECTION_BUILTIN(Memcached, Memcached::getbykey); m_impl->rescode = q_Memcached_RES_SUCCESS; if (key.empty()) { m_impl->rescode = q_Memcached_RES_BAD_KEY_PROVIDED; return false; } memcached_behavior_set(&m_impl->memcached, MEMCACHED_BEHAVIOR_SUPPORT_CAS, cas_token.isReferenced() ? 1 : 0); const char *myServerKey = server_key.empty() ? NULL : server_key.c_str(); size_t myServerKeyLen = server_key.length(); const char *myKey = key.c_str(); size_t myKeyLen = key.length(); memcached_return status = memcached_mget_by_key(&m_impl->memcached, myServerKey, myServerKeyLen, &myKey, &myKeyLen, 1); if (!handleError(status)) return false; Variant returnValue; MemcachedResultWrapper result(&m_impl->memcached); if (!memcached_fetch_result(&m_impl->memcached, &result.value, &status)) { if (status == MEMCACHED_END) status = MEMCACHED_NOTFOUND; if (status == MEMCACHED_NOTFOUND && !cache_cb.isNull()) { status = doCacheCallback(cache_cb, key, returnValue); if (!handleError(status)) return false; if (cas_token.isReferenced()) cas_token = 0.0; return returnValue; } handleError(status); return false; } if (!toObject(returnValue, result.value)) { m_impl->rescode = q_Memcached_RES_PAYLOAD_FAILURE; return false; } if (cas_token.isReferenced()) { cas_token = (double) memcached_result_cas(&result.value); } return returnValue; }
static void walk_func(VRefParam value, CVarRef key, CVarRef userdata, const void *data) { CallCtx* ctx = (CallCtx*)data; Variant sink; TypedValue args[3]; tvDup(*value->asTypedValue(), args[0]); tvDup(*key.asTypedValue(), args[1]); tvDup(*userdata.asTypedValue(), args[2]); g_vmContext->invokeFuncFew(sink.asTypedValue(), *ctx, 3, args); }
bool HHVM_FUNCTION(xbox_send_message, const String& msg, VRefParam retRef, int64_t timeout_ms, const String& host /* = "localhost" */) { Array ret; auto b = XboxServer::SendMessage(msg, ret, timeout_ms, host); retRef.assignIfRef(ret); return b; }
static Variant f_hphp_get_iterator(VRefParam iterable, bool isMutable) { if (iterable.isArray()) { if (isMutable) { return create_object(s_MutableArrayIterator, CREATE_VECTOR1(ref(iterable))); } return create_object(s_ArrayIterator, CREATE_VECTOR1(iterable)); } if (iterable.isObject()) { ObjectData *obj = iterable.getObjectData(); Variant iterator; while (obj->instanceof(SystemLib::s_IteratorAggregateClass)) { iterator = obj->o_invoke(s_getIterator, Array()); if (!iterator.isObject()) break; obj = iterator.getObjectData(); } VM::Class*ctx = g_vmContext->getContextClass(); CStrRef context = ctx ? ctx->nameRef() : empty_string; if (isMutable) { if (obj->instanceof(SystemLib::s_IteratorClass)) { throw FatalErrorException("An iterator cannot be used for " "iteration by reference"); } Array properties = obj->o_toIterArray(context, true); return create_object(s_MutableArrayIterator, CREATE_VECTOR1(ref(properties))); } else { if (obj->instanceof(SystemLib::s_IteratorClass)) { return obj; } return create_object(s_ArrayIterator, CREATE_VECTOR1(obj->o_toIterArray(context))); } } raise_warning("Invalid argument supplied for iteration"); if (isMutable) { return create_object(s_MutableArrayIterator, CREATE_VECTOR1(Array::Create())); } return create_object(s_ArrayIterator, CREATE_VECTOR1(Array::Create())); }
static Variant preg_replace_callback_array_impl( const Variant& patterns_and_callbacks, const Array& subjects, int limit, VRefParam count) { Array ret = Array::Create(); auto key = 0; auto total_replacement_count = 0; for (ArrayIter s_iter(subjects); s_iter; ++s_iter) { assert(s_iter.second().isString()); auto subj = s_iter.second(); for (ArrayIter pc_iter(patterns_and_callbacks.toArray()); pc_iter; ++pc_iter) { Variant pattern(pc_iter.first()); assert(pattern.isString()); Variant callback(pc_iter.second()); subj = HHVM_FN(preg_replace_callback)(pattern, callback, subj, limit, count); // If we got an error on the replacement, the subject will be null, // and then we will return null. if (subj.isNull()) { return init_null(); } if (count.isReferenced()) { total_replacement_count += count.toInt64(); } } ret.add(key++, subj); } // If count was passed in as an explicit reference, we will assign it to our // total replacement count; otherwise, count will just remained unassigned count.assignIfRef(total_replacement_count); // If there were no replacements (i.e., matches) return original subject(s) if (ret.empty()) { return subjects; } return ret; }
int64_t HHVM_FUNCTION(pcntl_wait, VRefParam status, int options /* = 0 */) { int nstatus = status; auto const child_id = LightProcess::pcntl_waitpid(-1, &nstatus, options); /* if (options) { child_id = wait3(&nstatus, options, NULL); } else { child_id = wait(&nstatus); }*/ status.assignIfRef(nstatus); return child_id; }
int64_t HHVM_FUNCTION(pcntl_waitpid, int pid, VRefParam status, int options /* = 0 */) { int nstatus = status; auto const child_id = LightProcess::pcntl_waitpid( (pid_t)pid, &nstatus, options ); status.assignIfRef(nstatus); return child_id; }
int64_t f_array_unshift(int _argc, VRefParam array, CVarRef var, CArrRef _argv /* = null_array */) { if (array.toArray()->isVectorData()) { if (!_argv.empty()) { for (ssize_t pos = _argv->iter_end(); pos != ArrayData::invalid_index; pos = _argv->iter_rewind(pos)) { array.prepend(_argv->getValueRef(pos)); } } array.prepend(var); } else { { Array newArray; newArray.append(var); if (!_argv.empty()) { for (ssize_t pos = _argv->iter_begin(); pos != ArrayData::invalid_index; pos = _argv->iter_advance(pos)) { newArray.append(_argv->getValueRef(pos)); } } for (ArrayIter iter(array); iter; ++iter) { Variant key(iter.first()); CVarRef value(iter.secondRef()); if (key.isInteger()) { newArray.appendWithRef(value); } else { newArray.lvalAt(key, AccessFlags::Key).setWithRef(value); } } array = newArray; } // Reset the array's internal pointer if (array.is(KindOfArray)) { f_reset(array); } } return array.toArray().size(); }
ALWAYS_INLINE static int64_t extract_impl(VRefParam vref_array, int extract_type /* = EXTR_OVERWRITE */, const String& prefix /* = "" */) { bool reference = extract_type & EXTR_REFS; extract_type &= ~EXTR_REFS; if (!vref_array.wrapped().isArray()) { raise_warning("extract() expects parameter 1 to be array"); return 0; } VMRegAnchor _; auto const varEnv = g_context->getVarEnv(); if (!varEnv) return 0; if (UNLIKELY(reference)) { auto& arr = vref_array.wrapped().toArrRef(); int count = 0; for (ArrayIter iter(arr); iter; ++iter) { String name = iter.first(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; g_context->bindVar(name.get(), arr.lvalAt(name).asTypedValue()); ++count; } return count; } auto const var_array = vref_array.wrapped().toArray(); int count = 0; for (ArrayIter iter(var_array); iter; ++iter) { String name = iter.first(); if (!modify_extract_name(varEnv, name, extract_type, prefix)) continue; g_context->setVar(name.get(), iter.secondRef().asTypedValue()); ++count; } return count; }
Variant HHVM_FUNCTION(preg_replace_callback, const Variant& pattern, const Variant& callback, const Variant& subject, int limit /* = -1 */, VRefParam count /* = null */) { if (!is_callable(callback)) { raise_warning("Not a valid callback function %s", callback.toString().data()); return empty_string_variant(); } return preg_replace_impl(pattern, callback, subject, limit, count.getVariantOrNull(), true, false); }
Object c_SetResultToRefWaitHandle::ti_create(CObjRef wait_handle, VRefParam ref) { TypedValue* var_or_cell = ref->asTypedValue(); if (wait_handle.isNull()) { tvSetNull(*var_or_cell); return wait_handle; } if (!wait_handle.get()->getAttribute(ObjectData::IsWaitHandle)) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected wait_handle to be an instance of WaitHandle or null")); throw e; } auto wh = static_cast<c_WaitHandle*>(wait_handle.get()); // succeeded? set result to ref and give back succeeded wait handle if (wh->isSucceeded()) { tvSet(wh->getResult(), *var_or_cell); return wh; } // failed? reset ref and give back failed wait handle if (wh->isFailed()) { tvSetNull(*var_or_cell); return wh; } // it's still running so it must be WaitableWaitHandle auto child = static_cast<c_WaitableWaitHandle*>(wh); // import child into the current context, detect cross-context cycles auto session = AsioSession::Get(); if (session->isInContext()) { child->enterContext(session->getCurrentContextIdx()); } // make sure the reference is properly boxed so that we can store cell pointer if (UNLIKELY(var_or_cell->m_type != KindOfRef)) { tvBox(var_or_cell); } p_SetResultToRefWaitHandle my_wh = NEWOBJ(c_SetResultToRefWaitHandle)(); my_wh->initialize(child, var_or_cell->m_data.pref); if (UNLIKELY(session->hasOnSetResultToRefCreateCallback())) { session->onSetResultToRefCreate(my_wh.get(), child); } return my_wh; }
static bool HHVM_METHOD(Collator, sort, VRefParam arr, int64_t sort_flag /* = Collator::SORT_REGULAR */) { FETCH_COL(data, this_, false); if (!arr.isArray()) { throw_expected_array_exception(); return false; } data->clearError(); bool ret = collator_sort(arr, sort_flag, true, data->collator(), data); if (U_FAILURE(data->getErrorCode())) { return false; } return ret; }
static bool HHVM_STATIC_METHOD(EventUtil, getSocketName, const Resource &socket, VRefParam address, VRefParam port){ evutil_socket_t fd = resource_to_fd(socket); struct sockaddr sa; socklen_t sa_len = sizeof(struct sockaddr); long l_port = 0; if (getsockname(fd, &sa, &sa_len)) { raise_warning("Unable to retreive socket name."); return false; } switch (sa.sa_family) { case AF_INET: { struct sockaddr_in *sa_in = (struct sockaddr_in *) &sa; char c_addr[INET_ADDRSTRLEN + 1]; if (evutil_inet_ntop(sa.sa_family, &sa_in->sin_addr, c_addr, sizeof(c_addr))) { address = StringData::Make(c_addr, CopyString); l_port = ntohs(sa_in->sin_port); } } break; #ifdef AF_INET6 case AF_INET6: { struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) &sa; char c_addr6[INET6_ADDRSTRLEN + 1]; if (evutil_inet_ntop(sa.sa_family, &sa_in6->sin6_addr, c_addr6, sizeof(c_addr6))) { address = StringData::Make(c_addr6, CopyString); l_port = ntohs(sa_in6->sin6_port); } break; } #endif #ifdef HAVE_SYS_UN_H case AF_UNIX: { struct sockaddr_un *ua = (struct sockaddr_un *) &sa; address = StringData::Make(ua->sun_path, CopyString); break; } #endif default: raise_warning("Unsupported address family."); return false; } if(port.isReferenced()){ port = l_port; } return true; }
bool f_array_walk(VRefParam input, CVarRef funcname, CVarRef userdata /* = null_variant */) { if (!input.isArray()) { throw_bad_array_exception(); return false; } CallCtx ctx; CallerFrame cf; vm_decode_function(funcname, cf(), false, ctx); if (ctx.func == NULL) { return false; } ArrayUtil::Walk(input, walk_func, &ctx, false, NULL, userdata); return true; }