/// <summary> /// Adds a variable to auto-global array. /// </summary> /// <param name="array">The array.</param> /// <param name="name">A unparsed name of variable.</param> /// <param name="value">A value to be added.</param> /// <param name="subname">A name of intermediate array inserted before the value.</param> private static void AddVariable( PhpArray/*!*/ array, string name, object value, string subname) { if (array == null) throw new ArgumentNullException("array"); if (name == null) name = String.Empty; string key; // current left and right square brace positions: int left, right; // checks pattern {var_name}[{key1}][{key2}]...[{keyn}] where var_name is [^[]* and keys are [^]]*: left = name.IndexOf('['); if (left > 0 && left < name.Length - 1 && (right = name.IndexOf(']', left + 1)) >= 0) { // the variable name is a key to the "array", dots are replaced by underscores in top-level name: key = EncodeTopLevelName(name.Substring(0, left)); // ensures that all [] operators in the chain except for the last one are applied on an array: for (;;) { // adds a level keyed by "key": array = Operators.EnsureItemIsArraySimple(array, key); // adds a level keyed by "subname" (once only): if (subname != null) { array = Operators.EnsureItemIsArraySimple(array, subname); subname = null; } // next key: key = name.Substring(left + 1, right - left - 1); // breaks if ']' is not followed by '[': left = right + 1; if (left == name.Length || name[left] != '[') break; // the next right brace: right = name.IndexOf(']', left + 1); } if (key.Length > 0) array.SetArrayItem(key, value); else array.Add(value); } else { // no array pattern in variable name, "name" is a top-level key: name = EncodeTopLevelName(name); // inserts a subname on the next level: if (subname != null) Operators.EnsureItemIsArraySimple(array, name)[subname] = value; else array[name] = value; } }
private static void SetItemEpilogue(object value, object key, ref object var) { // empty: if (IsEmptyForEnsure(var)) { PhpArray var_array = new PhpArray(0, 1); var_array.SetArrayItem(key, value); var = var_array; return; } // PhpArray (derived types): PhpArray array; if ((array = var as PhpArray) != null) { array.SetArrayItem(key, value); return; } // object behaving as array: DObject dobj = var as DObject; if (dobj != null) { var realObject = dobj.RealObject; if (realObject is Library.SPL.ArrayAccess) { //PhpStack stack = ScriptContext.CurrentContext.Stack; //stack.AddFrame(key, value); //dobj.InvokeMethod(Library.SPL.PhpArrayObject.offsetSet, null, stack.Context); ((Library.SPL.ArrayAccess)realObject).offsetSet(ScriptContext.CurrentContext, key, value); return; } if (realObject is IList) { ((IList)realObject)[Convert.ObjectToInteger(key)] = value; return; } if (realObject is IDictionary) { ((IDictionary)realObject)[key] = value; return; } } // errors - DObject, scalars: PhpException.VariableMisusedAsArray(var, false); }
/// <remarks> /// The following code has been taken from PHP View Engine. /// http://phpviewengine.codeplex.com/license /// </remarks> private object PhpSafeType(object o) { // PHP can handle bool, int, double, and long if ((o is int) || (o is double) || (o is long) || (o is bool)) { return o; } // Upcast other integer types so PHP can use them // TODO: What to do about System.UInt64 and byte? else if (o is short) { return (int)(short)o; } else if (o is ushort) { return (int)(ushort)o; } else if (o is uint) { return (long)(uint)o; } else if (o is ulong) { ulong u = (ulong)o; if (u <= Int64.MaxValue) { return System.Convert.ToInt64(u); } else { return u.ToString(); } } // Convert System.Single to a string // to reduce rounding errors // TODO: Figure out why I need to do this else if (o is float) { return Double.Parse(o.ToString()); } // Really not sure what the best thing is to do with 'System.Decimal' // TODO: Review this decision else if (o is decimal) { return o.ToString(); } // Strings and byte arrays require special handling else if (o is string) { return new PhpString((string)o); } else if (o is byte[]) { return new PhpBytes((byte[])o); } // Convert .NET collections into PHP arrays else if (o is ICollection) { var ca = new PhpArray(); if (o is IDictionary) { var dict = o as IDictionary; foreach (var key in dict.Keys) { var val = PhpSafeType(dict[key]); ca.SetArrayItem(PhpSafeType(key), val); } } else { foreach (var item in (ICollection)o) { ca.Add(PhpSafeType(item)); } } return ca; } // PHP types are obviously ok and can just move along if (o is DObject) { return o; } // Wrap all remaining CLR types so that PHP can handle tham return ClrObject.WrapRealObject(o); }