/// <summary> /// Associate data to an object in the storage. /// </summary> public virtual void offsetSet(PhpValue offset, PhpValue value = default(PhpValue)) { var obj = offset.AsObject(); if (obj != null) { Keys.AttachImpl(storage, obj, value); } else { throw new ArgumentException(nameof(offset)); } }
public virtual void __unserialize(PhpArray array) { var flattenedStorage = array.TryGetValue(0, out var storageVal) && storageVal.IsPhpArray(out var storageArray) ? storageArray : throw new InvalidDataException(); var e = flattenedStorage.GetFastEnumerator(); while (e.MoveNext()) { var key = e.CurrentValue.IsObject ? e.CurrentValue.Object : throw new InvalidDataException(); if (!e.MoveNext()) { throw new InvalidDataException(); } var val = e.CurrentValue; Keys.AttachImpl(storage, key, val); } __peach__runtimeFields = array.TryGetValue(1, out var propsVal) && propsVal.IsPhpArray(out var propsArray) ? propsArray : throw new InvalidDataException(); }
/// <summary> /// Adds an object inside the storage, and optionally associate it to some data. /// </summary> public virtual void attach(object @object, PhpValue data = default(PhpValue)) => Keys.AttachImpl(storage, @object, data);
/// <summary> /// Unserializes storage entries and attach them to the current storage. /// </summary> public virtual void unserialize(PhpString serialized) { // x:{count_int};{item0},{value0};...;m:{members_array} if (serialized.Length < 12) { throw new ArgumentException(nameof(serialized)); // quick check } var stream = new MemoryStream(serialized.ToBytes(_ctx)); try { PhpValue tmp; var reader = new PhpSerialization.PhpSerializer.ObjectReader(_ctx, stream, default(RuntimeTypeHandle)); // x: if (stream.ReadByte() != 'x' || stream.ReadByte() != ':') { throw new InvalidDataException(); } // i:{count}; tmp = reader.Deserialize(); if (tmp.TypeCode != PhpTypeCode.Long) { throw new InvalidDataException(); } var count = tmp.ToLong(); if (count < 0) { throw new InvalidDataException(nameof(count)); } stream.Seek(-1, SeekOrigin.Current); // back to `;` // {item},{value} while (count-- > 0) { // ;obj if (stream.ReadByte() != ';') { throw new InvalidDataException(); } var obj = reader.Deserialize(); // ,data PhpValue data; if (stream.ReadByte() == ',') { data = reader.Deserialize(); } else { // backward compatibility with data created with old PHP SplObjectStorage data = PhpValue.Void; stream.Seek(-1, SeekOrigin.Current); // back to `;` } // Keys.AttachImpl(storage, obj.AsObject(), data); } // ; if (stream.ReadByte() != ';') { throw new InvalidDataException(); } // m:{array} if (stream.ReadByte() != 'm' || stream.ReadByte() != ':') { throw new InvalidDataException(); } tmp = reader.Deserialize(); if (tmp.IsArray) { var arr = tmp.AsArray(); if (arr != null && arr.Count != 0) // do not leak empty arrays { __peach__runtimeFields = arr; } } else { throw new InvalidDataException(); } } catch (Exception e) { PhpException.Throw(PhpError.Notice, Resources.LibResources.deserialization_failed, e.Message, stream.Position.ToString(), stream.Length.ToString()); } }