예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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);
}
예제 #6
0
int Array::SortLocaleStringDescending(CVarRef v1, CVarRef v2,
                                      const void *data) {
  String s1 = v1.toString();
  String s2 = v2.toString();

  return strcoll(s2.data(), s1.data());
}
예제 #7
0
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;
}
예제 #8
0
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);
}
예제 #9
0
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();
}
예제 #10
0
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);
  }
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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);
}
예제 #14
0
파일: ext_ipc.cpp 프로젝트: RdeWilde/hhvm
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;
}
예제 #15
0
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;
}
예제 #16
0
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;
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
파일: ext_apc.cpp 프로젝트: TSMG1972/hhvm
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());
}
예제 #20
0
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;
}
예제 #21
0
Variant f_exit(CVarRef status /* = null_variant */) {
  if (status.isString()) {
    echo(status.toString());
    throw ExitException(0);
  }
  throw ExitException(status.toInt32());
}
예제 #22
0
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;
}
예제 #23
0
파일: ext_pcre.cpp 프로젝트: RdeWilde/hhvm
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());
  }
}
예제 #24
0
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);
}
예제 #25
0
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;
}
예제 #26
0
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;
}
예제 #27
0
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();
}
예제 #28
0
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;
}
예제 #29
0
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);
  }
}
예제 #30
0
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());
  }
}