//[return: PhpDeepCopy] // already deep copied public static PhpArray GetObjectVars(DTypeDesc caller, DObject obj, bool IgnoreReferences) { if (obj == null) { return(null); } Converter <object, object> copy = null; /////////////////////////////////////// // This is hot fix for a reference counting problem when reference aren't released in same way as in PHP. // Hence, we need to perform deep copy ignoring references if (IgnoreReferences) { copy = (value) => { PhpReference refValue = value as PhpReference; if (refValue != null) { return(copy(refValue.Value)); } PhpArray array = value as PhpArray; if (array != null) { PhpArray dst = new PhpArray(array.IntegerCount, array.StringCount); foreach (KeyValuePair <IntStringKey, object> entry in array) { // checks whether a value is a reference pointing to the instance itself: refValue = entry.Value as PhpReference; if (refValue != null && refValue.Value == array) { // copies the value so that it will self-reference the new instance (not the old one): dst.Add(entry.Key, new PhpReference(dst)); } else { dst.Add(entry.Key, copy(entry.Value)); } } return(dst); } return(value); } } ; else { copy = (value) => { return(PhpVariable.DeepCopy(value)); } }; // perform InplaceDeepCopy() here to save one more iteration through the array /////////////////////////////////////// PhpArray result = new PhpArray(0, obj.Count); var foreachEnumerator = obj.GetEnumerator((caller != null && caller.IsUnknown) ? PhpStackTrace.GetClassContext() : caller); while (foreachEnumerator.MoveNext()) //foreach (DictionaryEntry pair in obj) { DictionaryEntry pair = (DictionaryEntry)foreachEnumerator.Current; result.Add((string)pair.Key, copy(pair.Value)); } //result.InplaceCopyOnReturn = true; // already deep copied return(result); }
//[return: PhpDeepCopy] // already deep copied public static PhpArray GetObjectVars(DTypeDesc caller, DObject obj, bool IgnoreReferences) { if (obj == null) return null; Converter<object, object> copy = null; /////////////////////////////////////// // This is hot fix for a reference counting problem when reference aren't released in same way as in PHP. // Hence, we need to perform deep copy ignoring references if (IgnoreReferences) copy = (value) => { PhpReference refValue = value as PhpReference; if (refValue != null) return copy(refValue.Value); PhpArray array = value as PhpArray; if (array != null) { PhpArray dst = new PhpArray(array.IntegerCount, array.StringCount); foreach (KeyValuePair<IntStringKey, object> entry in array) { // checks whether a value is a reference pointing to the instance itself: refValue = entry.Value as PhpReference; if (refValue != null && refValue.Value == array) { // copies the value so that it will self-reference the new instance (not the old one): dst.Add(entry.Key, new PhpReference(dst)); } else { dst.Add(entry.Key, copy(entry.Value)); } } return dst; } return value; }; else copy = (value) => { return PhpVariable.DeepCopy(value); }; // perform InplaceDeepCopy() here to save one more iteration through the array /////////////////////////////////////// PhpArray result = new PhpArray(0, obj.Count); var foreachEnumerator = obj.GetEnumerator((caller != null && caller.IsUnknown) ? PhpStackTrace.GetClassContext() : caller); while (foreachEnumerator.MoveNext()) //foreach (DictionaryEntry pair in obj) { DictionaryEntry pair = (DictionaryEntry)foreachEnumerator.Current; result.Add((string)pair.Key, copy(pair.Value)); } //result.InplaceCopyOnReturn = true; // already deep copied return result; }
public static PhpArray GetClassVars(DTypeDesc caller, string className, bool parentsFirst, bool includeStatic) { ScriptContext script_context = ScriptContext.CurrentContext; DTypeDesc type = script_context.ResolveType(className); if (type == null) { return(null); } // determine the calling type //DTypeDesc caller = PhpStackTrace.GetClassContext(); if (caller != null && caller.IsUnknown) { caller = PhpStackTrace.GetClassContext(); } PhpArray result = new PhpArray(); // add instance properties bool have_instance_props = false; if (!type.IsAbstract) { // the class has to be instantiated in order to discover default instance property values // (the constructor will initialize default properties, user defined constructor will not be called) DObject obj = type.New(script_context) as DObject; if (obj == null) { return(null); } // populate the resulting array taking into account current caller IDictionaryEnumerator enumerator = obj.GetEnumerator(caller); while (enumerator.MoveNext()) { result.Add(enumerator.Key, enumerator.Value); } have_instance_props = true; } // add static fields (static and instance fields if the type is abstract) if (includeStatic) { foreach (KeyValuePair <VariableName, DPropertyDesc> pair in type.EnumerateProperties(caller)) { if (pair.Value.IsStatic) { result.Add(pair.Key.ToString(), pair.Value.Get(null)); } else if (!have_instance_props) { result.Add(pair.Key.ToString(), null); } } } result.InplaceCopyOnReturn = true; return(result); }