Example #1
0
static void php_array_replace_recursive(PointerSet &seen, bool check,
                                        Array &arr1, CArrRef arr2) {
  if (check) {
    if (seen.find((void*)arr1.get()) != seen.end()) {
      raise_warning("array_replace_recursive(): recursion detected");
      return;
    }
    seen.insert((void*)arr1.get());
  }

  for (ArrayIter iter(arr2); iter; ++iter) {
    Variant key = iter.first();
    CVarRef value = iter.secondRef();
    if (arr1.exists(key, true) && value.isArray()) {
      Variant &v = arr1.lvalAt(key, AccessFlags::Key);
      if (v.isArray()) {
        Array subarr1 = v.toArray();
        const ArrNR& arr_value = value.toArrNR();
        php_array_replace_recursive(seen, v.isReferenced(), subarr1,
                                    arr_value);
        v = subarr1;
      } else {
        arr1.set(key, value, true);
      }
    } else {
      arr1.lvalAt(key, AccessFlags::Key).setWithRef(value);
    }
  }

  if (check) {
    seen.erase((void*)arr1.get());
  }
}
Example #2
0
static void php_array_merge_recursive(PointerSet &seen, bool check,
                                      Array &arr1, CArrRef arr2) {
  if (check) {
    if (seen.find((void*)arr1.get()) != seen.end()) {
      raise_warning("array_merge_recursive(): recursion detected");
      return;
    }
    seen.insert((void*)arr1.get());
  }

  for (ArrayIter iter(arr2); iter; ++iter) {
    Variant key(iter.first());
    CVarRef value(iter.secondRef());
    if (key.isNumeric()) {
      arr1.appendWithRef(value);
    } else if (arr1.exists(key, true)) {
      // There is no need to do toKey() conversion, for a key that is already
      // in the array.
      Variant &v = arr1.lvalAt(key, AccessFlags::Key);
      Array subarr1(v.toArray()->copy());
      php_array_merge_recursive(seen, v.isReferenced(), subarr1,
                                value.toArray());
      v.unset(); // avoid contamination of the value that was strongly bound
      v = subarr1;
    } else {
      arr1.lvalAt(key, AccessFlags::Key).setWithRef(value);
    }
  }

  if (check) {
    seen.erase((void*)arr1.get());
  }
}
Example #3
0
static void php_array_replace(Array &arr1, CArrRef arr2) {
  for (ArrayIter iter(arr2); iter; ++iter) {
    Variant key = iter.first();
    CVarRef value = iter.secondRef();
    arr1.lvalAt(key, AccessFlags::Key).setWithRef(value);
  }
}
Example #4
0
Array TimeZone::GetAbbreviations() {
  Array ret;
  for (const timelib_tz_lookup_table *entry =
         timelib_timezone_abbreviations_list(); entry->name; entry++) {
    ArrayInit element(3);
    element.set(s_dst, (bool)entry->type);
    element.set(s_offset, entry->gmtoffset);
    if (entry->full_tz_name) {
      element.set(s_timezone_id, String(entry->full_tz_name, CopyString));
    } else {
      element.set(s_timezone_id, uninit_null());
    }
    ret.lvalAt(String(entry->name)).append(element.create());
  }
  return ret;
}
Example #5
0
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;
}
Example #6
0
Array TimeZone::GetAbbreviations() {
  Array ret;
  for (const timelib_tz_lookup_table *entry =
         timelib_timezone_abbreviations_list(); entry->name; entry++) {
    Array element;
    element.set("dst", (bool)entry->type);
    element.set("offset", entry->gmtoffset);
    if (entry->full_tz_name) {
      element.set("timezone_id", String(entry->full_tz_name, AttachLiteral));
    } else {
      element.set("timezone_id", null);
    }

    ret.lvalAt(entry->name).append(element);
  }
  return ret;
}
Example #7
0
Array f_hphp_get_closure_info(CVarRef closure) {
  Array mi = f_hphp_get_method_info(closure.toObject()->o_getClassName(),
                                    s___invoke);
  mi.set(s_name, s_closure_in_braces);
  mi.set(s_closureobj, closure);
  mi.set(s_closure, empty_string);
  mi.remove(s_access);
  mi.remove(s_modifiers);
  mi.remove(s_class);

  Array &params = mi.lvalAt(s_params).asArrRef();
  for (int i = 0; i < params.size(); i++) {
    params.lvalAt(i).asArrRef().remove(s_class);
  }

  return mi;
}
Example #8
0
void RequestEvalState::GetMethodStaticVariables(Array &arr) {
  RequestEvalState *self = s_res.get();
  String prefix("sv_");
  for (map<const FunctionStatement*, LVariableTable>::iterator it =
      self->m_functionStatics.begin(); it != self->m_functionStatics.end();
      ++it) {
    String fprefix = prefix;
    fprefix += it->first->name().c_str();
    fprefix += "$$";
    Array vars(it->second.getDefinedVars());
    for (ArrayIter vit(vars); !vit.end(); vit.next()) {
      String key(fprefix);
      key += vit.first();
      arr.set(key, vit.second());
    }
  }

  for (map<const MethodStatement*, map<string, LVariableTable> >::
      iterator it = self->m_methodStatics.begin();
      it != self->m_methodStatics.end(); ++it) {
    String mprefix(prefix);
    mprefix += it->first->getClass()->name().c_str();
    mprefix += "$$";
    mprefix += it->first->name().c_str();
    mprefix += "$$";
    Variant val;
    if (it->second.size() > 1) {
      for (map<string, LVariableTable>::iterator cit =
          it->second.begin(); cit != it->second.end(); ++cit) {
        Array vars(cit->second.getDefinedVars());
        for (ArrayIter vit(vars); !vit.end(); vit.next()) {
          arr.lvalAt(mprefix + vit.first()).set(cit->first.c_str(),
              vit.second());
        }
      }
    } else {
      Array vars(it->second.begin()->second.getDefinedVars());
      for (ArrayIter vit(vars); !vit.end(); vit.next()) {
        arr.set(mprefix + vit.first(), vit.second());
      }
    }
  }
}
Example #9
0
Variant f_array_combine(CVarRef keys, CVarRef values) {
  const auto& cell_keys = *keys.asCell();
  const auto& cell_values = *values.asCell();
  if (UNLIKELY(!isContainer(cell_keys) || !isContainer(cell_values))) {
    raise_warning("Invalid operand type was used: array_combine expects "
                  "arrays or collections");
    return uninit_null();
  }
  if (UNLIKELY(getContainerSize(cell_keys) != getContainerSize(cell_values))) {
    raise_warning("array_combine(): Both parameters should have an equal "
                  "number of elements");
    return false;
  }
  Array ret = ArrayData::Create();
  for (ArrayIter iter1(cell_keys), iter2(cell_values);
       iter1; ++iter1, ++iter2) {
    ret.lvalAt(iter1.secondRefPlus()).setWithRef(iter2.secondRefPlus());
  }
  return ret;
}
void EvalObjectData::o_getArray(Array &props, bool pubOnly /* = false */)
const {
    if (!pubOnly) {
        String zero("\0", 1, AttachLiteral);
        for (ArrayIter it(m_privates); !it.end(); it.next()) {
            String prefix(zero);
            prefix += it.first();
            prefix += zero;
            for (ArrayIter it2(it.second()); !it2.end(); it2.next()) {
                CVarRef v = it2.secondRef();
                if (v.isInitialized()) {
                    props.lvalAt(prefix + it2.first()).setWithRef(v);
                }
            }
        }
    }
    DynamicObjectData::o_getArray(props, pubOnly);
    if (pubOnly) {
        const ClassInfo *info = ClassInfo::FindClass(o_getClassName());
        info->filterProperties(props, ClassInfo::IsProtected);
    }
}
void FiberReferenceMap::unmarshalDynamicGlobals
(Array &dest, CArrRef src, char default_strategy,
 const hphp_string_map<char> &additional_strategies) {
  for (ArrayIter iter(src); iter; ++iter) {
    String key = iter.first().toString();
    CVarRef val = iter.secondRef();
    String fullKey = String("gv_") + key;

    FiberAsyncFunc::Strategy strategy =
      (FiberAsyncFunc::Strategy)default_strategy;
    hphp_string_map<char>::const_iterator it =
      additional_strategies.find(fullKey.data());
    if (it != additional_strategies.end()) {
      strategy = (FiberAsyncFunc::Strategy)it->second;
    }

    if (strategy != FiberAsyncFunc::GlobalStateIgnore) {
      Variant &dval = dest.lvalAt(key.fiberCopy());
      unmarshal(dval, val, strategy);
    }
  }
}
Example #12
0
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)) {
      array.array_iter_reset();
    }
  }
  return array.toArray().size();
}
Example #13
0
static Array HHVM_FUNCTION(getopt, const String& options,
                                   const Variant& longopts /*=null */) {
  opt_struct *opts, *orig_opts;
  int len = parse_opts(options.data(), options.size(), &opts);

  if (!longopts.isNull()) {
    Array arropts = longopts.toArray();
    int count = arropts.size();

    /* the first <len> slots are filled by the one short ops
     * we now extend our array and jump to the new added structs */
    opts = (opt_struct *)smart_realloc(
      opts, sizeof(opt_struct) * (len + count + 1));
    orig_opts = opts;
    opts += len;

    memset(opts, 0, count * sizeof(opt_struct));

    for (ArrayIter iter(arropts); iter; ++iter) {
      String entry = iter.second().toString();

      opts->need_param = 0;
      opts->opt_name = strdup(entry.data());
      len = strlen(opts->opt_name);
      if ((len > 0) && (opts->opt_name[len - 1] == ':')) {
        opts->need_param++;
        opts->opt_name[len - 1] = '\0';
        if ((len > 1) && (opts->opt_name[len - 2] == ':')) {
          opts->need_param++;
          opts->opt_name[len - 2] = '\0';
        }
      }
      opts->opt_char = 0;
      opts++;
    }
  } else {
    opts = (opt_struct*) smart_realloc(opts, sizeof(opt_struct) * (len + 1));
    orig_opts = opts;
    opts += len;
  }

  /* php_getopt want to identify the last param */
  opts->opt_char   = '-';
  opts->need_param = 0;
  opts->opt_name   = NULL;

  static const StaticString s_argv("argv");
  Array vargv = php_global(s_argv).toArray();
  int argc = vargv.size();
  char **argv = (char **)smart_malloc((argc+1) * sizeof(char*));
  std::vector<String> holders;
  int index = 0;
  for (ArrayIter iter(vargv); iter; ++iter) {
    String arg = iter.second().toString();
    holders.push_back(arg);
    argv[index++] = (char*)arg.data();
  }
  argv[index] = NULL;

  /* after our pointer arithmetic jump back to the first element */
  opts = orig_opts;

  int o;
  char *php_optarg = NULL;
  int php_optind = 1;

  SCOPE_EXIT {
    free_longopts(orig_opts);
    smart_free(orig_opts);
    smart_free(argv);
  };

  Array ret = Array::Create();

  Variant val;
  int optchr = 0;
  int dash = 0; /* have already seen the - */
  char opt[2] = { '\0' };
  char *optname;
  int optname_len = 0;
  int php_optidx;
  while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1,
                         optchr, dash, php_optidx))
         != -1) {
    /* Skip unknown arguments. */
    if (o == '?') {
      continue;
    }

    /* Prepare the option character and the argument string. */
    if (o == 0) {
      optname = opts[php_optidx].opt_name;
    } else {
      if (o == 1) {
        o = '-';
      }
      opt[0] = o;
      optname = opt;
    }

    if (php_optarg != NULL) {
      /* keep the arg as binary, since the encoding is not known */
      val = String(php_optarg, CopyString);
    } else {
      val = false;
    }

    /* Add this option / argument pair to the result hash. */
    optname_len = strlen(optname);
    if (!(optname_len > 1 && optname[0] == '0') &&
        is_numeric_string(optname, optname_len, NULL, NULL, 0) ==
        KindOfInt64) {
      /* numeric string */
      int optname_int = atoi(optname);
      if (ret.exists(optname_int)) {
        Variant &e = ret.lvalAt(optname_int);
        if (!e.isArray()) {
          ret.set(optname_int, make_packed_array(e, val));
        } else {
          e.toArrRef().append(val);
        }
      } else {
        ret.set(optname_int, val);
      }
    } else {
      /* other strings */
      String key(optname, strlen(optname), CopyString);
      if (ret.exists(key)) {
        Variant &e = ret.lvalAt(key);
        if (!e.isArray()) {
          ret.set(key, make_packed_array(e, val));
        } else {
          e.toArrRef().append(val);
        }
      } else {
        ret.set(key, val);
      }
    }

    php_optarg = NULL;
  }

  return ret;
}
Example #14
0
void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Char **attributes) {
  XmlParser *parser = (XmlParser *)userData;
  const char **attrs = (const char **) attributes;
  Variant retval;
  Array args = Array::Create();

  if (parser) {
    parser->level++;

    char* tag_name = _xml_decode_tag(parser, (const char*)name);

    if (parser->startElementHandler.toBoolean()) {
      args.append(parser);
      args.append(_xml_string_zval(tag_name));
      args.append(Array::Create());

      while (attributes && *attributes) {
        char* att = _xml_decode_tag(parser, (const char*)attributes[0]);
        int val_len;
        char* val = xml_utf8_decode(attributes[1],
                                    strlen((const char*)attributes[1]),
                                    &val_len, parser->target_encoding);
        args.lvalAt(2).toArrRef().set(
          String(att, AttachString),
          String(val, val_len, AttachString)
        );
        attributes += 2;
      }

      xml_call_handler(parser, parser->startElementHandler, args);
    }

    if (!parser->data.isNull()) {
      if (parser->level <= XML_MAXLEVEL) {
        Array tag, atr;
        int atcnt = 0;
        tag = Array::Create();
        atr = Array::Create();

        _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);

        tag.set(s_tag,String(((char *)tag_name)+parser->toffset,CopyString));
        tag.set(s_type, s_open);
        tag.set(s_level, parser->level);

        parser->ltags[parser->level-1] = strdup(tag_name);
        parser->lastwasopen = 1;

        attributes = (const XML_Char **) attrs;

        while (attributes && *attributes) {
          char* att = _xml_decode_tag(parser, (const char*)attributes[0]);
          int val_len;
          char* val = xml_utf8_decode(attributes[1],
                                      strlen((const char*)attributes[1]),
                                      &val_len, parser->target_encoding);
          atr.set(String(att, AttachString),
                  String(val, val_len, AttachString));
          atcnt++;
          attributes += 2;
        }

        if (atcnt) {
          tag.set(s_attributes,atr);
        }
        auto& lval = parser->data.toArrRef().lvalAt();
        lval.assignRef(tag);
        parser->ctag.assignRef(lval);
      } else if (parser->level == (XML_MAXLEVEL + 1)) {
        raise_warning("Maximum depth exceeded - Results truncated");
      }
    }

    free(tag_name);
  }
}
Example #15
0
bool TestCppBase::TestArray() {
  // Array::Create(), Array constructors and informational
  {
    Array arr;
    VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
    VERIFY(arr.isNull());

    arr = Array::Create();
    VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
    VERIFY(!arr.isNull());

    arr = Array::Create(0);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[0].toInt32() == 0);

    arr = Array::Create("test");
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(equal(arr[0], String("test")));

    Array arrCopy = arr;
    arr = Array::Create(arr);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[0].toArray().size() == 1);
    VS(arr[0], arrCopy);

    arr = Array::Create("name", 1);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[s_name].toInt32() == 1);

    arr = Array::Create(s_name, "test");
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(equal(arr[s_name], String("test")));

    arrCopy = arr;
    arr = Array::Create(s_name, arr);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VS(arr[s_name], arrCopy);
    VERIFY(arr[s_name].toArray().size() == 1);
  }

  // iteration
  {
    Array arr = make_map_array("n1", "v1", "n2", "v2");
    int i = 0;
    for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) {
      if (i == 0) {
        VERIFY(equal(iter.first(), String("n1")));
        VERIFY(equal(iter.second(), String("v1")));
      } else {
        VERIFY(equal(iter.first(), String("n2")));
        VERIFY(equal(iter.second(), String("v2")));
      }
    }
    VERIFY(i == 2);
  }

  static const StaticString s_Array("Array");

  // conversions
  {
    Array arr0;
    VERIFY(arr0.toBoolean() == false);
    VERIFY(arr0.toByte() == 0);
    VERIFY(arr0.toInt16() == 0);
    VERIFY(arr0.toInt32() == 0);
    VERIFY(arr0.toInt64() == 0);
    VERIFY(arr0.toDouble() == 0.0);
    VERIFY(arr0.toString().empty());

    Array arr1 = Array::Create("test");
    VERIFY(arr1.toBoolean() == true);
    VERIFY(arr1.toByte() == 1);
    VERIFY(arr1.toInt16() == 1);
    VERIFY(arr1.toInt32() == 1);
    VERIFY(arr1.toInt64() == 1);
    VERIFY(arr1.toDouble() == 1.0);
    VERIFY(arr1.toString() == s_Array);
  }

  // offset
  {
    Array arr;
    arr.set(0, "v1");
    arr.set(1, "v2");
    VS(arr, make_packed_array("v1", "v2"));
  }
  {
    Array arr;
    arr.set(s_n1, "v1");
    arr.set(s_n2, "v2");
    VS(arr, make_map_array("n1", "v1", "n2", "v2"));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    arr.lvalAt(1) = String("v2");
    VS(arr, make_packed_array("v1", "v2"));
  }
  {
    Array arr;
    arr.lvalAt(s_n1) = String("v1");
    arr.lvalAt(s_n2) = String("v2");
    VS(arr, make_map_array("n1", "v1", "n2", "v2"));
  }
  {
    Array arr;
    Variant name = "name";
    arr.lvalAt(name) = String("value");
    VS(arr, make_map_array("name", "value"));
  }

  {
    Array arr;
    arr.lvalAt(1) = 10;
    VS(arr[1], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(Variant(1.5)) = 10;
    VS(arr[1], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(s_1) = 10;
    VS(arr[1], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(Variant("1")) = 10;
    VS(arr[1], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }

  // membership
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    arr.lvalAt(1) = String("v2");
    VERIFY(arr.exists(0));
    arr.remove(0);
    VERIFY(!arr.exists(0));
    VS(arr, Array::Create(1, "v2"));
    arr.append("v3");
    VS(arr, make_map_array(1, "v2", 2, "v3"));
  }
  {
    static const StaticString s_0("0");
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(String(s_0));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant("0"));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant(Variant("0")));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant(Variant(0.5)));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(Variant()) = 123;
    VERIFY(arr.exists(empty_string_ref));
    arr.remove(Variant());
    VERIFY(!arr.exists(empty_string_ref));
  }
  {
    Array arr;
    arr.lvalAt(s_n1) = String("v1");
    arr.lvalAt(s_n2) = String("v2");
    VERIFY(arr.exists(s_n1));
    arr.remove(s_n1);
    VERIFY(!arr.exists(s_n1));
    VS(arr, Array::Create(s_n2, "v2"));
    arr.append("v3");
    VS(arr, make_map_array("n2", "v2", 0, "v3"));
  }
  {
    Array arr;
    arr.lvalAt() = String("test");
    VS(arr, make_packed_array("test"));
  }
  {
    Array arr;
    arr.lvalAt(s_name) = String("value");
    VERIFY(arr.exists(s_name));
  }
  {
    Array arr;
    arr.lvalAt(1) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(s_1) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(Variant(1.5)) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(Variant("1")) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }

  // merge
  {
    Array arr = Array::Create(0) + Array::Create(1);
    VS(arr, Array::Create(0));
    arr += make_packed_array(0, 1);
    VS(arr, make_packed_array(0, 1));

    arr = Array::Create(0).merge(Array::Create(1));
    VS(arr, make_packed_array(0, 1));
    arr = arr.merge(make_packed_array(0, 1));
    VS(arr, make_packed_array(0, 1, 0, 1));

    arr = Array::Create("s0").merge(Array::Create("s1"));
    VS(arr, make_packed_array("s0", "s1"));

    arr = Array::Create("n0", "s0") + Array::Create("n1", "s1");
    VS(arr, make_map_array("n0", "s0", "n1", "s1"));
    arr += make_map_array("n0", "s0", "n1", "s1");
    VS(arr, make_map_array("n0", "s0", "n1", "s1"));

    arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1"));
    VS(arr, make_map_array("n0", "s0", "n1", "s1"));
    Array arrX = make_map_array("n0", "s2", "n1", "s3");
    arr = arr.merge(arrX);
    VS(arr, make_map_array("n0", "s2", "n1", "s3"));
  }

  {
    Array arr = make_map_array(0, "a", 1, "b");
    VERIFY(arr->isVectorData());
  }
  {
    Array arr = make_map_array(1, "a", 0, "b");
    VERIFY(!arr->isVectorData());
  }
  {
    Array arr = make_map_array(1, "a", 2, "b");
    VERIFY(!arr->isVectorData());
  }
  {
    Array arr = make_map_array(1, "a");
    arr.set(0, "b");
    VERIFY(!arr->isVectorData());
  }

  return Count(true);
}
Example #16
0
bool TestCppBase::TestArray() {
  // Array::Create(), Array constructors and informational
  {
    Array arr;
    VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
    VERIFY(arr.isNull());

    arr = Array::Create();
    VERIFY(arr.empty()); VERIFY(arr.size() == 0); VERIFY(arr.length() == 0);
    VERIFY(!arr.isNull());

    arr = Array::Create(0);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY((int)arr[0] == 0);
    VS(arr, Array(ArrayInit(1).set(0).create()));

    arr = Array::Create("test");
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[0] == "test");
    VS(arr, Array(ArrayInit(1).set("test").create()));

    Array arrCopy = arr;
    arr = Array::Create(arr);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[0].toArray().size() == 1);
    VS(arr[0], arrCopy);
    VS(arr, Array(ArrayInit(1).set(arrCopy).create()));

    arr = Array::Create("name", 1);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY((int)arr[s_name] == 1);
    VS(arr, Array(ArrayInit(1).set(s_name, 1).create()));

    arr = Array::Create(s_name, "test");
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VERIFY(arr[s_name] == "test");
    VS(arr, Array(ArrayInit(1).set(s_name, "test").create()));

    arrCopy = arr;
    arr = Array::Create(s_name, arr);
    VERIFY(!arr.empty()); VERIFY(arr.size() == 1); VERIFY(arr.length() == 1);
    VERIFY(!arr.isNull());
    VS(arr[s_name], arrCopy);
    VERIFY(arr[s_name].toArray().size() == 1);
    VS(arr, Array(ArrayInit(1).set(s_name, arrCopy).create()));
  }

  // iteration
  {
    Array arr = CREATE_MAP2("n1", "v1", "n2", "v2");
    int i = 0;
    for (ArrayIter iter = arr.begin(); iter; ++iter, ++i) {
      if (i == 0) {
        VERIFY(iter.first() == "n1");
        VERIFY(iter.second() == "v1");
      } else {
        VERIFY(iter.first() == "n2");
        VERIFY(iter.second() == "v2");
      }
    }
    VERIFY(i == 2);
  }
  /* TODO: fix this
  {
    Variant arr = CREATE_MAP2("n1", "v1", "n2", "v2");
    arr.escalate();
    for (ArrayIterPtr iter = arr.begin(arr, true); !iter->end(); iter->next()){
      unset(arr.lvalAt(iter->first()));
    }
    VS(arr, Array::Create());
  }
  */

  // conversions
  {
    Array arr0;
    VERIFY(arr0.toBoolean() == false);
    VERIFY(arr0.toByte() == 0);
    VERIFY(arr0.toInt16() == 0);
    VERIFY(arr0.toInt32() == 0);
    VERIFY(arr0.toInt64() == 0);
    VERIFY(arr0.toDouble() == 0.0);
    VERIFY(arr0.toString() == "");

    Array arr1 = Array::Create("test");
    VERIFY(arr1.toBoolean() == true);
    VERIFY(arr1.toByte() == 1);
    VERIFY(arr1.toInt16() == 1);
    VERIFY(arr1.toInt32() == 1);
    VERIFY(arr1.toInt64() == 1);
    VERIFY(arr1.toDouble() == 1.0);
    VERIFY(arr1.toString() == "Array");
  }

  // offset
  {
    Array arr;
    arr.set(0, "v1");
    arr.set(1, "v2");
    VS(arr, CREATE_VECTOR2("v1", "v2"));
  }
  {
    Array arr;
    arr.set(s_n1, "v1");
    arr.set(s_n2, "v2");
    VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2"));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    arr.lvalAt(1) = String("v2");
    VS(arr, CREATE_VECTOR2("v1", "v2"));
  }
  {
    Array arr;
    arr.lvalAt(s_n1) = String("v1");
    arr.lvalAt(s_n2) = String("v2");
    VS(arr, CREATE_MAP2("n1", "v1", "n2", "v2"));
  }
  {
    Array arr;
    Variant name = "name";
    arr.lvalAt(name) = String("value");
    VS(arr, CREATE_MAP1("name", "value"));
  }
  {
    Array arr;
    arr.lvalAt(s_A) = 10;
    arr.lvalAt(s_A)++;
    VS(arr[s_A], 11);
  }

  {
    Array arr;
    arr.lvalAt(1) = 10;
    VS(arr[1], 10);
    VS(arr[1.5], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(Variant(1.5)) = 10;
    VS(arr[1], 10);
    VS(arr[1.5], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(s_1) = 10;
    VS(arr[1], 10);
    VS(arr[1.5], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }
  {
    Array arr;
    arr.lvalAt(Variant("1")) = 10;
    VS(arr[1], 10);
    VS(arr[1.5], 10);
    VS(arr[Variant(1.5)], 10);
    VS(arr[s_1], 10);
    VS(arr[Variant("1")], 10);
  }

  // membership
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    arr.lvalAt(1) = String("v2");
    VERIFY(arr.exists(0));
    arr.remove(0);
    VERIFY(!arr.exists(0));
    VS(arr, Array::Create(1, "v2"));
    arr.append("v3");
    VS(arr, CREATE_MAP2(1, "v2", 2, "v3"));
  }
  {
    static const StaticString s_0("0");
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(String(s_0));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant("0"));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant(Variant("0")));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(0) = String("v1");
    VERIFY(arr.exists(0));
    arr.remove(Variant(Variant(0.5)));
    VERIFY(!arr.exists(0));
  }
  {
    Array arr;
    arr.lvalAt(Variant()) = 123;
    VERIFY(arr.exists(empty_string));
    arr.remove(Variant());
    VERIFY(!arr.exists(empty_string));
  }
  {
    Array arr;
    arr.lvalAt(s_n1) = String("v1");
    arr.lvalAt(s_n2) = String("v2");
    VERIFY(arr.exists(s_n1));
    arr.remove(s_n1);
    VERIFY(!arr.exists(s_n1));
    VS(arr, Array::Create(s_n2, "v2"));
    arr.append("v3");
    VS(arr, CREATE_MAP2("n2", "v2", 0, "v3"));
  }
  {
    Array arr;
    arr.lvalAt() = String("test");
    VS(arr, CREATE_VECTOR1("test"));
  }
  {
    Array arr;
    arr.lvalAt(s_name) = String("value");
    VERIFY(arr.exists(s_name));
  }
  {
    Array arr;
    arr.lvalAt(1) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(1.5));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(s_1) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(1.5));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(1.5) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(1.5));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(Variant(1.5)) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(1.5));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }
  {
    Array arr;
    arr.lvalAt(Variant("1")) = String("value");
    VERIFY(arr.exists(1));
    VERIFY(arr.exists(1.5));
    VERIFY(arr.exists(s_1));
    VERIFY(arr.exists(Variant("1")));
    VERIFY(arr.exists(Variant(1)));
    VERIFY(arr.exists(Variant(1.5)));
  }

  // merge
  {
    Array arr = Array::Create(0) + Array::Create(1);
    VS(arr, Array::Create(0));
    arr += CREATE_VECTOR2(0, 1);
    VS(arr, CREATE_VECTOR2(0, 1));

    arr = Array::Create(0).merge(Array::Create(1));
    VS(arr, CREATE_VECTOR2(0, 1));
    arr = arr.merge(CREATE_VECTOR2(0, 1));
    VS(arr, CREATE_VECTOR4(0, 1, 0, 1));

    arr = Array::Create("s0").merge(Array::Create("s1"));
    VS(arr, CREATE_VECTOR2("s0", "s1"));

    arr = Array::Create("n0", "s0") + Array::Create("n1", "s1");
    VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));
    arr += CREATE_MAP2("n0", "s0", "n1", "s1");
    VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));

    arr = Array::Create("n0", "s0").merge(Array::Create("n1", "s1"));
    VS(arr, CREATE_MAP2("n0", "s0", "n1", "s1"));
    Array arrX = CREATE_MAP2("n0", "s2", "n1", "s3");
    arr = arr.merge(arrX);
    VS(arr, CREATE_MAP2("n0", "s2", "n1", "s3"));
  }

  // slice
  {
    Array arr = CREATE_VECTOR2("test1", "test2");
    Array sub = arr.slice(1, 1, true);
    VS(sub, CREATE_MAP1(1, "test2"));
  }
  {
    Array arr = CREATE_VECTOR2("test1", "test2");
    Array sub = arr.slice(1, 1, false);
    VS(sub, CREATE_VECTOR1("test2"));
  }
  {
    Array arr = CREATE_MAP2("n1", "test1", "n2", "test2");
    Array sub = arr.slice(1, 1, true);
    VS(sub, CREATE_MAP1("n2", "test2"));
  }
  {
    Array arr = CREATE_MAP2("n1", "test1", "n2", "test2");
    Array sub = arr.slice(1, 1, false);
    VS(sub, CREATE_MAP1("n2", "test2"));
  }

  // escalation
  {
    Array arr;
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Array arr;
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Array arr = Array::Create();
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Array arr = Array::Create();
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Array arr = Array::Create("test");
    arr.lvalAt(0) = CREATE_VECTOR1(1.2);
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Array arr = Array::Create("test");
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Array arr = Array::Create();
    arr.append("apple");
    arr.set(2, "pear");
    VS(arr[2], "pear");
  }

  {
    Array arr = CREATE_MAP2(0, "a", 1, "b");
    VERIFY(arr->isVectorData());
  }
  {
    Array arr = CREATE_MAP2(1, "a", 0, "b");
    VERIFY(!arr->isVectorData());
  }
  {
    Array arr = CREATE_MAP2(1, "a", 2, "b");
    VERIFY(!arr->isVectorData());
  }
  {
    Array arr = CREATE_MAP1(1, "a");
    arr.set(0, "b");
    VERIFY(!arr->isVectorData());
  }

  return Count(true);
}
Example #17
0
void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Char **attributes) {
  XmlParser *parser = (XmlParser *)userData;
  const char **attrs = (const char **) attributes;
  Variant retval;
  Array args = Array::Create();

  if (parser) {
    parser->level++;

    char* tag_name = _xml_decode_tag(parser, (const char*)name);

    if (parser->startElementHandler) {
      args.append(parser);
      args.append(_xml_string_zval(tag_name));
      args.append(Array::Create());

      while (attributes && *attributes) {
        char* att = _xml_decode_tag(parser, (const char*)attributes[0]);
        int val_len;
        char* val = xml_utf8_decode(attributes[1],
                                    strlen((const char*)attributes[1]),
                                    &val_len, parser->target_encoding);
        args.lvalAt(2).set(String(att, AttachString),
                           String(val, val_len, AttachString));
        attributes += 2;
      }

      xml_call_handler(parser, parser->startElementHandler, args);
    }

    if (!parser->data.isNull()) {
      Array tag, atr;
      int atcnt = 0;
      tag = Array::Create();
      atr = Array::Create();

      _xml_add_to_info(parser,((char *) tag_name) + parser->toffset);

      tag.set(s_tag,String(((char *)tag_name)+parser->toffset,CopyString));
      tag.set(s_type, s_open);
      tag.set(s_level, parser->level);

      parser->ltags[parser->level-1] = strdup(tag_name);
      parser->lastwasopen = 1;

      attributes = (const XML_Char **) attrs;

      while (attributes && *attributes) {
        char* att = _xml_decode_tag(parser, (const char*)attributes[0]);
        int val_len;
        char* val = xml_utf8_decode(attributes[1],
                                    strlen((const char*)attributes[1]),
                                    &val_len, parser->target_encoding);
        atr.set(String(att, AttachString), String(val, val_len, AttachString));
        atcnt++;
        attributes += 2;
      }

      if (atcnt) {
        tag.set(s_attributes,atr);
      }
      parser->data.append(tag);
      parser->ctag.assignRef(parser->data.getArrayData()->endRef());
    }

    free(tag_name);
  }
}