/// <summary> /// Adds a parameter to variable binding. /// </summary> /// <param name="parameter">SQL parameter.</param> /// <param name="variable">PHP variable passed by reference.</param> /// <param name="type">Parameter type specified by user.</param> /// <returns><B>true</B> if the binding succeeded.</returns> public bool AddBinding(IDataParameter /*!*/ parameter, PhpReference /*!*/ variable, ParameterType type) { if (parameter == null) { throw new ArgumentNullException("parameter"); } if (variable == null) { throw new ArgumentNullException("variable"); } if (type < ParameterType.String || type > ParameterType.Infer) { throw new ArgumentOutOfRangeException("type"); } if (Bindings.ContainsKey(parameter.ParameterName)) { return(false); } Bindings.Add(parameter.ParameterName, new Binding(variable, parameter, type)); return(true); }
private static PhpResource Open(string filename, int mode, PhpReference error, bool persistent) { if (persistent) PhpException.FunctionNotSupported(PhpError.Notice); SQLiteConnectionStringBuilder csb = new SQLiteConnectionStringBuilder(); csb.DataSource = filename; csb.Version = 3; try { PhpSQLiteDbConnection connection = new PhpSQLiteDbConnection(csb.ConnectionString); if (error != null) { error.Value = null; } return connection; } catch (Exception ex) { if (error != null) { error.Value = ex.Message; } return null; } }
static PhpReference GetRefMemberNotFound(DObject self, string name, DTypeDesc caller) { PhpReference reference; bool getter_exists; // search in RT fields if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name)) { var namekey = new IntStringKey(name); return(self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields)); } // property is not present -> try to invoke __get reference = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) { return((reference == null) ? new PhpReference() : reference); } // (no notice/warning/error thrown by PHP) // add the field reference = new PhpReference(); if (self.RuntimeFields == null) { self.RuntimeFields = new PhpArray(); } self.RuntimeFields[name] = reference; return(reference); }
protected override void SetArrayItemRefOverride(object key, PhpReference value) { PhpStack stack = ScriptContext.CurrentContext.Stack; stack.AddFrame(key, value); arrayAccess.InvokeMethod(offsetSet, null, stack.Context); }
private static PhpResource Open(string filename, int mode, PhpReference error, bool persistent) { if (persistent) { PhpException.FunctionNotSupported(PhpError.Notice); } SQLiteConnectionStringBuilder csb = new SQLiteConnectionStringBuilder(); csb.DataSource = filename; csb.Version = 3; try { PhpSQLiteDbConnection connection = new PhpSQLiteDbConnection(csb.ConnectionString); if (error != null) { error.Value = null; } return(connection); } catch (Exception ex) { if (error != null) { error.Value = ex.Message; } return(null); } }
public static bool Bind(PhpResource statement, string parameterName, PhpReference variable, VariableType type, bool isOutput, bool isNullable, int maxLength) { PhpSqlDbProcedure procedure = PhpSqlDbProcedure.ValidProcedure(statement); if (procedure == null) { return(false); } if (parameterName == null) { PhpException.ArgumentNull("parameterName"); return(false); } PhpSqlDbProcedure.ParameterType param_type = PhpSqlDbProcedure.VariableTypeToParamType(type); if (param_type == PhpSqlDbProcedure.ParameterType.Invalid) { PhpException.ArgumentValueNotSupported("type", (int)type); return(false); } SqlParameter parameter = new SqlParameter(); parameter.ParameterName = parameterName; // it is necessary to set size for in-out params as the results are truncated to this size; // 8000 is maximal size of the data according to the doc: if (maxLength >= 0) { parameter.Size = maxLength; } else { parameter.Size = 8000; } if (String.Compare(parameterName, "RETVAL", true) == 0) { parameter.Direction = ParameterDirection.ReturnValue; } else if (isOutput) { parameter.Direction = ParameterDirection.InputOutput; } else { parameter.Direction = ParameterDirection.Input; } if (!procedure.AddBinding(parameter, variable, param_type)) { PhpException.Throw(PhpError.Notice, LibResources.GetString("parameter_already_bound", parameterName)); return(false); } return(true); }
public Binding(PhpReference/*!*/ variable, IDataParameter/*!*/ parameter, ParameterType type) { Debug.Assert(variable != null && parameter != null && type != ParameterType.Invalid); this.Variable = variable; this.Parameter = parameter; this.Type = type; }
public Binding(PhpReference /*!*/ variable, IDataParameter /*!*/ parameter, ParameterType type) { Debug.Assert(variable != null && parameter != null && type != ParameterType.Invalid); this.Variable = variable; this.Parameter = parameter; this.Type = type; }
public static object query(object instance, PhpStack stack) { object query = stack.PeekValue(1); object resultType = stack.PeekValueOptional(2); PhpReference error = stack.PeekReferenceOptional(3); stack.RemoveFrame(); return(((SQLiteDatabase)instance).query(stack.Context, query, resultType, error)); }
public static object __construct(object instance, PhpStack stack) { object argFileName = stack.PeekValue(1); object argMode = stack.PeekValueOptional(2); PhpReference error = stack.PeekReferenceOptional(3); stack.RemoveFrame(); string filename = PHP.Core.Convert.ObjectToString(argFileName); int mode = PHP.Core.Convert.ObjectToInteger(argMode); return(((SQLiteDatabase)instance).__construct(stack.Context, filename, mode, error)); }
static PhpReference notsetOperation(DObject self, string name, DTypeDesc caller, PhpReference refrnc) { bool getter_exists; // the CT property has been unset -> try to invoke __get PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) return get_ref ?? new PhpReference(); Debug.Assert(refrnc != null); refrnc.IsAliased = true; refrnc.IsSet = true; return refrnc; }
public static T Call <T>(this ScriptContext context, string /*!*/ functionName, NamingContext namingContext, Dictionary <string, object> callerLocalVariables, params object[] arguments) where T : class { PhpReference rf = context.Call(functionName, namingContext, callerLocalVariables, arguments); if (rf.Value == null) { return(null); } else { return(DuckTyping.Instance.ImplementDuckType <T>(rf.Value)); } }
/// <summary> /// Gets an item of a user array by invoking <see cref="Library.SPL.ArrayAccess.offsetGet"/>. /// </summary> /// <param name="arrayAccess">User array object.</param> /// <param name="index">An index.</param> /// <param name="context">The current script context.</param> /// <returns>A reference on item returned by the user getter.</returns> internal static PhpReference GetUserArrayItemRef(DObject /*!*/ arrayAccess, object index, ScriptContext /*!*/ context) { Debug.Assert(arrayAccess.RealObject is Library.SPL.ArrayAccess); Debug.Assert(!(index is PhpReference)); context.Stack.AddFrame(index); object result = arrayAccess.InvokeMethod(Library.SPL.PhpArrayObject.offsetGet, null, context); PhpReference ref_result = result as PhpReference; if (ref_result == null) { // obsolete (?): PhpException.Throw(PhpError.Error,CoreResources.GetString("offsetGet_must_return_byref")); ref_result = new PhpReference(result); } return(ref_result); }
static PhpReference notsetOperation(DObject self, string name, DTypeDesc caller, PhpReference refrnc) { bool getter_exists; // the CT property has been unset -> try to invoke __get PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) { return(get_ref ?? new PhpReference()); } Debug.Assert(refrnc != null); refrnc.IsAliased = true; refrnc.IsSet = true; return(refrnc); }
public object query(ScriptContext context, object query, object resultType, PhpReference error) { SQLite.QueryResultKeys rt = SQLite.QueryResultKeys.Both; int vRt = PHP.Core.Convert.ObjectToInteger(resultType); if (Enum.IsDefined(typeof(SQLite.QueryResultKeys), vRt)) { rt = (SQLite.QueryResultKeys)vRt; } PhpSQLiteDbResult result = (PhpSQLiteDbResult)SQLite.Query(this.m_con, query, rt, error); if (result != null) { return new SQLiteResult(result); } else { return null; } }
public static bool ParseStr(string encoded_string, PhpReference array) { try { PhpArray result = new PhpArray(); foreach (var x in ParseUrlEncodedGetParameters(encoded_string)) { result.Add(x.Key, x.Value); } array.Value = result; return(true); } catch { return(false); } }
/// <summary> /// Calls the indexer (offsetGet) and ensures that its result is an array or can be converted to an array. /// </summary> /// <param name="key">A key passed to the indexer.</param> /// <returns>The array (either previously existing or a created one) or a <B>null</B> reference on error.</returns> /// <exception cref="PhpException">The indexer doesn't return a reference (Error).</exception> /// <exception cref="PhpException">The return value cannot be converted to an array (Warning).</exception> private PhpArray EnsureIndexerResultIsRefArray(object key) { PhpReference ref_result = GetUserArrayItemRef(arrayAccess, key, ScriptContext.CurrentContext); object new_value; var wrappedwarray = Operators.EnsureObjectIsArray(ref_result.Value, out new_value); if (wrappedwarray != null) { if (new_value != null) { ref_result.Value = new_value; } return(wrappedwarray); } // the result is neither array nor object behaving like array: PhpException.VariableMisusedAsArray(ref_result.Value, false); return(null); }
public static bool SetObject(PhpResource parser, PhpReference objRef) { XmlParserResource xmlParser = parser as XmlParserResource; if (xmlParser != null) { DObject dObject = objRef != null ? objRef.Value as DObject : null; if (dObject != null) { xmlParser.HandlerObject = dObject; } else { xmlParser.HandlerObject = null; } return(true); } return(false); }
public object query(ScriptContext context, object query, object resultType, PhpReference error) { SQLite.QueryResultKeys rt = SQLite.QueryResultKeys.Both; int vRt = PHP.Core.Convert.ObjectToInteger(resultType); if (Enum.IsDefined(typeof(SQLite.QueryResultKeys), vRt)) { rt = (SQLite.QueryResultKeys)vRt; } PhpSQLiteDbResult result = (PhpSQLiteDbResult)SQLite.Query(this.m_con, query, rt, error); if (result != null) { return(new SQLiteResult(result)); } else { return(null); } }
public static bool Exec(object arg1, object arg2, PhpReference error_message) { PhpSQLiteDbConnection connection = PhpSQLiteDbConnection.ValidConnection(arg1 as PhpResource); string query; if (connection == null) { connection = PhpSQLiteDbConnection.ValidConnection(arg2 as PhpResource); query = PHP.Core.Convert.ObjectToString(arg1); } else { query = PHP.Core.Convert.ObjectToString(arg2); } if (query == null || connection == null) { return(false); } try { connection.ExecuteCommand(query, System.Data.CommandType.Text, true, null, true); if (error_message != null) { error_message.Value = null; } return(true); } catch (Exception ex) { if (error_message != null) { error_message.Value = ex.Message; } return(false); } }
/// <summary> /// Calls the indexer (offsetGet) and ensures that its result is an <see cref="DObject"/> or can be /// converted to <see cref="DObject"/>. /// </summary> /// <param name="key">A key passed to the indexer.</param> /// <param name="context">A script context.</param> /// <returns>The <see cref="DObject"/> (either previously existing or a created one) or a <B>null</B> reference on error.</returns> /// <exception cref="PhpException">The indexer doesn't return a reference (Error).</exception> /// <exception cref="PhpException">The return value cannot be converted to a DObject (Warning).</exception> private DObject EnsureIndexerResultIsRefObject(object key, ScriptContext /*!*/ context) { PhpReference ref_result = GetUserArrayItemRef(arrayAccess, key, context); // is the result an array: DObject result = ref_result.Value as DObject; if (result != null) { return(result); } // is result empty => creates a new array and writes it back: if (Operators.IsEmptyForEnsure(ref_result.Value)) { ref_result.Value = result = stdClass.CreateDefaultObject(context); return(result); } // the result is neither array nor object behaving like array not empty value: PhpException.VariableMisusedAsObject(ref_result.Value, false); return(null); }
public static bool ParseStr(string encoded_string, PhpReference array) { try { PhpArray result = new PhpArray(); foreach (var x in ParseUrlEncodedGetParameters(encoded_string)) result.Add(x.Key, x.Value); array.Value = result; return true; } catch { return false; } }
public static PhpBytes exif_thumbnail(string filename, PhpReference width, PhpReference height, PhpReference imagetype) { if (string.IsNullOrEmpty(filename)) { PhpException.Throw(PhpError.Warning, Utils.Resources.GetString("filename_cannot_be_empty")); return(null); } if (imagetype != null) { PhpException.ArgumentValueNotSupported("imagetype", "!=null"); } Bitmap thumbnail = null; PhpBytes bytes, result; bytes = Utils.ReadPhpBytes(filename); if (bytes == null) { return(null); } // get thumbnail from <filename>'s content: using (MemoryStream ms = new MemoryStream(bytes.ReadonlyData)) { try { using (Bitmap image = (Bitmap)Image.FromStream(ms)) { thumbnail = (Bitmap)image.GetThumbnailImage(0, 0, () => true, IntPtr.Zero); } } catch { return(null); } } if (thumbnail == null) { return(null); } // if (width != null) { width.Value = thumbnail.Width; } if (height != null) { height.Value = thumbnail.Height; } using (MemoryStream ms2 = new MemoryStream()) { thumbnail.Save(ms2, ImageFormat.Png); result = new PhpBytes(ms2.GetBuffer()); } thumbnail.Dispose(); return(result); }
public static PhpReference GetVariableRef(ScriptContext/*!*/ context, Dictionary<string, object> locals, string/*!*/ name) { Debug.Assert(name != null); if (locals != null) { // included in method // PhpReference result; object item; if (locals.TryGetValue(name, out item)) { result = item as PhpReference; if (result != null) return result; } else { item = null; } // it is correct to box the item without making a deep copy since there was a single pointer on item // before this operation (by invariant) and there will be a single one after the operation as well: locals[name] = result = new PhpReference(item); return result; } else { // true global code // PhpArray globals = context.AutoGlobals.Globals.Value as PhpArray; PhpReference result; object item = null; if (globals == null) { context.AutoGlobals.Globals.Value = globals = new PhpArray(); } else if (globals.TryGetValue(name, out item)) { result = item as PhpReference; if (result != null) return result; } // it is correct to box the item without making a deep copy since there was a single pointer on item // before this operation (by invariant) and there will be a single one after the operation as well: globals[name] = result = new PhpReference(item); return result; } }
/// <summary> /// Adds session variables aliases to global variables. /// </summary> public void RegisterSessionGlobals() { PhpArray globals, session; // do not create session variables table if not exists: if ((session = PhpReference.AsPhpArray(AutoGlobals.Session)) == null) return; // creates globals array if it doesn't exists: globals = GlobalVariables; // iterates using unbreakable enumerator: foreach (KeyValuePair<IntStringKey, object> entry in session) { PhpReference php_ref = entry.Value as PhpReference; // converts the session variable to a reference if it is not one ("no duplicate pointers" rule preserved): if (php_ref == null) session[entry.Key] = php_ref = new PhpReference(entry.Value); // adds alias to the globals: globals[entry.Key] = php_ref; } }
/// <summary> /// Adds a level of indirection to a specified argument. /// Supresses checks that disables a reference to containe another reference. /// </summary> /// <param name="i">An index of argument starting from 1.</param> internal void AddIndirection(int i) { // preserves "no duplicate pointers" invariant: Items[Top - i] = new PhpReference(Items[Top - i], true); }
public static void f0(PhpReference arg) { PhpVariable.Dump(arg.value); arg.value = "hello"; }
public static PhpReference GetObjectFieldDirectRef(DObject/*!*/ obj, PhpReference/*!*/ field, string/*!*/ name, DTypeDesc caller) { Debug.Assert(obj != null && field != null && name != null); if (field.IsSet) { field.IsAliased = true; return field; } else { return GetObjectPropertyRef(obj, name, caller); } }
public static PhpResource POpen(string filename, int mode, PhpReference error) { return(Open(filename, mode, error, true)); }
public static PhpResource Query(object arg1, object arg2, QueryResultKeys result_type, PhpReference error_msg) { PhpSQLiteDbConnection connection = PhpSQLiteDbConnection.ValidConnection(arg1 as PhpResource); string query; if (connection == null) { connection = PhpSQLiteDbConnection.ValidConnection(arg2 as PhpResource); query = PHP.Core.Convert.ObjectToString(arg1); } else { query = PHP.Core.Convert.ObjectToString(arg2); } if (query == null || connection == null) { return(null); } try { var result = connection.ExecuteQuery(query, true); if (error_msg != null) { error_msg.Value = null; } return(result); } catch (Exception ex) { if (error_msg != null) { error_msg.Value = ex.Message; } return(null); } }
//[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 bool Bind(PhpResource statement, string parameterName, PhpReference variable, VariableType type, bool isOutput, bool isNullable) { return(Bind(statement, parameterName, variable, type, isOutput, isNullable, -1)); }
/// <summary> /// Parses the <B>R</B> token. /// </summary> private void ParseReference() { Consume(Tokens.Colon); int seq_number = (unchecked((int)ReadInteger())) - 1; Consume(Tokens.Semicolon); if (seq_number < 0 || seq_number >= sequenceMap.Count) ThrowInvalidReference(); int index = sequenceMap[seq_number]; // make the referenced atom a PhpReference PhpReference reference = atoms[index] as PhpReference; if (reference == null) { reference = new PhpReference(atoms[index]); atoms[index] = reference; } atoms.Add(new BackReference(index, true)); }
/// <summary> /// Serializes a <see cref="PhpReference"/>. /// </summary> /// <param name="value">The reference.</param> private void WriteReference(PhpReference value) { sequenceNumber--; if (!value.IsAliased) { Serialize(value.Value); return; } int seq; if (serializedRefs.TryGetValue(value, out seq)) { // this reference has already been serialized -> write out its seq. number writer.Write(Tokens.Reference); writer.Write(Tokens.Colon); writer.Write(seq); writer.Write(Tokens.Semicolon); } else { serializedRefs.Add(value, sequenceNumber + 1); if (value.Value is DObject && serializedRefs.TryGetValue(value.Value, out seq)) { // this reference's value has already been serialized -> write out its seq. number // (this is to handle situations such as array($x, &$x), where $x is an object instance) writer.Write(Tokens.Reference); writer.Write(Tokens.Colon); writer.Write(seq); writer.Write(Tokens.Semicolon); } else Serialize(value.Value); } }
public static int ParseIntoStruct(NamingContext /*!*/ namingContext, DTypeDesc caller, PhpResource parser, string data, PhpReference values) { return(ParseIntoStruct(namingContext, caller, parser, data, values, null)); }
public PhpReference PeekReferenceUnchecked(int i) { object item = Items[Top - i]; PhpReference result; PhpRuntimeChain php_chain; // the caller may not pushed a reference although the formal argument is a reference: // it doesn't matter if called by callback: if ((result = item as PhpReference) == null) { // caller may have pushed a runtime chain => evaluate it: if ((php_chain = item as PhpRuntimeChain) != null) { // call state has to be stored since chain can call arbitrary user code: CallState call_state = SaveCallState(); result = php_chain.GetReference(Context); RestoreCallState(call_state); } else { // the reason of copy is not exactly known (it may be returning by copy as well as passing by copy): result = new PhpReference(PhpVariable.Copy(item, CopyReason.Unknown)); // Reports an error in the case that we are not called by callback. // Although, this error is fatal one can switch throwing exceptions off. // If this is the case the afterwards behavior will be the same as if callback was called. if (!Callback) { // warning (can invoke user code => we have to save and restore callstate): CallState call_state = SaveCallState(); PhpException.ArgumentNotPassedByRef(i, CalleeName); RestoreCallState(call_state); } } } return result; }
public static PhpReference GetItemRef(ref object var) { Debug.Assert(!(var is PhpReference)); // PhpArray: if (var != null && var.GetType() == typeof(PhpArray)) // fast check for PhpArray, not derived types return ((PhpArray)var).GetArrayItemRef(); // creates a new reference and adds it to an a new array: if (IsEmptyForEnsure(var)) { PhpArray array; var = array = new PhpArray(1, 0); PhpReference result = new PhpReference(); array.Add(result); return result; } return GetItemRefEpilogue(null, ref var); }
public PhpReference PeekReference(int i) { PhpReference result; if (ArgCount >= i) { // peeks the reference: result = PeekReferenceUnchecked(i); // stores the value back to the stack so that user args functions can work with it: Items[Top - i] = result; } else { result = new PhpReference(); // warning (can invoke user code => we have to save and restore callstate): CallState call_state = SaveCallState(); PhpException.MissingArgument(i, CalleeName); RestoreCallState(call_state); } return result; }
public static void SetItemRef(PhpReference value, string key, ref object var) { Debug.Assert(!(var is PhpReference)); Debug.Assert(!(var is PhpArrayString), "ensures and end-of-chain operators only"); PhpArray array; // PhpArray: if ((array = var as PhpArray) != null) { // a reference in "value" is directly assigned to the array's item: array.SetArrayItemRef(key, value); return; } // null, empty string or empty string of bytes if (IsEmptyForEnsure(var)) { // a reference in "value" is directly assigned to the array's item: PhpArray var_array = new PhpArray(); var_array.SetArrayItemRef(key, value); var = var_array; return; } SetItemRefEpilogue(value, key, ref var); }
/// <summary> /// Ensures that a property value is of <see cref="PhpArray"/> type. /// </summary> /// <param name="obj">The object whose property is to be checked.</param> /// <param name="name">The property name.</param> /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param> /// <param name="propValue">The property value (might get updated).</param> /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound /// statement should not proceed.</returns> internal static PhpArray EnsurePropertyIsArrayInternal(DObject obj, string name, DTypeDesc caller, ref object propValue) { PhpArray result; PhpReference reference = propValue as PhpReference; object value; if (reference != null && !reference.IsSet) { // this CT property has been unset if (obj.TypeDesc.GetMethod(Name.SpecialMethodNames.Set) != null && obj.TypeDesc.RealType.Namespace != null && obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library)) { ScriptContext context = ScriptContext.CurrentContext; // create a chain of arguments to be passed to the setter context.BeginSetterChain(obj); context.ExtendSetterChain(new RuntimeChainProperty(name)); return ScriptContext.SetterChainSingletonArray; } // try to invoke __get bool getter_exists; reference = obj.InvokeGetterRef(name, caller, out getter_exists); if (!getter_exists) { result = new PhpArray(); propValue = new PhpReference(result); return result; } else if (reference == null) return null; // error value = reference.Value; } else value = PhpVariable.Dereference(propValue); // try to wrap into PhpArray: object new_value; var wrappedarray = EnsureObjectIsArray(value, out new_value); if (wrappedarray != null) { if (new_value != null) { if (reference != null) reference.Value = new_value; else propValue = new_value; } return wrappedarray; } // error - the property is a scalar or a PhpObject: PhpException.VariableMisusedAsArray(value, false); return null; }
public static PhpReference GetPropertyRef(ref object var, string name, DTypeDesc caller, ScriptContext context) { Debug.Assert(!(var is PhpReference) && name != null); DObject obj; PhpReference result; // DObject if ((obj = var as DObject) != null) return GetObjectPropertyRef(obj, name, caller); // creates a new stdClass and adds a new property referencing null value if (IsEmptyForEnsure(var)) { result = new PhpReference(); stdClass var_object = stdClass.CreateDefaultObject(context); SetObjectProperty(var_object, name, result, caller); var = var_object; return result; } // errors - PhpArray, a scalar, string PhpException.VariableMisusedAsObject(var, true); return new PhpReference(); }
public static void SetVariableRef(ScriptContext/*!*/ context, Dictionary<string, object> locals, string/*!*/ name, PhpReference reference) { Debug.Assert(name != null); if (locals != null) { locals[name] = reference; } else { PhpArray globals = context.AutoGlobals.Globals.Value as PhpArray; if (globals == null) context.AutoGlobals.Globals.Value = globals = new PhpArray(); globals[name] = reference; } }
public static PhpBytes exif_thumbnail(string filename, PhpReference width, PhpReference height) { return(exif_thumbnail(filename, width, height, null)); }
public static PhpReference/*!*/ GetItemRef(string key, ref object var) { Debug.Assert(!(var is PhpReference)); Debug.Assert(!(var is PhpArrayString), "ensures and end-of-chain operators only"); // PhpArray: if (var != null && var.GetType() == typeof(PhpArray)) // fast check for PhpArray, not derived types return ((PhpArray)var).GetArrayItemRef(key); // creates a new reference and adds it to an a new array: if (IsEmptyForEnsure(var)) { PhpArray array; var = array = new PhpArray(0, 1); PhpReference result = new PhpReference(); array.SetArrayItemRef(key, result); return result; } return GetItemRefEpilogue(key, ref var); }
public static PhpArray Map(PHP.Core.Reflection.DTypeDesc caller, PhpCallback map, [PhpRw] params PhpArray[] arrays) { if (!PhpArgument.CheckCallback(map, caller, "map", 0, true)) return null; if (arrays == null || arrays.Length == 0) { PhpException.InvalidArgument("arrays", LibResources.GetString("arg:null_or_emtpy")); return null; } // if callback has not been specified uses the default one: if (map == null) map = new PhpCallback(new RoutineDelegate(MapIdentity), ScriptContext.CurrentContext); int count = arrays.Length; bool preserve_keys = count == 1; PhpReference[] args = new PhpReference[count]; IEnumerator<KeyValuePair<IntStringKey, object>>[] iterators = new IEnumerator<KeyValuePair<IntStringKey, object>>[count]; PhpArray result; // initializes iterators and args array, computes length of the longest array: int max_count = 0; for (int i = 0; i < arrays.Length; i++) { var array = arrays[i]; if (array == null) { PhpException.Throw(PhpError.Warning, LibResources.GetString("argument_not_array", i + 2));// +2 (first arg is callback) return null; } args[i] = new PhpReference(); iterators[i] = array.GetEnumerator(); if (array.Count > max_count) max_count = array.Count; } // keys are preserved in a case of a single array and re-indexed otherwise: if (preserve_keys) result = new PhpArray(arrays[0].IntegerCount, arrays[0].StringCount); else result = new PhpArray(max_count, 0); for (; ; ) { // fills args[] with items from arrays: for (int i = 0; i < arrays.Length; i++) { if (iterators[i] != null) { // an element is available: if (iterators[i].MoveNext()) { // note: deep copy is not necessary since a function copies its arguments if needed: object value = iterators[i].Current.Value; PhpReference valueref = (value != null) ? value as PhpReference : null; args[i].Value = (valueref != null) ? valueref.value : value; //args[i].Value = iterators[i].Current.Value; // TODO: throws if the current Value is PhpReference } else { // the i-th iterator has stopped: count--; iterators[i] = null; args[i].Value = null; } } } if (count == 0) break; // invokes callback: object return_value = map.Invoke(args); // return value is not deeply copied: if (preserve_keys) result.Add(iterators[0].Current.Key, return_value); else result.Add(return_value); // loads new values (callback may modify some by ref arguments): for (int i = 0; i < arrays.Length; i++) { if (iterators[i] != null) { object item = iterators[i].Current.Value; PhpReference ref_item = item as PhpReference; if (ref_item != null) { ref_item.Value = args[i].Value; } else { arrays[i][iterators[i].Current.Key] = args[i].Value; } } } } return result; }
private static void SetItemRefEpilogue(PhpReference value, object key, ref object var) { // object behaving as array: DObject dobj = var as DObject; if (dobj != null && dobj.RealObject is Library.SPL.ArrayAccess) { PhpStack stack = ScriptContext.CurrentContext.Stack; stack.AddFrame(key, value); dobj.InvokeMethod(Library.SPL.PhpArrayObject.offsetSet, null, stack.Context); return; } // errors - non-empty string, DObject, scalar: PhpException.VariableMisusedAsArray(var, true); }
public static bool Bind(PhpResource statement, string parameterName, PhpReference variable, VariableType type) { return(Bind(statement, parameterName, variable, type, false, false, -1)); }
/// <summary> /// Ensures that a property value is of <see cref="DObject"/> type. /// </summary> /// <param name="obj">The object whose property is to be checked.</param> /// <param name="name">The property name.</param> /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param> /// <param name="propValue">The property value (might get updated).</param> /// <param name="context">The current <see cref="ScriptContext"/>.</param> /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound /// statement should not proceed.</returns> internal static DObject EnsurePropertyIsObjectInternal(DObject obj, string name, DTypeDesc caller, ref object propValue, ScriptContext context) { DObject result; PhpReference reference = propValue as PhpReference; object value; if (reference != null && !reference.IsSet) { // this CT property has been unset if (obj.TypeDesc.GetMethod(Name.SpecialMethodNames.Set) != null && obj.TypeDesc.RealType.Namespace != null && obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library)) { // create a chain of arguments to be passed to the setter context.BeginSetterChain(obj); context.ExtendSetterChain(new RuntimeChainProperty(name)); return ScriptContext.SetterChainSingletonObject; } // try to invoke __get bool getter_exists; reference = obj.InvokeGetterRef(name, caller, out getter_exists); if (!getter_exists) { result = stdClass.CreateDefaultObject(context); propValue = new PhpReference(result); return result; } else if (reference == null) return null; // error value = reference.Value; } else value = PhpVariable.Dereference(propValue); // if property value is a DObject, nothing has to be done result = value as DObject; if (result != null) return result; // if the property is "empty"? if (IsEmptyForEnsure(value)) { // create a new stdClass and update the reference result = stdClass.CreateDefaultObject(context); if (reference != null) { reference.Value = result; reference.IsSet = true; } else propValue = result; return result; } // error - the property is a scalar or a PhpArray or a non-empty string PhpException.VariableMisusedAsObject(value, false); return null; }
/// <summary> /// Ensures that a property value is of <see cref="PhpArray"/> type. /// </summary> /// <param name="obj">The object whose property is to be checked.</param> /// <param name="name">The property name.</param> /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param> /// <param name="propValue">The property value (might get updated).</param> /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound /// statement should not proceed.</returns> internal static PhpArray EnsurePropertyIsArrayInternal(DObject obj, string name, DTypeDesc caller, ref object propValue) { PhpArray result; PhpReference reference = propValue as PhpReference; object value; if (reference != null && !reference.IsSet) { // this CT property has been unset if (obj.TypeDesc.GetMethod(DObject.SpecialMethodNames.Set) != null && obj.TypeDesc.RealType.Namespace != null && obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library)) { ScriptContext context = ScriptContext.CurrentContext; // create a chain of arguments to be passed to the setter context.BeginSetterChain(obj); context.ExtendSetterChain(new RuntimeChainProperty(name)); return ScriptContext.SetterChainSingletonArray; } // try to invoke __get bool getter_exists; reference = obj.InvokeGetterRef(name, caller, out getter_exists); if (!getter_exists) { result = new PhpArray(); propValue = new PhpReference(result); return result; } else if (reference == null) return null; // error value = reference.Value; } else value = PhpVariable.Dereference(propValue); // if the property is PhpArray, nothing has to be done result = value as PhpArray; if (result != null) return result; // checks an object behaving like an array: DObject dobj = value as DObject; if (dobj != null && dobj.RealObject is Library.SPL.ArrayAccess) return new Library.SPL.PhpArrayObject(dobj); // if the property is "empty" if (IsEmptyForEnsure(value)) { // create a new PhpArray and update the reference result = new PhpArray(); if (reference != null) { reference.Value = result; reference.IsSet = true; } else propValue = result; return result; } // non-empty immutable string: string str_value = value as string; if (str_value != null) { PhpString str = new PhpString(str_value); if (reference != null) reference.Value = str; else propValue = str; return new PhpArrayString(str); } // non-empty mutable string: if (value is PhpString || value is PhpBytes) return new PhpArrayString(value); // error - the property is a scalar or a PhpObject: PhpException.VariableMisusedAsArray(value, false); return null; }
public static object GetObjectFieldDirect(DObject/*!*/ obj, PhpReference/*!*/ field, string/*!*/ name, DTypeDesc caller, bool quiet) { Debug.Assert(obj != null && field != null && name != null); if (field.IsSet) { return field.Value; } else { return GetObjectProperty(obj, name, caller, quiet); } }
public static int ReadLineFormat(PhpResource handle, string format, PhpReference arg, params PhpReference[] arguments) { PhpStream stream = PhpStream.GetValid(handle); if (stream == null) return -1; string line = stream.ReadLine(-1, null); return PhpStrings.ScanFormat(line, format, arg, arguments); }
public static void SetObjectFieldDirectRef(PhpReference value, DObject/*!*/ obj, ref PhpReference/*!*/ field, string/*!*/ name, DTypeDesc caller) { Debug.Assert(obj != null && field != null && name != null); if (field.IsSet) { field = value; } else { SetObjectProperty(obj, name, value, caller); } }
private DynamicMetaObject /*!*/ FallbackInvokeMember(DynamicMetaObject target /*!*/, DynamicMetaObject /*!*/[] /*!*/ args) { // determine run time values and additional restrictions: DTypeDesc classContext = this._classContext; string fieldName = this._fieldName; BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType); //target.Restrictions; int currentArg = 0; if (!ClassContextIsKnown) { Debug.Assert(args.Length > currentArg, "Not enough arguments!"); Debug.Assert(args[currentArg].Value == null || Types.DTypeDesc[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong class context type!"); classContext = (DTypeDesc)args[currentArg].Value; Debug.Assert(classContext == null || !classContext.IsUnknown, "Class context should be known at run time!"); restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(args[currentArg].Expression, classContext)); currentArg++; } if (IsIndirect) { Debug.Assert(args.Length > currentArg, "Not enough arguments!"); Debug.Assert(Types.String[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong field name type!"); fieldName = (string)args[currentArg].Value; restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Expression.Equal( args[currentArg].Expression, Expression.Constant(fieldName, Types.String[0])))); currentArg++; } // ////Debug.Assert(!(var is PhpReference) && name != null); Debug.Assert(target.HasValue && target.LimitType != Types.PhpReference[0], "Target should not be PhpReference!"); ////if (ReferenceEquals(obj, ScriptContext.SetterChainSingletonObject)) ////{ //// ScriptContext.CurrentContext.AbortSetterChain(false); //// return new PhpReference(); ////} if (WantReference && ReferenceEquals(target.Value, ScriptContext.SetterChainSingletonObject)) { // GetObjectPropertyRef: Func <PhpReference> abortSetterChain = () => { ScriptContext.CurrentContext.AbortSetterChain(false); return(new PhpReference()); }; return(new DynamicMetaObject( Expression.Call(abortSetterChain.Method), BindingRestrictions.GetInstanceRestriction(target.Expression, ScriptContext.SetterChainSingletonObject) )); } DObject obj; ////// a property of a DObject: if ((obj = target.Value as DObject) != null) { if (obj is ClrObject /*|| obj is IClrValue // IClrValue -> ClrValue<T> -> already in restriction */) { // ((DObject)target).RealType == <obj>.RealType restrictions = restrictions.Merge( BindingRestrictions.GetInstanceRestriction( Expression.Property(Expression.Convert(target.Expression, Types.DObject[0]), Properties.DObject_RealType), obj.RealType)); } //// return GetObjectProperty(obj, name, caller, quiet); DPropertyDesc property; GetMemberResult result = obj.TypeDesc.GetInstanceProperty(new VariableName(fieldName), classContext, out property); switch (result) { case GetMemberResult.OK: ////object value = property.Get(this); ////PhpReference reference = value as PhpReference; if (property.Member is PhpField || property.Member is PhpVisibleProperty) { var realType = property.DeclaringType.RealType; FieldInfo realField = (property.Member is PhpField) ? property.PhpField.RealField : null; PropertyInfo realProperty = (property.Member is PhpVisibleProperty) ? ((PhpVisibleProperty)property.Member).RealProperty : null; Debug.Assert(realField != null ^ realProperty != null); MemberExpression getter = null; if (realField != null) { getter = Expression.Field(Expression.Convert(target.Expression, realType), realField); } else if (realProperty != null) { getter = Expression.Property(Expression.Convert(target.Expression, realType), realProperty); } if (Types.PhpReference[0].IsAssignableFrom(getter.Type)) { var reference = Expression.Variable(Types.PhpReference[0]); var assignment = Expression.Assign(reference, getter); if (WantReference) { ////value = property.Get(this); ////reference = value as PhpReference; var returnLabel = Expression.Label(this._returnType); ////if (reference != null && reference.IsSet) ////{ //// reference.IsAliased = true; //// return reference; ////} var isset = Expression.IfThen( Expression.Property(assignment, Properties.PhpReference_IsSet), Expression.Block( Expression.Assign(Expression.Property(reference, Properties.PhpReference_IsAliased), Expression.Constant(true)), Expression.Return(returnLabel, reference))); ////// the CT property has been unset -> try to invoke __get ////PhpReference get_ref = InvokeGetterRef(name, caller, out getter_exists); ////if (getter_exists) return (get_ref == null ? new PhpReference() : get_ref); ////if (reference == null) ////{ //// reference = new PhpReference(value); //// property.Set(this, reference); ////} ////else ////{ //// reference.IsAliased = true; //// reference.IsSet = true; ////} Func <DObject, string, DTypeDesc, PhpReference, PhpReference> notsetOperation = (self, name, caller, refrnc) => { bool getter_exists; // the CT property has been unset -> try to invoke __get PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) { return(get_ref ?? new PhpReference()); } Debug.Assert(refrnc != null); refrnc.IsAliased = true; refrnc.IsSet = true; return(refrnc); }; ////return reference; return(new DynamicMetaObject( Expression.Block(this._returnType, new[] { reference }, new Expression[] { isset, Expression.Label(returnLabel, Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]), reference)) }), restrictions)); } else { ////if (reference != null && !reference.IsSet) ////{ //// // the property is CT but has been unset //// if (issetSemantics) //// { //// bool handled; //// return PropertyIssetHandler(name, caller, out handled); //// } //// else return GetRuntimeField(name, caller); ////} ////else return value; Func <DObject, string, DTypeDesc, object> notsetOperation; if (_issetSemantics) { notsetOperation = (self, name, caller) => { return(PhpVariable.Dereference(self.GetRuntimeField(name, caller))); } } ; else { notsetOperation = (self, name, caller) => { bool handled; return(PhpVariable.Dereference(self.PropertyIssetHandler(name, caller, out handled))); } }; var value = Expression.Block(this._returnType, new[] { reference }, Expression.Condition( Expression.Property(assignment, Properties.PhpReference_IsSet), Expression.Field(reference, Fields.PhpReference_Value), Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])) )); return(new DynamicMetaObject(value, restrictions)); } } else { if (WantReference) { return(new DynamicMetaObject( Expression.New(Constructors.PhpReference_Object, Expression.Convert(getter, Types.Object[0])), restrictions)); } else { return(new DynamicMetaObject( Expression.Call(Methods.PhpVariable.Dereference, Expression.Convert(getter, Types.Object[0])), restrictions)); } } } else if (property.Member is ClrProperty) { var realType = property.DeclaringType.RealType; var realProperty = property.ClrProperty.RealProperty; // (target.{RealObject|realValue}).<realProperty> Expression value = Expression.Convert( BinderHelper.ClrObjectWrapDynamic( Expression.Property( BinderHelper.ClrRealObject(target, realType), realProperty)), Types.Object[0]); if (WantReference) { value = BinderHelper.MakePhpReference(value); } return(new DynamicMetaObject(value, restrictions)); } else if (property.Member is ClrField) { var realType = property.DeclaringType.RealType; var realField = property.ClrField.FieldInfo; // (target.{RealObject|realValue}).<realField> Expression value = Expression.Convert( BinderHelper.ClrObjectWrapDynamic( Expression.Field( BinderHelper.ClrRealObject(target, realType), realField)), Types.Object[0]); if (WantReference) { value = BinderHelper.MakePhpReference(value); } return(new DynamicMetaObject(value, restrictions)); } else if (property.Member is ClrEvent) { var clrEvent = (ClrEvent)property.Member; var realType = property.DeclaringType.RealType; // emit stub that Wraps event as [ ClrEventObject<handlerType>.Wrap(<SC>, <event name>, <addMethod>, <removeMethod>) ] var stub = new System.Reflection.Emit.DynamicMethod( string.Format("event<{0}>", fieldName), Types.DObject[0], new[] { realType }, realType); var il = new ILEmitter(stub); clrEvent.EmitGetEventObject( il, new Place(null, Properties.ScriptContext_CurrentContext), new IndexedPlace(PlaceHolder.Argument, 0), false); il.Emit(System.Reflection.Emit.OpCodes.Ret); Expression value = Expression.Call(stub, BinderHelper.ClrRealObject(target, realType)); if (WantReference) { value = BinderHelper.MakePhpReference(value); } return(new DynamicMetaObject(value, restrictions)); } else { throw new NotImplementedException(); } case GetMemberResult.NotFound: if (WantReference) { Func <DObject, string, DTypeDesc, PhpReference> op = (self, name, caller) => { PhpReference reference; bool getter_exists; // search in RT fields if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name)) { var namekey = new IntStringKey(name); return(self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields)); } // property is not present -> try to invoke __get reference = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) { return((reference == null) ? new PhpReference() : reference); } // (no notice/warning/error thrown by PHP) // add the field reference = new PhpReference(); if (self.RuntimeFields == null) { self.RuntimeFields = new PhpArray(); } self.RuntimeFields[name] = reference; return(reference); }; return(new DynamicMetaObject( Expression.Call(null, op.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])), restrictions)); } else { ////if (issetSemantics) ////{ //// OrderedHashtable<string>.Element element; //// if (RuntimeFields != null && (element = RuntimeFields.GetElement(name)) != null) //// { //// return element.Value; //// } //// else //// { //// bool handled; //// return PropertyIssetHandler(name, caller, out handled); //// } ////} ////else return GetRuntimeField(name, caller); if (_issetSemantics) { Func <DObject, string, DTypeDesc, object> notsetOperation = (self, name, caller) => { if (self.RuntimeFields != null) { object value; if (self.RuntimeFields.TryGetValue(name, out value)) { return(value); } } bool handled; return(self.PropertyIssetHandler(name, caller, out handled)); }; return(new DynamicMetaObject( Expression.Call(Methods.PhpVariable.Dereference, Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))), restrictions)); } else { return(new DynamicMetaObject( Expression.Call( Methods.PhpVariable.Dereference, Expression.Call( Expression.Convert(target.Expression, Types.DObject[0]), Methods.DObject_GetRuntimeField, Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))), restrictions)); }; } case GetMemberResult.BadVisibility: { ////PhpException.PropertyNotAccessible( //// property.DeclaringType.MakeFullName(), //// name.ToString(), //// (caller == null ? String.Empty : caller.MakeFullName()), //// property.IsProtected); string stringResourceKey = property.IsProtected ? "protected_property_accessed" : "private_property_accessed"; return(new DynamicMetaObject( Expression.Block(this._returnType, Expression.Call(null, Methods.PhpException.Throw, Expression.Constant(PhpError.Error, Types.PhpError_String[0]), Expression.Constant(CoreResources.GetString(stringResourceKey, property.DeclaringType.MakeFullName(), fieldName, (classContext == null ? String.Empty : classContext.MakeFullName())))), WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null) ), restrictions)); } } } ////// warnings: ////if (!quiet) // not in isset() operator only ////{ if (!_issetSemantics) { //// if (PhpVariable.IsEmpty(var)) //// // empty: //// PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object")); //// else //// // PhpArray, string, scalar type: //// PhpException.VariableMisusedAsObject(var, false); Action <object> error = (var) => { if (PhpVariable.IsEmpty(var)) { // empty: PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object")); } else { // PhpArray, string, scalar type: PhpException.VariableMisusedAsObject(var, false); } }; return(new DynamicMetaObject( Expression.Block(this._returnType, Expression.Call(error.Method, target.Expression), WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)), (target.HasValue && target.Value == null) ? BindingRestrictions.GetInstanceRestriction(target.Expression, null) : BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))); } ////} ////// property does not exist ////return null; return(new DynamicMetaObject( Expression.Constant(null), (target.HasValue && target.Value == null) ? BindingRestrictions.GetInstanceRestriction(target.Expression, null) : BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType))); }
public static int ParseIntoStruct(NamingContext /*!*/ namingContext, DTypeDesc caller, PhpResource parser, string data, PhpReference values, PhpReference index) { if (values == null) { PhpException.Throw(PhpError.Warning, "values argument should not be null"); return(0); } values.Value = new PhpArray(); if (index != null) { index.Value = new PhpArray(); } XmlParserResource xmlParser = parser as XmlParserResource; if (xmlParser != null) { return(xmlParser.ParseIntoStruct(caller, namingContext, data, (PhpArray)values.Value, index != null ? (PhpArray)index.Value : null) ? 1 : 0); } PhpException.Throw(PhpError.Warning, "parser argument should contain valid XML parser"); return(0); }
private static PhpArray getimagesize(Stream stream, PhpReference imageinfo) { PhpArray exif; PhpArray result = GetImageSize(stream, imageinfo != null, out exif); if (imageinfo != null) imageinfo.value = exif ?? new PhpArray(); return result; }
public static object Reduce(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpArray array, PhpCallback function, [PhpDeepCopy] object initialValue) { if (array == null) { PhpException.ReferenceNull("array"); return null; } if (!PhpArgument.CheckCallback(function, caller, "function", 0, false)) return null; if (array.Count == 0) return initialValue; object[] args = new object[] { initialValue, null }; PhpReference holder = new PhpReference(); foreach (KeyValuePair<IntStringKey, object> entry in array) { object item = entry.Value; PhpReference ref_item = item as PhpReference; // array item is a reference: if (ref_item != null) { args[1] = item; args[0] = function.Invoke(args); } else { // array item is not a reference: holder.Value = item; args[1] = holder; args[0] = function.Invoke(args); // updates an item if it has been changed: if (item != holder.Value) array[entry.Key] = holder.Value; } } // dereferences the last returned value: return PhpVariable.Dereference(args[0]); }
private static void WriteAutoGlobal(TextWriter output, ScriptContext context, string name, PhpReference autoglobal) { PhpArray array; if ((array = autoglobal.Value as PhpArray) != null) { foreach (KeyValuePair<IntStringKey, object> entry in array) HtmlVarRow(output, name, entry.Key.Object, entry.Value); } }
/// <summary> /// Start listing of a directory (intended to be used from C#). /// </summary> /// <param name="directory">The path to the directory.</param> public Directory(string directory) : this(ScriptContext.CurrentContext, true) { this.path = new PhpReference(directory); this.handle = new PhpReference(PhpDirectory.Open(directory)); }