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 ArrayUtil::Range(double low, double high, int64_t step /* = 1 */) { Array ret; if (low > high) { // Negative steps if (low - high < step || step <= 0) { throw_invalid_argument("step exceeds the specified range"); return false; } rangeCheckAlloc((low - high) / step); for (; low >= high; low -= step) { ret.append((int64_t)low); } } else if (high > low) { // Positive steps if (high - low < step || step <= 0) { throw_invalid_argument("step exceeds the specified range"); return false; } rangeCheckAlloc((high - low) / step); for (; low <= high; low += step) { ret.append((int64_t)low); } } else { ret.append((int64_t)low); } return ret; }
Variant f_stream_get_contents(const Resource& handle, int maxlen /* = -1 */, int offset /* = -1 */) { if (maxlen < -1) { throw_invalid_argument("maxlen: %d", maxlen); return false; } if (maxlen == 0) { return init_null(); } File *file = handle.getTyped<File>(false /* nullOkay */, true /* badTypeOkay */); if (!file) { throw_invalid_argument( "stream_get_contents() expects parameter 1 to be a resource"); return false; } if (offset >= 0 && !file->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %d in the stream", offset); return false; } String ret; if (maxlen != -1) { if (maxlen < 0) { return false; } ret = file->read(maxlen); } else { ret = file->read(); } return ret; }
bool validate_dns_arguments(const String& host, const String& type, int& ntype) { IOStatusHelper io("dns_check_record", host.data()); const char *stype; if (type.empty()) { stype = "MX"; } else { stype = type.data(); } if (host.empty()) { throw_invalid_argument("host: [empty]"); } if (!strcasecmp("A", stype)) ntype = DNS_T_A; else if (!strcasecmp("NS", stype)) ntype = DNS_T_NS; else if (!strcasecmp("MX", stype)) ntype = DNS_T_MX; else if (!strcasecmp("PTR", stype)) ntype = DNS_T_PTR; else if (!strcasecmp("ANY", stype)) ntype = DNS_T_ANY; else if (!strcasecmp("SOA", stype)) ntype = DNS_T_SOA; else if (!strcasecmp("TXT", stype)) ntype = DNS_T_TXT; else if (!strcasecmp("CNAME", stype)) ntype = DNS_T_CNAME; else if (!strcasecmp("AAAA", stype)) ntype = DNS_T_AAAA; else if (!strcasecmp("SRV", stype)) ntype = DNS_T_SRV; else if (!strcasecmp("NAPTR", stype)) ntype = DNS_T_NAPTR; else if (!strcasecmp("A6", stype)) ntype = DNS_T_A6; else { throw_invalid_argument("type: %s", stype); return false; } return true; }
Variant f_substr_count(CStrRef haystack, CStrRef needle, int offset /* = 0 */, int length /* = 0x7FFFFFFF */) { int lenNeedle = needle.size(); if (lenNeedle == 0) { throw_invalid_argument("needle: (empty)"); return false; } if (offset < 0 || offset > haystack.size()) { throw_invalid_argument("offset: (out of range)"); return false; } if (length == 0x7FFFFFFF) { length = haystack.size() - offset; } else if (length <= 0 || length > haystack.size() - offset) { throw_invalid_argument("length: (out of range)"); return false; } int count = 0; int posMax = offset + length - lenNeedle; for (int pos = haystack.find(needle, offset); pos != -1 && pos <= posMax; pos = haystack.find(needle, pos + lenNeedle)) { ++count; } return count; }
Variant ArrayUtil::Range(double low, double high, double step /* = 1.0 */) { Array ret; double element; int64_t i; if (low > high) { // Negative steps if (low - high < step || step <= 0) { throw_invalid_argument("step exceeds the specified range"); return false; } rangeCheckAlloc((low - high) / step); for (i = 0, element = low; element >= (high - DOUBLE_DRIFT_FIX); i++, element = low - (i * step)) { ret.append(element); } } else if (high > low) { // Positive steps if (high - low < step || step <= 0) { throw_invalid_argument("step exceeds the specified range"); return false; } rangeCheckAlloc((high - low) / step); for (i = 0, element = low; element <= (high + DOUBLE_DRIFT_FIX); i++, element = low + (i * step)) { ret.append(element); } } else { ret.append(low); } 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()); }
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_base_convert(CStrRef number, int64_t frombase, int64_t tobase) { if (!string_validate_base(frombase)) { throw_invalid_argument("Invalid frombase: %d", frombase); return false; } if (!string_validate_base(tobase)) { throw_invalid_argument("Invalid tobase: %d", tobase); return false; } Variant v = string_base_to_numeric(number.data(), number.size(), frombase); return String(string_numeric_to_base(v, tobase), AttachString); }
Variant f_stream_get_contents(CObjRef handle, int maxlen /* = 0 */, int offset /* = 0 */) { if (maxlen < 0) { throw_invalid_argument("maxlen: %d", maxlen); return false; } File *file = handle.getTyped<File>(); if (offset > 0 && !file->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %d in the stream", offset); return false; } String ret; if (maxlen) { char *buf = (char *)malloc(maxlen + 1); maxlen = file->readImpl(buf, maxlen); if (maxlen < 0) { free(buf); return false; } buf[maxlen] = '\0'; ret = String(buf, maxlen, AttachString); } else { StringBuffer sb; sb.read(file); ret = sb.detach(); } return ret; }
Variant ArrayUtil::Range(unsigned char low, unsigned char high, int64_t step /* = 1 */) { if (step <= 0) { throw_invalid_argument("step exceeds the specified range"); return false; } Array ret; if (low > high) { // Negative Steps for (; low >= high; low -= (unsigned int)step) { ret.append(String::FromChar(low)); if (((signed int)low - step) < 0) { break; } } } else if (high > low) { // Positive Steps for (; low <= high; low += (unsigned int)step) { ret.append(String::FromChar(low)); if (((signed int)low + step) > 255) { break; } } } else { ret.append(String::FromChar(low)); } return ret; }
Variant f_stream_copy_to_stream(const Resource& source, const Resource& dest, int maxlength /* = -1 */, int offset /* = 0 */) { if (maxlength == 0) return 0; if (maxlength == PHP_STREAM_COPY_ALL) maxlength = 0; File *srcFile = source.getTyped<File>(); File *destFile = dest.getTyped<File>(); if (maxlength < 0) { throw_invalid_argument("maxlength: %d", maxlength); return false; } if (offset > 0 && !srcFile->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %d in the stream", offset); return false; } int cbytes = 0; if (maxlength == 0) maxlength = INT_MAX; while (cbytes < maxlength) { int remaining = maxlength - cbytes; String buf = srcFile->read(std::min(remaining, File::CHUNK_SIZE)); if (buf.size() == 0) break; if (destFile->write(buf) != buf.size()) { return false; } cbytes += buf.size(); } return cbytes; }
Variant f_stream_copy_to_stream(CObjRef source, CObjRef dest, int maxlength /* = -1 */, int offset /* = 0 */) { if (maxlength == 0) return 0; if (maxlength == PHP_STREAM_COPY_ALL) maxlength = 0; File *srcFile = source.getTyped<File>(); File *destFile = dest.getTyped<File>(); if (maxlength < 0) { throw_invalid_argument("maxlength: %d", maxlength); return false; } if (offset > 0 && !srcFile->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %ld in the stream", offset); return false; } int cbytes = 0; if (maxlength == 0) maxlength = INT_MAX; while (cbytes < maxlength) { char buf[8193]; int remaining = maxlength - cbytes; int toread = ((remaining >= (int)sizeof(buf)) ? sizeof(buf) - 1 : remaining); int rbytes = srcFile->readImpl(buf, toread); if (rbytes == 0) break; if (rbytes < 0) return false; buf[rbytes] = '\0'; if (destFile->write(String(buf, rbytes, AttachLiteral)) != rbytes) { return false; } cbytes += rbytes; } return cbytes; }
void StringData::append(const char *s, int len) { if (len == 0) return; if (len < 0 || (len & IsMask)) { throw_invalid_argument("len: %d", len); } if (!isMalloced()) { int newlen; m_data = string_concat(data(), size(), s, len, newlen); if (isShared()) { m_shared->decRef(); } m_len = newlen; } else if (m_data == s) { int newlen; char *newdata = string_concat(data(), size(), s, len, newlen); releaseData(); m_data = newdata; m_len = newlen; } else { int dataLen = size(); ASSERT((m_data > s && m_data - s > len) || (m_data < s && s - m_data > dataLen)); // no overlapping m_len = len + dataLen; m_data = (const char*)realloc((void*)m_data, m_len + 1); memcpy((void*)(m_data + dataLen), s, len); ((char*)m_data)[m_len] = '\0'; } }
Variant ArrayUtil::Chunk(CArrRef input, int size, bool preserve_keys /* = false */) { if (size < 1) { throw_invalid_argument("size: %d", size); return uninit_null(); } Array ret = Array::Create(); Array chunk; int current = 0; for (ArrayIter iter(input); iter; ++iter) { if (preserve_keys) { chunk.addLval(iter.first(), true).setWithRef(iter.secondRef()); } else { chunk.appendWithRef(iter.secondRef()); } if ((++current % size) == 0) { ret.append(chunk); chunk.clear(); } } if (!chunk.empty()) { ret.append(chunk); } return ret; }
bool HHVM_FUNCTION(time_sleep_until, double timestamp) { struct timeval tm; if (gettimeofday((struct timeval *)&tm, NULL) != 0) { return false; } double c_ts = (double)(timestamp - tm.tv_sec - tm.tv_usec / 1000000.0); if (c_ts < 0) { throw_invalid_argument ("timestamp: Sleep until to time is less than current time"); return false; } struct timespec req, rem; req.tv_sec = (time_t)c_ts; req.tv_nsec = (long)((c_ts - req.tv_sec) * 1000000000.0); IOStatusHelper io("nanosleep"); while (nanosleep(&req, &rem)) { recordNanosleepTime(req, &rem); if (errno != EINTR) return false; req.tv_sec = rem.tv_sec; req.tv_nsec = rem.tv_nsec; } recordNanosleepTime(req, nullptr); return true; }
Variant HHVM_FUNCTION(base_convert, const Variant& number, int64_t frombase, int64_t tobase) { if (!string_validate_base(frombase)) { throw_invalid_argument("Invalid frombase: %" PRId64, frombase); return false; } if (!string_validate_base(tobase)) { throw_invalid_argument("Invalid tobase: %" PRId64, tobase); return false; } String str = number.toString(); Variant v = string_base_to_numeric(str.data(), str.size(), frombase); return string_numeric_to_base(v, tobase); }
static Variant HHVM_FUNCTION(assert_options, int64_t what, const Variant& value /*=null */) { if (what == k_ASSERT_ACTIVE) { int oldValue = s_option_data->assertActive; if (!value.isNull()) s_option_data->assertActive = value.toInt64(); return oldValue; } if (what == k_ASSERT_WARNING) { int oldValue = s_option_data->assertWarning; if (!value.isNull()) s_option_data->assertWarning = value.toInt64(); return oldValue; } if (what == k_ASSERT_BAIL) { int oldValue = s_option_data->assertBail; if (!value.isNull()) s_option_data->assertBail = value.toInt64(); return oldValue; } if (what == k_ASSERT_CALLBACK) { Variant oldValue = s_option_data->assertCallback; if (!value.isNull()) s_option_data->assertCallback = value; return oldValue; } if (what == k_ASSERT_QUIET_EVAL) { bool oldValue = s_option_data->assertQuietEval; if (!value.isNull()) s_option_data->assertQuietEval = value.toBoolean(); return Variant(oldValue); } if (what == k_ASSERT_EXCEPTION) { int oldValue = s_option_data->assertException; if (!value.isNull()) s_option_data->assertException = value.toBoolean(); return Variant(oldValue); } throw_invalid_argument("assert option %ld is not supported", (long)what); return false; }
USING device_array_group::device_array_group(const device_array_pool_ptr& pool) : _pool(pool) { if (!_pool) throw_invalid_argument("Pool is null."); }
Variant f_stream_get_contents(CObjRef handle, int maxlen /* = 0 */, int offset /* = 0 */) { if (maxlen < 0) { throw_invalid_argument("maxlen: %d", maxlen); return false; } File *file = handle.getTyped<File>(); if (offset > 0 && !file->seek(offset, SEEK_SET) ) { raise_warning("Failed to seek to position %d in the stream", offset); return false; } String ret; if (maxlen) { ret = String(maxlen, ReserveString); char *buf = ret.mutableSlice().ptr; maxlen = file->readImpl(buf, maxlen); if (maxlen < 0) { return false; } ret.setSize(maxlen); } else { StringBuffer sb; sb.read(file); ret = sb.detach(); } return ret; }
Variant ArrayUtil::Combine(CArrRef keys, CArrRef values) { if (keys.size() != values.size()) { throw_invalid_argument("keys and values not same count"); return false; } if (keys.empty()) { throw_invalid_argument("keys and values empty"); return false; } Array ret = Array::Create(); for (ArrayIter iter1(keys), iter2(values); iter1; ++iter1, ++iter2) { CVarRef v(iter2.secondRef()); ret.lvalAt(iter1.secondRef()).setWithRef(v); } return ret; }
Variant f_idate(CStrRef format, int64_t timestamp /* = TimeStamp::Current() */) { if (format.size() != 1) { throw_invalid_argument("format: %s", format.data()); return false; } int64_t ret = DateTime(timestamp, false).toInteger(*format.data()); if (ret == -1) return false; return ret; }
static Variant idateImpl(const String& format, int64_t timestamp) { if (format.size() != 1) { throw_invalid_argument("format: %s", format.data()); return false; } int64_t ret = DateTime(timestamp, false).toInteger(*format.data()); if (ret == -1) return false; return ret; }
static Variant HHVM_FUNCTION(idate, const String& fmt, int64_t timestamp) { if (fmt.size() != 1) { throw_invalid_argument("format: %s", fmt.data()); return false; } int64_t ret = req::make<DateTime>(timestamp, false)->toInteger(*fmt.data()); if (ret == -1) return false; return ret; }
bool f_apc_clear_cache(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; } return s_apc_store[cache_id].clear(); }
bool Array::MultiSort(std::vector<SortData> &data, bool renumber) { ASSERT(!data.empty()); int count = -1; for (unsigned int k = 0; k < data.size(); k++) { SortData &opaque = data[k]; ASSERT(opaque.array); ASSERT(opaque.cmp_func); int size = opaque.array->size(); if (count == -1) { count = size; } else if (count != size) { throw_invalid_argument("arrays: (inconsistent sizes)"); return false; } opaque.positions.reserve(size); CArrRef arr = *opaque.array; if (!arr.empty()) { for (ssize_t pos = arr->iter_begin(); pos != ArrayData::invalid_index; pos = arr->iter_advance(pos)) { opaque.positions.push_back(pos); } } } if (count == 0) { return true; } int *indices = (int *)malloc(sizeof(int) * count); for (int i = 0; i < count; i++) { indices[i] = i; } zend_qsort(indices, count, sizeof(int), multi_compare_func, (void *)&data); for (unsigned int k = 0; k < data.size(); k++) { SortData &opaque = data[k]; CArrRef arr = *opaque.array; Array sorted; for (int i = 0; i < count; i++) { ssize_t pos = opaque.positions[indices[i]]; Variant k(arr->getKey(pos)); if (renumber && k.isInteger()) { sorted.append(arr->getValueRef(pos)); } else { sorted.set(k, arr->getValueRef(pos)); } } *opaque.original = sorted; } free(indices); return true; }
static Variant HHVM_FUNCTION(mysql_async_fetch_array, const Resource& result, int result_type /* = 1 */) { if ((result_type & PHP_MYSQL_BOTH) == 0) { throw_invalid_argument("result_type: %d", result_type); return false; } auto res = php_mysql_extract_result(result); if (!res) { return false; } MYSQL_RES* mysql_result = res->get(); if (!mysql_result) { raise_warning("invalid parameter to mysql_async_fetch_array"); return false; } MYSQL_ROW mysql_row = nullptr; int status = mysql_fetch_row_nonblocking(mysql_result, &mysql_row); // Last row, or no row yet available. if (status != NET_ASYNC_COMPLETE) { return false; } if (mysql_row == nullptr) { res->close(); return false; } unsigned long *mysql_row_lengths = mysql_fetch_lengths(mysql_result); if (!mysql_row_lengths) { return false; } mysql_field_seek(mysql_result, 0); Array ret; MYSQL_FIELD *mysql_field; int i; for (mysql_field = mysql_fetch_field(mysql_result), i = 0; mysql_field; mysql_field = mysql_fetch_field(mysql_result), i++) { Variant data; if (mysql_row[i]) { data = mysql_makevalue(String(mysql_row[i], mysql_row_lengths[i], CopyString), mysql_field); } if (result_type & PHP_MYSQL_NUM) { ret.set(i, data); } if (result_type & PHP_MYSQL_ASSOC) { ret.set(String(mysql_field->name, CopyString), data); } } return ret; }
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(); }
bool f_apc_cas(const String& key, int64_t old_cas, int64_t new_cas, 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; } return s_apc_store[cache_id].cas(key, old_cas, new_cas); }
Variant HHVM_FUNCTION(time_nanosleep, int seconds, int nanoseconds) { if (seconds < 0) { throw_invalid_argument("seconds: cannot be negative"); return false; } if (nanoseconds < 0 || nanoseconds > 999999999) { throw_invalid_argument("nanoseconds: has to be 0 to 999999999"); return false; } struct timespec req, rem; req.tv_sec = (time_t)seconds; req.tv_nsec = nanoseconds; IOStatusHelper io("nanosleep"); if (!nanosleep(&req, &rem)) { recordNanosleepTime(req, nullptr); return true; } recordNanosleepTime(req, &rem); if (errno == EINTR) { return make_map_array(s_seconds, (int64_t)rem.tv_sec, s_nanoseconds, (int64_t)rem.tv_nsec); } return false; }