/// <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; }
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; }
/// <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; }
/// <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 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; }
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()); }
/// <summary> /// Lazy copy construction. /// </summary> /// <param name="phps"></param> private PhpString(PhpString phps) { this.cow = phps.cow.Share(); }
/// <summary> /// Lazy copy construction. /// </summary> /// <param name="phps"></param> private PhpString(PhpString phps) { this.cow = phps.cow.Share(); }