/// <summary> /// Resolves path according to PHP semantics, lookups the file in runtime tables and calls its Main method. /// </summary> /// <param name="cd">Current script directory. Used for relative path resolution. Can be <c>null</c> to not resolve against current directory.</param> /// <param name="path">The relative or absolute path to resolve and include.</param> /// <param name="locals">Variables scope for the included script.</param> /// <param name="this">Reference to <c>this</c> variable.</param> /// <param name="self">Reference to current class context.</param> /// <param name="once">Whether to include according to include once semantics.</param> /// <param name="throwOnError">Whether to include according to require semantics.</param> /// <returns>Inclusion result value.</returns> public PhpValue Include(string cd, string path, PhpArray locals, object @this = null, RuntimeTypeHandle self = default(RuntimeTypeHandle), bool once = false, bool throwOnError = false) { var script = ScriptsMap.ResolveInclude(path, RootPath, IncludePaths, WorkingDirectory, cd); if (script.IsValid) { if (once && _scripts.IsIncluded(script.Index)) { return(PhpValue.Create(true)); } else { return(script.Evaluate(this, locals, @this, self)); } } else { if (TryIncludeFileContent(path)) // include non-compiled file (we do not allow dynamic compilation yet) { return(PhpValue.Null); } else { var cause = string.Format(Resources.ErrResources.script_not_found, path); PhpException.Throw( throwOnError ? PhpError.Error : PhpError.Notice, Resources.ErrResources.script_inclusion_failed, path, cause, string.Join(";", IncludePaths), cd); if (throwOnError) { throw new ArgumentException(cause); } return(PhpValue.False); } } }
/// <summary> /// Resolves path according to PHP semantics, lookups the file in runtime tables and calls its Main method. /// </summary> /// <param name="cd">Current script directory. Used for relative path resolution. Can be <c>null</c> to not resolve against current directory.</param> /// <param name="path">The relative or absolute path to resolve and include.</param> /// <param name="locals">Variables scope for the included script.</param> /// <param name="this">Reference to <c>this</c> variable.</param> /// <param name="once">Whether to include according to include once semantics.</param> /// <param name="throwOnError">Whether to include according to require semantics.</param> /// <returns>Inclusion result value.</returns> public PhpValue Include(string cd, string path, PhpArray locals, object @this = null, bool once = false, bool throwOnError = false) { ScriptInfo script; path = path.Replace('/', '\\'); // normalize slashes if (path.StartsWith(this.RootPath, StringComparison.Ordinal)) // rooted { script = _scripts.GetScript(path.Substring(this.RootPath.Length)); } else { script = ScriptsMap.SearchForIncludedFile(path, IncludePaths, cd, _scripts.GetScript); } if (script.IsValid) { if (once && _scripts.IsIncluded(script.Index)) { return(PhpValue.Create(true)); } else { return(script.MainMethod(this, locals, @this)); } } else { if (throwOnError) { throw new ArgumentException($"File '{path}' cannot be included with current configuration."); // TODO: ErrCode } else { return(PhpValue.Create(false)); // TODO: Warning } } }
public bool IsEmpty() => /*this == default;*/ _long == 0L; // => _double == 0 public stdClass ToObject() => new stdClass(PhpValue.Create(this));
public PhpValue ToPhpValue() => IsLong?PhpValue.Create(_long) : PhpValue.Create(_double);
} // TODO: Err public override PhpValue DeepCopy(ref PhpValue me) => PhpValue.Create(me.WritableString.DeepCopy());
public override PhpValue ToPhpValue() => PhpValue.Create(new PhpArray(2) { _item1, _item2 });
public override PhpValue ToPhpValue() => PhpValue.Create(_function);
public object ToClass() { return(new stdClass(PhpValue.Create(ToString()))); }
public static stdClass ToObject(PhpString value) => new stdClass(PhpValue.Create(value.DeepCopy()));
public ScriptDiedException() : this(PhpValue.Create(255)) { }
public ScriptDiedException(long status) : this(PhpValue.Create(status)) { }
public override PhpValue ToPhpValue() => PhpValue.Create(new PhpArray(2) { _obj, _method });
public void SetItemAlias(PhpValue index, PhpAlias alias) => _array.offsetSet(index, PhpValue.Create(alias));
/// <summary> /// Gets value at given index. /// Gets <c>void</c> value in case the key is not found. /// </summary> PhpValue IPhpArray.GetItemValue(IntStringKey key) { int index = key.IsInteger ? key.Integer : (int)Convert.StringToLongInteger(key.String); return((index >= 0 && index < this.Length) ? this[index].AsValue() : PhpValue.Create(string.Empty)); }
/// <summary> /// Wraps the string into <see cref="PhpValue"/>. /// </summary> public PhpValue AsPhpValue(PhpString str) => str.IsEmpty ? PhpValue.Create(string.Empty) : PhpValue.Create(str._blob);
public object ToClass() { return(new stdClass(PhpValue.Create(this))); }
public PhpArray ToArray() => PhpArray.New(PhpValue.Create(this));
public PhpAlias EnsureItemAlias(IntStringKey key) { return(_array.offsetGet(PhpValue.Create(key)).EnsureAlias()); }
/// <summary> /// Flushes data on current level of buffering to the sinks or to the previous level. /// The current level clean up MUST follow this method's call. /// </summary> internal void InternalFlush() { Debug.Assert(_level != null); if (_level.filter == null) { if (_level.Index == 0) { // TODO: PhpString buffers // NOTE: avoid calling non-async on ASP.NET Core 3.0; consider changing to async // writes top-level data to sinks: for (int i = 0; i < _level.buffers.Count; i++) { var element = _level.buffers[i]; if (element.data is char[] chars) { _charSink.Write(chars, 0, element.size); } else { _byteSink .WriteAsync((byte[])element.data, 0, element.size) .GetAwaiter() .GetResult(); } } } else { // joins levels (data are not copied => the current level MUST be cleaned up after the return from this method): if (_level.size > 0) { var lower_level = _levels[_level.Index - 1]; lower_level.buffers.AddRange(_level.buffers); lower_level.size += _level.size; lower_level.freeSpace = _level.freeSpace; // free space in the last buffer of the level lower_level.containsByteData |= _level.containsByteData; lower_level.containsCharData |= _level.containsCharData; } } } else { // gets data from user's callback: var data = _level.filter.Invoke(_ctx, GetContent(), PhpValue.Create((int)(ChunkPosition.First | ChunkPosition.Middle | ChunkPosition.Last))); if (!data.IsEmpty) { var bytes = data.AsBytesOrNull(_ctx); // writes data to the current level of buffering or to sinks depending on the level count: if (_level.Index == 0) { // checks whether the filtered data are binary at first; if not so, converts them to a string: if (bytes != null) { _byteSink.Write(bytes); } else { // TODO: PhpString containing both string and byte[] _charSink.Write(data.ToString(_ctx)); } } else { // temporarily decreases the level of buffering toredirect writes to the lower level: var old_level = _level; _level = _levels[_level.Index - 1]; // checks whether the filtered data are binary at first; if not so, converts them to a string: if (bytes != null) { Stream.Write(bytes); } else { // TODO: PhpString containing both string and byte[] this.Write(data.ToString(_ctx)); } // restore the level of buffering: _level = old_level; } } } }
public IPhpArray EnsureItemArray(IntStringKey key) { return(_array.offsetGet(PhpValue.Create(key)).EnsureArray()); }
public PhpArray ToArray() => PhpArray.New(PhpValue.Create(this.DeepCopy()));
public object EnsureItemObject(IntStringKey key) { return(_array.offsetGet(PhpValue.Create(key)).EnsureObject()); }
public override PhpValue ToPhpValue() => PhpValue.Create(new PhpArray(2) { (PhpValue)_class, (PhpValue)_method });
public PhpValue GetItemValue(IntStringKey key) { return(_array.offsetGet(PhpValue.Create(key))); }
public override PhpValue GetArrayItem(ref PhpValue me, PhpValue index, bool quiet) => PhpValue.Create(Operators.GetItemValue(me.String, index, quiet));
public void RemoveKey(IntStringKey key) { _array.offsetUnset(PhpValue.Create(key)); }
public override PhpValue DeepCopy(ref PhpValue me) => PhpValue.Create(me.Array.DeepCopy());
public void SetItemAlias(IntStringKey key, PhpAlias alias) { _array.offsetSet(PhpValue.Create(key), PhpValue.Create(alias)); }
public void SetItemAlias(IntStringKey key, PhpAlias alias) { this.EnsureWritable(); table._add_or_update(ref key, PhpValue.Create(alias)); this.KeyAdded(ref key); }
public void SetItemValue(IntStringKey key, PhpValue value) { _array.offsetSet(PhpValue.Create(key), value); }