예제 #1
0
		/// <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;
			}
		}
예제 #2
0
        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);
        }