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()); } }
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()); } }
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); } }
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; }
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; }
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; }
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 ¶ms = mi.lvalAt(s_params).asArrRef(); for (int i = 0; i < params.size(); i++) { params.lvalAt(i).asArrRef().remove(s_class); } return mi; }
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()); } } } }
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); } } }
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(); }
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; }
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); } }
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); }
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); }
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); } }