bool f_xml_parser_set_option(CObjRef parser, int option, CVarRef value) { XmlParser * p = parser.getTyped<XmlParser>(); switch (option) { case PHP_XML_OPTION_CASE_FOLDING: p->case_folding = value.toInt64(); break; case PHP_XML_OPTION_SKIP_TAGSTART: p->toffset = value.toInt64(); break; case PHP_XML_OPTION_SKIP_WHITE: p->skipwhite = value.toInt64(); break; case PHP_XML_OPTION_TARGET_ENCODING: { xml_encoding *enc; enc = xml_get_encoding((const XML_Char*)value.toString().data()); if (enc == NULL) { raise_warning("Unsupported target encoding \"%s\"", value.toString().data()); return false; } p->target_encoding = enc->name; break; } default: raise_warning("Unknown option"); return false; } return true; }
static Variant xml_call_handler(XmlParser *parser, CVarRef handler, CArrRef args) { if (parser && handler) { Variant retval; if (handler.isString()) { if (!parser->object.isObject()) { retval = invoke(handler.toString().c_str(), args, -1); } else { retval = parser->object.toObject()-> o_invoke(handler.toString(), args, -1); } } else if (handler.isArray() && handler.getArrayData()->size() == 2 && (handler[0].isString() || handler[0].isObject()) && handler[1].isString()) { if (handler[0].isString()) { // static method retval = ObjectData::os_invoke(handler[0].toString(), handler[1].toString(), args, -1); } else { // instance method retval = handler[0].toObject()->o_invoke(handler[1].toString(), args, -1); } } else { raise_warning("Handler is invalid"); } return retval; } return null; }
bool VectorString::setImpl(int index, CVarRef v, bool copy, ArrayData *&ret) { bool keepVector = false; if (index >= 0) { keepVector = true; } if (!v.isString()) { if (keepVector) { ret = NEW(VectorVariant)(this, index, v); return true; } return false; } if (!keepVector) { return false; } if (copy) { ret = NEW(VectorString)(this, index, v.toString()); return true; } if ((ssize_t)index < size()) { ASSERT(index >= 0); m_elems[index] = v.toString(); } else { ASSERT((ssize_t)index == size()); m_elems.push_back(v.toString()); } ret = NULL; return true; }
static bool ctype(CVarRef v, int (*iswhat)(int)) { if (v.isInteger()) { int64_t n = v.toInt64(); if (n <= 255 && n >= 0) { return iswhat(n); } if (n >= -128 && n < 0) { return iswhat(n + 256); } return ctype(v.toString(), iswhat); } if (v.isString()) { String s = v.toString(); if (!s.empty()) { const char *p = s.data(); const char *e = s.data() + s.size(); while (p < e) { if (!iswhat((int)*(unsigned char *)(p++))) { return false; } } return true; } } return false; }
static int collator_string_compare_function(CVarRef v1, CVarRef v2, const void *data, bool ascending) { assert(data); String str1; if (v1.isString()) { str1 = v1.toString(); } else { UErrorCode status; str1 = intl_convert_str_utf8_to_utf16(v1.toString(), &status); if (U_FAILURE(status)) { raise_warning("Error converting utf8 to utf16 in " "collator_string_compare_function()"); } } String str2; if (v2.isString()) { str2 = v2.toString(); } else { UErrorCode status; str2 = intl_convert_str_utf8_to_utf16(v2.toString(), &status); if (U_FAILURE(status)) { raise_warning("Error converting utf8 to utf16 in " "collator_string_compare_function()"); } } int ret = ucol_strcoll((const UCollator *)data, (UChar*)(str1.data()), UCHARS(str1.length()), (UChar*)(str2.data()), UCHARS(str2.length())); return ascending ? ret : (-ret); }
int Array::SortLocaleStringDescending(CVarRef v1, CVarRef v2, const void *data) { String s1 = v1.toString(); String s2 = v2.toString(); return strcoll(s2.data(), s1.data()); }
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; }
Variant f_range(CVarRef low, CVarRef high, CVarRef step /* = 1 */) { bool is_step_double = false; double dstep = 1.0; if (step.isDouble()) { dstep = step.toDouble(); is_step_double = true; } else if (step.isString()) { int64_t sn; double sd; DataType stype = step.toString()->isNumericWithVal(sn, sd, 0); if (stype == KindOfDouble) { is_step_double = true; dstep = sd; } else if (stype == KindOfInt64) { dstep = (double)sn; } else { dstep = step.toDouble(); } } else { dstep = step.toDouble(); } /* We only want positive step values. */ if (dstep < 0.0) dstep *= -1; if (low.isString() && high.isString()) { String slow = low.toString(); String shigh = high.toString(); if (slow.size() >= 1 && shigh.size() >=1) { int64_t n1, n2; double d1, d2; DataType type1 = slow->isNumericWithVal(n1, d1, 0); DataType type2 = shigh->isNumericWithVal(n2, d2, 0); if (type1 == KindOfDouble || type2 == KindOfDouble || is_step_double) { if (type1 != KindOfDouble) d1 = slow.toDouble(); if (type2 != KindOfDouble) d2 = shigh.toDouble(); return ArrayUtil::Range(d1, d2, dstep); } int64_t lstep = (int64_t) dstep; if (type1 == KindOfInt64 || type2 == KindOfInt64) { if (type1 != KindOfInt64) n1 = slow.toInt64(); if (type2 != KindOfInt64) n2 = shigh.toInt64(); return ArrayUtil::Range((double)n1, (double)n2, lstep); } return ArrayUtil::Range((unsigned char)slow.charAt(0), (unsigned char)shigh.charAt(0), lstep); } } if (low.is(KindOfDouble) || high.is(KindOfDouble) || is_step_double) { return ArrayUtil::Range(low.toDouble(), high.toDouble(), dstep); } int64_t lstep = (int64_t) dstep; return ArrayUtil::Range(low.toDouble(), high.toDouble(), lstep); }
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(); }
String static memcache_prepare_for_storage(CVarRef var, int &flag) { if (var.isString()) { return var.toString(); } else if (var.isNumeric() || var.isBoolean()) { return var.toString(); } else { flag |= MMC_SERIALIZED; return f_serialize(var); } }
static Variant collator_convert_string_to_number_if_possible(CVarRef str) { int64_t lval = 0; double dval = 0; if (!str.isString()) return false; DataType ret = collator_is_numeric((UChar*)(str.toString().data()), UCHARS(str.toString().length()), &lval, &dval, 1); if (ret == KindOfInt64) return lval; if (ret == KindOfDouble) return dval; return false; }
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; }
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 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; }
Variant f_class_implements(CVarRef obj, bool autoload /* = true */) { String clsname; if (obj.isString()) { clsname = obj.toString(); } else if (obj.isObject()) { clsname = obj.toObject()->o_getClassName(); } else { return false; } const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname); if (info == NULL) { if (!autoload) return false; AutoloadHandler::s_instance->invokeHandler(clsname); return f_class_implements(clsname, false); } Array ret(Array::Create()); ClassInfo::InterfaceVec ifs; info->getAllInterfacesVec(ifs); for (unsigned int i = 0; i < ifs.size(); i++) { ret.set(ifs[i], ifs[i]); } return ret; }
Variant f_setlocale(int _argc, int category, CVarRef locale, CArrRef _argv /* = null_array */) { Array argv = _argv; if (locale.is(KindOfArray)) { if (!argv.empty()) throw_invalid_argument("locale: not string)"); argv = locale; // ignore _argv } for (int i = -1; i < argv.size(); i++) { String slocale; if (i == -1) { if (locale.is(KindOfArray)) continue; slocale = locale.toString(); } else { slocale = argv[i].toString(); } const char *loc = slocale; if (slocale.size() >= 255) { throw_invalid_argument("locale name is too long: %s", loc); return false; } if (strcmp("0", loc) == 0) { loc = NULL; } { Lock lock(s_mutex); const char *retval = setlocale(category, loc); if (retval) { return String(retval, CopyString); } } } return false; }
Variant f_class_uses(CVarRef obj, bool autoload /* = true */) { String clsname; if (obj.isString()) { clsname = obj.toString(); } else if (obj.isObject()) { clsname = obj.toObject()->o_getClassName(); } else { return false; } const ClassInfo *info = ClassInfo::FindClassInterfaceOrTrait(clsname); if (!info) { if (!autoload) return false; AutoloadHandler::s_instance->invokeHandler(clsname); return f_class_uses(clsname, false); } Array ret(Array::Create()); const ClassInfo::TraitVec &traits = info->getTraitsVec(); for (unsigned int i = 0; i < traits.size(); i++) { ret.set(traits[i], traits[i]); } return ret; }
bool f_pcntl_signal(int signo, CVarRef handler, bool restart_syscalls /* = true */) { /* Special long value case for SIG_DFL and SIG_IGN */ if (handler.isInteger()) { int64_t handle = handler.toInt64(); if (handle != (long)SIG_DFL && handle != (long)SIG_IGN) { raise_warning("Invalid value for handle argument specified"); } if (php_signal(signo, (Sigfunc *)handle, restart_syscalls) == SIG_ERR) { raise_warning("Error assigning signal"); return false; } return true; } if (!f_is_callable(handler)) { raise_warning("%s is not a callable function name error", handler.toString().data()); return false; } s_signal_handlers->handlers.set(signo, handler); if (php_signal(signo, pcntl_signal_handler, restart_syscalls) == SIG_ERR) { raise_warning("Error assigning signal"); return false; } return true; }
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()); }
Array f_hphp_get_method_info(CVarRef cls, CVarRef name) { const Class* c = get_cls(cls); if (!c) return Array(); if (c->clsInfo()) { /* * Default arguments for builtins arent setup correctly, * so use the ClassInfo instead. */ return get_method_info(c->clsInfo(), name); } CStrRef method_name = name.toString(); const Func* func = c->lookupMethod(method_name.get()); if (!func) { if (c->attrs() & AttrAbstract) { const Class::InterfaceMap& ifaces = c->allInterfaces(); for (int i = 0, size = ifaces.size(); i < size; i++) { func = ifaces[i]->lookupMethod(method_name.get()); if (func) break; } } if (!func) return Array(); } Array ret; set_method_info(ret, func); return ret; }
Variant f_exit(CVarRef status /* = null_variant */) { if (status.isString()) { echo(status.toString()); throw ExitException(0); } throw ExitException(status.toInt32()); }
Variant f_bzopen(CVarRef filename, CStrRef mode) { if (mode != "r" && mode != "w") { raise_warning( "'%s' is not a valid mode for bzopen(). " "Only 'w' and 'r' are supported.", mode.data() ); return false; } BZ2File *bz; if (filename.isString()) { if (filename.asCStrRef().empty()) { raise_warning("filename cannot be empty"); return false; } bz = NEWOBJ(BZ2File)(); bool ret = bz->open(File::TranslatePath(filename.toString()), mode); if (!ret) { raise_warning("%s", Util::safe_strerror(errno).c_str()); return false; } } else { if (!filename.isResource()) { raise_warning("first parameter has to be string or file-resource"); return false; } PlainFile* f = filename.cast<PlainFile>(); if (!f) { return false; } std::string stream_mode = f->getMode(); int stream_mode_len = stream_mode.length(); if (stream_mode_len != 1 && !(stream_mode_len == 2 && stream_mode.find('b') != string::npos)) { raise_warning("cannot use stream opened in mode '%s'", stream_mode.c_str()); return false; } else if (stream_mode_len == 1 && stream_mode[0] != 'r' && stream_mode[0] != 'w' && stream_mode[0] != 'a' && stream_mode[0] != 'x') { raise_warning("cannot use stream opened in mode '%s'", stream_mode.c_str()); return false; } const char rw_mode = stream_mode[0]; if (mode == "r" && rw_mode != 'r') { raise_warning("cannot write to a stream opened in read only mode"); return false; } else if (mode == "w" && rw_mode != 'w' && rw_mode != 'a' && rw_mode != 'x') { raise_warning("cannot read from a stream opened in write only mode"); return false; } bz = NEWOBJ(BZ2File)(f); } Object handle(bz); return handle; }
String HHVM_FUNCTION(preg_quote, const String& str, CVarRef delimiter /* = null_string */) { if (delimiter.isNull()) { return preg_quote(str, null_string); } else { return preg_quote(str, delimiter.toString()); } }
ssize_t GlobalArrayWrapper::getIndex(CVarRef k, int64 prehash /* = -1*/) const { if (k.isInteger()) { return ((Array*)m_globals)->get()->getIndex(k.toInt64(), prehash) + m_globals->size(); } return m_globals->getIndex(k.toString().data(), prehash); }
Variant SharedMap::get(CVarRef k, int64 prehash /* = -1 */, bool error /* = false */) const { SharedVariant *sv = m_arr->get(k); if (sv) return getLocal(sv); if (error) { raise_notice("Undefined index: %s", k.toString().data()); } return null; }
Variant f_strripos(CStrRef haystack, CVarRef needle, int offset /* = 0 */) { int pos; if (needle.isString()) { pos = haystack.rfind(needle.toString(), offset, false); } else { pos = haystack.rfind(needle.toByte(), offset, false); } if (pos >= 0) return pos; return false; }
Variant f_assert(CVarRef assertion) { if (!s_option_data->assertActive) return true; Transl::CallerFrame cf; Offset callerOffset; auto const fp = cf(&callerOffset); auto const passed = [&]() -> bool { if (assertion.isString()) { if (RuntimeOption::RepoAuthoritative) { // We could support this with compile-time string literals, // but it's not yet implemented. throw NotSupportedException(__func__, "assert with strings argument in RepoAuthoritative mode"); } return eval_for_assert(fp, assertion.toString()).toBoolean(); } return assertion.toBoolean(); }(); if (passed) return true; if (!s_option_data->assertCallback.isNull()) { auto const unit = fp->m_func->unit(); VectorInit ai(3); ai.add(String(unit->filepath())); ai.add(Variant(unit->getLineNumber(callerOffset))); ai.add(assertion.isString() ? assertion.toString() : String("")); f_call_user_func(1, s_option_data->assertCallback, ai.toArray()); } if (s_option_data->assertWarning) { auto const str = !assertion.isString() ? String("Assertion failed") : concat3("Assertion \"", assertion.toString(), "\" failed"); raise_warning("%s", str.data()); } if (s_option_data->assertBail) { throw Assertion(); } return uninit_null(); }
CVarRef VectorArray::get(CVarRef k, bool error /* = false */) const { Variant::TypedValueAccessor tva = k.getTypedAccessor(); if (isIntKey(tva)) { return VectorArray::get(getIntKey(tva), error); } if (error) { raise_notice("Undefined index: %s", k.toString().data()); } return null_variant; }
Variant invoke_failed(CVarRef func, CArrRef params, bool fatal /* = true */) { if (func.isObject()) { return o_invoke_failed( func.objectForCall()->o_getClassName().c_str(), "__invoke", fatal); } else { return invoke_failed(func.toString().c_str(), params, fatal); } }
void StringBuffer::append(CVarRef v) { Variant::TypedValueAccessor tva = v.getTypedAccessor(); if (Variant::IsString(tva)) { append(Variant::GetAsString(tva)); } else if (IS_INT_TYPE(Variant::GetAccessorType(tva))) { append(Variant::GetInt64(tva)); } else { append(v.toString()); } }