static int collator_numeric_compare_function(CVarRef v1, CVarRef v2, const void *data, bool ascending) { Variant num1; Variant num2; if (v1.isString()) { num1 = collator_convert_string_to_double(v1); } else { num1 = v1.toDouble(); } if (v2.isString()) { num2 = collator_convert_string_to_double(v2); } else { num2 = v2.toDouble(); } if (ascending) { if (num1.less(num2)) return -1; if (num1.equal(num2)) return 0; return 1; } if (num1.less(num2)) return 1; if (num1.equal(num2)) return 0; return -1; }
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); }
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); }
Object Certificate::Get(CVarRef var) { if (var.isResource()) { return var.toObject(); } if (var.isString() || var.isObject()) { bool file; BIO *in = ReadData(var, &file); if (in == nullptr) return Object(); X509 *cert; /* if (file) { cert = PEM_read_bio_X509(in, NULL, NULL, NULL); } else { cert = (X509 *)PEM_ASN1_read_bio ((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); } */ cert = PEM_read_bio_X509(in, nullptr, nullptr, nullptr); BIO_free(in); if (cert) { return Object(new Certificate(cert)); } } return Object(); }
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; }
bool ZendArray::exists(CVarRef k) const { TypedValueAccessor tva = k.getTypedAccessor(); if (isIntKey(tva)) return find(getIntKey(tva)); ASSERT(k.isString()); StringData *key = getStringKey(tva); return find(key->data(), key->size(), key->hash()); }
Variant f_property_exists(CVarRef class_or_object, const String& property) { if (class_or_object.isObject()) { const String& context = ctxClassName(); return (bool)class_or_object.toObject()->o_realProp( property, ObjectData::RealPropExist, context); } if (!class_or_object.isString()) { raise_warning( "First parameter must either be an object" " or the name of an existing class" ); return Variant(Variant::NullInit()); } Class* cls = Unit::lookupClass(get_classname(class_or_object).get()); if (!cls) { return false; } bool accessible; auto propInd = cls->getDeclPropIndex(cls, property.get(), accessible); if (propInd != kInvalidSlot) { return true; } propInd = cls->lookupSProp(property.get()); return (propInd != kInvalidSlot); }
Variant f_get_parent_class(CVarRef object /* = null_variant */) { if (!object.isInitialized()) { CallerFrame cf; Class* cls = arGetContextClass(cf()); if (cls && cls->parent()) { return String(cls->parentRef()); } return false; } Variant class_name; if (object.isObject()) { class_name = f_get_class(object); } else if (object.isString()) { class_name = object; } else { return false; } const Class* cls = Unit::lookupClass(class_name.toString().get()); if (cls) { auto& parentClass = *(const String*)(&cls->parentRef()); if (!parentClass.empty()) { return parentClass; } } return false; }
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; }
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 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; }
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; }
Variant f_get_parent_class(CVarRef object /* = null_variant */) { if (hhvm) { if (!object.isInitialized()) { CallerFrame cf; HPHP::VM::Class* cls = arGetContextClass(cf()); if (cls && cls->parent()) { return CStrRef(cls->parentRef()); } return false; } } Variant class_name; if (object.isObject()) { class_name = f_get_class(object); } else if (object.isString()) { class_name = object; } else { return false; } const ClassInfo *classInfo = ClassInfo::FindClass(class_name.toString()); if (classInfo) { CStrRef parentClass = classInfo->getParentClass(); if (!parentClass.empty()) { return parentClass; } } return false; }
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; }
Variant f_exit(CVarRef status /* = null_variant */) { if (status.isString()) { echo(status.toString()); throw ExitException(0); } throw ExitException(status.toInt32()); }
bool same(CVarRef v1, const StringData* v2) { bool null1 = v1.isNull(); bool null2 = (v2 == nullptr); if (null1 && null2) return true; if (null1 || null2) return false; if (!v1.isString()) return false; auto const sdata = v1.getStringData(); return sdata == v2 || v2->same(sdata); }
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; }
static void xml_set_handler(Variant * handler, CVarRef data) { if (same(data, false) || data.isString() || (data.isArray() && data.getArrayData()->size() == 2 && (data[0].isString() || data[0].isObject()) && data[1].isString())) { *handler = data; } else { raise_warning("Handler is invalid"); } }
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(); }
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); } }
string& SourceRootInfo::initPhpRoot() { GlobalVariables *g = get_global_variables(); CVarRef server = g->get(s_SERVER); CVarRef v = server.rvalAt(s_PHP_ROOT); if (v.isString()) { *s_phproot.getCheck() = string(v.asCStrRef().data()) + string("/"); } else { // Our best guess at the source root. *s_phproot.getCheck() = GetCurrentSourceRoot(); } return *s_phproot.getCheck(); }
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; }
int MapVariant::insertKey(CVarRef key, int64 prehash /* = -1 */) { int res; ASSERT(key.isInteger() || key.isString()); if (m_map.insert(key, m_elems.size(), res, prehash)) { if (m_keys) { m_keys->push_back(key); } if (key.isInteger()) { int64 index = key.toInt64(); if (index + 1 > m_nextIndex) m_nextIndex = index + 1; } } return res; }
static void collator_convert_array_from_utf16_to_utf8(Array &array, UErrorCode * status) { for (ArrayIter iter(array); iter; ++iter) { CVarRef value = iter.secondRef(); /* Process string values only. */ if (!value.isString()) continue; String str = intl_convert_str_utf16_to_utf8(value, status); if (U_FAILURE(*status)) { return; } /* Update current value with the converted value. */ const_cast<Variant&>(value) = str; } }
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; }
ssize_t ZendArray::getIndex(CVarRef k) const { Bucket *p; TypedValueAccessor tva = k.getTypedAccessor(); if (isIntKey(tva)) { p = find(getIntKey(tva)); } else { ASSERT(k.isString()); StringData *key = getStringKey(tva); p = find(key->data(), key->size(), key->hash()); } if (p) { return (ssize_t)p; } return ArrayData::invalid_index; }
void ZendArray::load(CVarRef k, Variant &v) const { Bucket *p; TypedValueAccessor tva = k.getTypedAccessor(); if (isIntKey(tva)) { p = find(getIntKey(tva)); } else { ASSERT(k.isString()); StringData *strkey = getStringKey(tva); int64 prehash = strkey->hash(); p = find(strkey->data(), strkey->size(), prehash); } if (p) { v.setWithRef(p->data); } }
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; } }
static Variant collator_normalize_sort_argument(CVarRef arg) { if (!arg.isString()) return arg; Variant n_arg = collator_convert_string_to_number_if_possible(arg); if (same(n_arg, false)) { /* Conversion to number failed. */ UErrorCode status; n_arg = intl_convert_str_utf16_to_utf8(arg, &status); if (U_FAILURE(status)) { raise_warning("Error converting utf16 to utf8 in " "collator_normalize_sort_argument()"); } } return n_arg; }
Variant f_strpos(CStrRef haystack, CVarRef needle, int offset /* = 0 */) { int pos; if (needle.isString()) { String n(needle.toString()); if (n.length() == 0) { raise_warning("Empty delimiter"); return false; } pos = haystack.find(n, offset); } else { pos = haystack.find(needle.toByte(), offset); } if (pos >= 0) return pos; return false; }