Ejemplo n.º 1
0
        /// <summary>
        /// Wraps <c>null</c>, <see cref="string"/>, <see cref="PhpString"/>, <see cref="PhpBytes"/>, <c>EmptyForEnsure</c> and others into an instance assignable to <see cref="PhpArray"/>.
        /// </summary>
        /// <param name="obj">An object which has to be accessed as <see cref="PhpArray"/>.</param>
        /// <param name="convertedobj">In case <paramref name="obj"/> was converted (upgraded, e.g. from read-only to read/write), contains an instance of new object.
        /// Can be <c>null</c> reference if <paramref name="obj"/> was not changed.</param>
        /// <remarks>Note <c>null</c> reference is converted to new instance of <see cref="PhpArray"/>.</remarks>
        public static PhpArray EnsureObjectIsArray(object obj, out object convertedobj)
        {
            convertedobj = null;

            // PhpArray instance already:
            PhpArray arrayobj;
            if ((arrayobj = obj as PhpArray) != null)
                return arrayobj;

            // empty variable:
            if (IsEmptyForEnsure(obj))
            {
                PhpArray tmparray = new PhpArray();
                convertedobj = tmparray;
                return tmparray;
            }

            // ensure for optimizations below:
            Debug.Assert(typeof(PhpString).IsSealed);
            Debug.Assert(typeof(PhpBytes).IsSealed);

            // non-empty immutable string:
            if (obj.GetType() == typeof(string)) return new PhpArrayString(convertedobj = new PhpString((string)obj));

            // non-empty mutable string:
            if (obj.GetType() == typeof(PhpString)) return new PhpArrayString((PhpString)obj);
            if (obj.GetType() == typeof(PhpBytes)) return new PhpArrayString((PhpBytes)obj);

            // checks an object behaving like an array:
            DObject dobj;
            if ((dobj = obj as DObject) != null)
            {
                var realObject = dobj.RealObject;
                if (realObject is Library.SPL.ArrayAccess)
                    return new Library.SPL.PhpArrayObject(dobj);

                // TODO: IList, IDictionary
                if (realObject is IList)
                    throw new NotImplementedException();

                if (realObject is IDictionary)
                    throw new NotImplementedException();
            }

            // obj cannot be accessed as an array:
            return null;
        }
Ejemplo n.º 2
0
        public static PhpArray EnsureStaticPropertyIsArray(DTypeDesc type, object propertyName, DTypeDesc caller,
            ScriptContext context)
        {
            DPropertyDesc property = GetStaticPropertyDesc(type, propertyName, caller, context, false);
            if (property == null) return null;

            object property_value = property.Get(null);
            PhpReference property_value_ref = PhpVariable.Dereference(ref property_value);

            // array:
            PhpArray result = property_value as PhpArray;
            if (result != null) return result;

            // empty value:
            if (IsEmptyForEnsure(property_value))
            {
                result = new PhpArray();
                if (property_value_ref != null) property_value_ref.Value = result;
                else property.Set(null, result);

                return result;
            }

            // non-empty immutable string:
            string str_value = property_value as string;
            if (str_value != null)
            {
                PhpString php_str = new PhpString(str_value);
                if (property_value_ref != null) property_value_ref.Value = php_str;
                else property.Set(null, php_str);

                return new PhpArrayString(php_str);
            }

            // non-empty mutable string:
            if (property_value is PhpString || property_value is PhpBytes)
                return new PhpArrayString(property_value);

            // error - the property is a scalar or a DObject:
            PhpException.VariableMisusedAsArray(property_value, false);
            return null;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Implements oprators [],{} on a string.
        /// </summary>
        /// <param name="str">The string builder which character to set.</param>
        /// <param name="index">The index of an item.</param>
        /// <param name="value">The new value of an item.</param>
        /// <exception cref="PhpException"><paramref name="index"/> converted to integer by <see cref="Convert.ObjectToInteger"/> is negative. (Warning)</exception>
        /// <include file='Doc/Operators.xml' path='docs/operator[@name="SetStringItem"]/*'/>
        internal static PhpString/*!*/ SetStringItem(PhpString/*!*/ str, int index, object value)
        {
            Debug.Assert(str != null);

            // the new character will be the first character of the value converted to string or the '\0'
            // if the length of the converted value is zero; dereferencing is also done:
            char c = Convert.ObjectToChar(value);

            if (index >= str.Length)
            {
                // if index is greater than the string length the string is padded by spaces:
                str.Append(' ', index - str.Length);
                str.Append(c);
            }
            else
            {
                // otherwise, the respective character of the string is replaced by the new one:
                str.SetCharUnchecked(index, c);
            }

            return str;
        }
Ejemplo n.º 4
0
        /// <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;
        }
Ejemplo n.º 5
0
        public static PhpArray EnsureVariableIsArray(ref object var)
        {
            Debug.Assert(!(var is PhpReference));
            
            if (var != null && var.GetType() == typeof(PhpArray))
                return (PhpArray)var;

            if (IsEmptyForEnsure(var))
            {
                PhpArray tmparray;
                var = tmparray = new PhpArray();
                return tmparray;
            }

            // checks an object behaving like an array:
            DObject dobj = var as DObject;
            if (dobj != null && dobj.RealObject is Library.SPL.ArrayAccess)
                return new Library.SPL.PhpArrayObject(dobj);

            // immutable string:
            if (var.GetType() == typeof(string))
            {
                PhpString phps = new PhpString((string)var);
                var = phps;
                return new PhpArrayString(phps);
            }

            // mutable string:
            if (var.GetType() == typeof(PhpString) || var.GetType() == typeof(PhpBytes))
                return new PhpArrayString(var);

            // inherited PhpArray types:
            PhpArray array = var as PhpArray;
            if (array != null) return array;

            // warnings - variable is a DObject, a scalar:
            PhpException.VariableMisusedAsArray(var, false);
            return null;
        }
Ejemplo n.º 6
0
            internal static void GetObjectData(PhpString/*!*/instance, SerializationInfo info, StreamingContext context)
            {
                Debug.Assert(instance != null);
                Debug.Assert(info != null);

                info.SetType(typeof(SerializationHelper));
                info.AddValue(InfoValueName, instance.ToString());
            }
Ejemplo n.º 7
0
		/// <summary>
		/// Lazy copy construction.
		/// </summary>
		/// <param name="phps"></param>
		private PhpString(PhpString phps)
		{
			this.cow = phps.cow.Share();
		}
Ejemplo n.º 8
0
 /// <summary>
 /// Lazy copy construction.
 /// </summary>
 /// <param name="phps"></param>
 private PhpString(PhpString phps)
 {
     this.cow = phps.cow.Share();
 }