예제 #1
0
파일: DOMXPath.cs 프로젝트: hungud/peachpie
        /// <summary>
        /// Evaluates the given XPath expression and returns a typed result if possible.
        /// </summary>
        /// <param name="expr">The expression to evaluate.</param>
        /// <param name="contextnode">The context node for doing relative XPath queries. By default, the queries are
        /// relative to the root element.</param>
        /// <param name="registerNodeNS">Can be specified to disable automatic registration of the context node namespace.</param>
        /// <returns>A typed result if possible or a <see cref="DOMNodeList"/> containing all nodes matching the
        /// given <paramref name="expr"/>.</returns>
        public PhpValue evaluate(string expr, DOMNode contextnode = null, bool registerNodeNS = true)
        {
            XPathNavigator navigator = GetNavigator(contextnode);

            if (navigator == null)
            {
                return(PhpValue.Create(false));
            }

            var nsManager = registerNodeNS ? NamespaceManagerFull : NamespaceManagerExplicit;

            object result;

            try
            {
                result = navigator.Evaluate(expr, nsManager);
            }
            catch (Exception ex)
            {
                DOMException.Throw(ExceptionCode.SyntaxError, ex.Message);
                return(PhpValue.Create(false));
            }

            // the result can be bool, double, string, or iterator
            XPathNodeIterator iterator = result as XPathNodeIterator;

            if (iterator != null)
            {
                //return PhpValue.FromClass(IteratorToList(iterator));
                var domList = QueryInternal(contextnode?.XmlNode, expr, nsManager);
                return((domList == null) ? PhpValue.Create(false) : PhpValue.FromClass(domList));
            }
            else
            {
                return(PhpValue.FromClr(result));
            }
        }
예제 #2
0
        ref PhpValue Ensure(ref PhpValue value)
        {
            Debug.Assert(Next.Operation != RuntimeChainOperation.End);

            switch (Next.Operation)
            {
            case RuntimeChainOperation.Value:
                break;

            case RuntimeChainOperation.Property:
                value = PhpValue.FromClass(PhpValue.EnsureObject(ref value));
                break;

            case RuntimeChainOperation.ArrayItem:
                value = PhpValue.Create(PhpValue.EnsureArray(ref value));
                break;

            default:
                throw new InvalidOperationException();
            }

            //
            return(ref value);
        }
예제 #3
0
        public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext)
        {
            var receiver = PhpValue.EnsureObject(ref value);
            var t        = receiver.GetPhpTypeInfo();

            PhpValue tmp;

            if (BinderHelpers.TryResolveDeclaredProperty(t, classContext, false, Name, out var prop))
            {
                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(prop.EnsureObject(ctx, receiver));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(prop.EnsureArray(ctx, receiver));
                    break;

                case RuntimeChainOperation.End:
                    return(prop.EnsureAlias(ctx, receiver));

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureObject(key) : ( __get(key) ?? runtimeflds.EnsureObject(key))

                var runtimeFields = t.GetRuntimeFields(receiver);
                if (runtimeFields == null || !runtimeFields.Contains(Name))
                {
                    //
                    var __get = t.RuntimeMethods[TypeMethods.MagicMethods.__get];
                    if (__get != null)
                    {
                        // NOTE: magic methods must have public visibility, therefore the visibility check is unnecessary

                        // int subkey1 = access.Write() ? 1 : access.Unset() ? 2 : access.Isset() ? 3 : 4;
                        int subkey = Name.GetHashCode() ^ (1 << 4 /*subkey1*/);

                        using (var token = new Context.RecursionCheckToken(ctx, receiver, subkey))
                        {
                            if (!token.IsInRecursion)
                            {
                                tmp = __get.Invoke(ctx, receiver, Name);
                                return(Next.GetAlias(ref tmp, ctx, classContext));
                            }
                        }
                    }
                }

                if (runtimeFields == null)
                {
                    runtimeFields = t.EnsureRuntimeFields(receiver);
                }

                //

                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(runtimeFields.EnsureItemObject(Name));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(runtimeFields.EnsureItemArray(Name));
                    break;

                case RuntimeChainOperation.End:
                    return(runtimeFields.EnsureItemAlias(Name));

                default:
                    throw new InvalidOperationException();
                }
            }

            // chain:
            return(Next.GetAlias(ref tmp, ctx, classContext));
        }
예제 #4
0
 PhpValue Iterator.key() => PhpValue.Create(_element);
예제 #5
0
 PhpValue Iterator.key() => PhpValue.Create(_list[_element].localName);
        /// <summary>
        /// Adds a variable to auto-global array.
        /// Duplicit entries are collected into a sub-array item.
        /// The routine respects <c>[subkey]</c> notation to build a hierarchy of sub-arrays.
        /// </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>
        public static void AddVariable(this IPhpArray /*!*/ array, string name, string value, string subname = null)
        {
            Debug.Assert(array != null);
            Debug.Assert(name != null);
            Debug.Assert(value != null);

            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 = EnsureItemArray(array, key);

                    // adds a level keyed by "subname" (once only):
                    if (subname != null)
                    {
                        array   = EnsureItemArray(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 (string.IsNullOrEmpty(key))
                {
                    array.AddValue(PhpValue.Create(value));
                }
                else
                {
                    array.SetItemValue(new IntStringKey(key), PhpValue.Create(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)
                {
                    EnsureItemArray(array, name).SetItemValue(new IntStringKey(subname), PhpValue.Create(value));
                }
                else
                {
                    array.SetItemValue(new IntStringKey(name), PhpValue.Create(value));
                }
            }
        }
        public PhpValue getTypeClass(PhpValue typeName)
        {
            Type objectType = _codenames.Keys.FirstOrDefault(type => GetCodename(type).Equals(typeName.String));

            return(PhpValue.Create("\\" + objectType.FullName.Replace('.', '\\')));
        }
예제 #8
0
        /// <summary>
        /// Retrieves the length of the output buffer.
        /// </summary>
        /// <returns>The length of the contents in the output buffer or <B>false</B>, if output buffering isn't active.</returns>
        public static PhpValue ob_get_length(Context ctx)
        {
            var length = ctx.BufferedOutput.Length;

            return((length >= 0) ? PhpValue.Create(length) : PhpValue.False);
        }
예제 #9
0
 public bool write(string session_id, PhpString session_data) => (bool)_write.Invoke(_ctx, (PhpValue)session_id, PhpValue.Create(session_data));
예제 #10
0
        /// <inheritDoc />
        public PhpValue fetch(PDO.PDO_FETCH fetch_style = PDO.PDO_FETCH.FETCH_USE_DEFAULT, int cursor_orientation = default(int), int cursor_offet = 0)
        {
            this.m_pdo.ClearError();

            if (storedQueryResult != null)
            {
                return(FetchFromStored());
            }
            else
            {
                try
                {
                    PDO.PDO_FETCH style = this.m_fetchStyle;

                    if ((int)fetch_style != -1 && Enum.IsDefined(typeof(PDO.PDO_FETCH), fetch_style))
                    {
                        style = (PDO.PDO_FETCH)fetch_style;
                    }
                    PDO.PDO_FETCH_ORI ori = PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT;
                    if (Enum.IsDefined(typeof(PDO.PDO_FETCH_ORI), cursor_orientation))
                    {
                        ori = (PDO.PDO_FETCH_ORI)cursor_orientation;
                    }

                    switch (ori)
                    {
                    case PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT:
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    if (!this.m_dr.Read())
                    {
                        return(PhpValue.False);
                    }

                    // Get the column schema, if possible, for the associative fetch
                    if (this.m_dr_names == null)
                    {
                        this.m_dr_names = new string[m_dr.FieldCount];

                        if (this.m_dr.CanGetColumnSchema())
                        {
                            var columnSchema = this.m_dr.GetColumnSchema();

                            for (int i = 0; i < m_dr.FieldCount; i++)
                            {
                                this.m_dr_names[i] = columnSchema[i].ColumnName;
                            }
                        }
                        else
                        {
                            for (int i = 0; i < m_dr.FieldCount; i++)
                            {
                                this.m_dr_names[i] = this.m_dr.GetName(i);
                            }
                        }
                    }

                    switch (style)
                    {
                    case PDO.PDO_FETCH.FETCH_OBJ:
                        return(this.ReadObj());

                    case PDO.PDO_FETCH.FETCH_ASSOC:
                        return(PhpValue.Create(this.ReadArray(true, false)));

                    case PDO.PDO_FETCH.FETCH_BOTH:
                    case PDO.PDO_FETCH.FETCH_USE_DEFAULT:
                        return(PhpValue.Create(this.ReadArray(true, true)));

                    case PDO.PDO_FETCH.FETCH_NUM:
                        return(PhpValue.Create(this.ReadArray(false, true)));

                    case PDO.PDO_FETCH.FETCH_COLUMN:
                        if (FetchColNo != -1)
                        {
                            m_pdo.HandleError(new PDOException("The column number for FETCH_COLUMN mode is not set."));
                            return(PhpValue.False);
                        }

                        return(this.ReadArray(false, true)[FetchColNo].GetValue());

                    case PDO.PDO_FETCH.FETCH_CLASS:
                        if (FetchClassName == null)
                        {
                            m_pdo.HandleError(new PDOException("The className for FETCH_CLASS mode is not set."));
                            return(PhpValue.False);
                        }

                        var obj = _ctx.Create(FetchClassName, FetchClassCtorArgs ?? Array.Empty <PhpValue>());
                        return(PhpValue.FromClass(obj));

                    default:
                        throw new NotImplementedException();
                    }
                }
                catch (System.Exception ex)
                {
                    this.m_pdo.HandleError(ex);
                    return(PhpValue.False);
                }
            }
        }
예제 #11
0
        static PhpValue ProcessResponse(Context ctx, CURLResource ch, HttpWebResponse response)
        {
            // in case we are returning the response value
            var returnstream = ch.ProcessingResponse.Method == ProcessMethodEnum.RETURN
                ? new MemoryStream()
                : null;

            // handle headers
            if (!ch.ProcessingHeaders.IsEmpty)
            {
                switch (ch.ProcessingHeaders.Method)
                {
                case ProcessMethodEnum.RETURN:
                case ProcessMethodEnum.STDOUT:
                    (returnstream ?? ctx.OutputStream).Write(response.Headers.ToByteArray());
                    break;

                case ProcessMethodEnum.FILE:
                    ch.ProcessingHeaders.Stream.RawStream.Write(response.Headers.ToByteArray());
                    break;

                case ProcessMethodEnum.USER:
                    // pass headers one by one,
                    // in original implementation we should pass them as they are read from socket:

                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.StatusHeader(response) + HttpHeaders.HeaderSeparator)
                    });

                    for (int i = 0; i < response.Headers.Count; i++)
                    {
                        // header
                        ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(response.Headers[i] + HttpHeaders.HeaderSeparator),
                        });
                    }

                    // \r\n
                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.HeaderSeparator)
                    });

                    break;

                default:
                    Debug.Fail("Unexpected ProcessingHeaders " + ch.ProcessingHeaders.Method);
                    break;
                }
            }

            var stream = response.GetResponseStream();

            // read into output stream:
            switch (ch.ProcessingResponse.Method)
            {
            case ProcessMethodEnum.STDOUT: stream.CopyTo(ctx.OutputStream); break;

            case ProcessMethodEnum.RETURN: stream.CopyTo(returnstream); break;

            case ProcessMethodEnum.FILE: stream.CopyTo(ch.ProcessingResponse.Stream.RawStream); break;

            case ProcessMethodEnum.USER:
                if (response.ContentLength != 0)
                {
                    // preallocate a buffer to read to,
                    // this should be according to PHP's behavior and slightly more effective than memory stream
                    byte[] buffer = new byte[ch.BufferSize > 0 ? ch.BufferSize : 2048];
                    int    bufferread;

                    while ((bufferread = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ch.ProcessingResponse.User.Invoke(ctx, new[]
                        {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(new PhpString(buffer.AsSpan(0, bufferread).ToArray())),     // clone the array and pass to function
                        });
                    }
                }
                break;

            case ProcessMethodEnum.IGNORE: break;
            }

            //

            return((returnstream != null)
                ? PhpValue.Create(new PhpString(returnstream.ToArray()))
                : PhpValue.True);
        }
예제 #12
0
        /// <summary>
        /// Loads $_SERVER from <see cref="_httpctx"/>.
        /// </summary>
        protected override PhpArray InitServerVariable()
        {
            var array = new PhpArray(32);

            var request = _httpctx.Request;

            //// adds variables defined by ASP.NET and IIS:
            //var serverVariables = _httpctx.Features.Get<IServerVariablesFeature>()?.ServerVariables;
            //if (serverVariables != null)
            //{
            //    foreach (string name in serverVariables)
            //    {
            //        // gets all values associated with the name:
            //        string[] values = serverVariables.GetValues(name);

            //        if (values == null)
            //            continue;   // http://phalanger.codeplex.com/workitem/30132

            //        // adds all items:
            //        if (name != null)
            //        {
            //            foreach (string value in values)
            //                Superglobals.AddVariable(array, name, value, null);
            //        }
            //        else
            //        {
            //            // if name is null, only name of the variable is stated:
            //            // e.g. for GET variables, URL looks like this: ...&test&...
            //            // we add the name of the variable and an emtpy string to get what PHP gets:
            //            foreach (string value in values)
            //            {
            //                Superglobals.AddVariable(array, value, string.Empty, null);
            //            }
            //        }
            //    }
            //}

            //// adds argv, argc variables:
            //if (RegisterArgcArgv)
            //{
            //    array["argv"] = PhpValue.Create(new PhpArray(1) { request.QueryString });
            //    array["argc"] = PhpValue.Create(0);
            //}

            // variables defined in PHP manual
            // order as it is by builtin PHP server
            array["DOCUMENT_ROOT"] = (PhpValue)RootPath;    // string, backslashes, no trailing slash

            //var f_connection = _httpctx.Features.Get<IHttpConnectionFeature>();
            array["REMOTE_ADDR"]          = (PhpValue)_httpctx.Connection.RemoteIpAddress.ToString();
            array["REMOTE_PORT"]          = (PhpValue)_httpctx.Connection.RemotePort;
            array["LOCAL_ADDR"]           = array["SERVER_ADDR"] = (PhpValue)_httpctx.Connection.LocalIpAddress.ToString();
            array["LOCAL_PORT"]           = (PhpValue)_httpctx.Connection.LocalPort;
            array["SERVER_SOFTWARE"]      = (PhpValue)"ASP.NET Core Server";
            array["SERVER_PROTOCOL"]      = (PhpValue)request.Protocol;
            array["SERVER_NAME"]          = (PhpValue)request.Host.Host;
            array["SERVER_PORT"]          = (PhpValue)request.Host.Port;
            array["REQUEST_URI"]          = (PhpValue)(request.Path.Value + request.QueryString.Value);
            array["REQUEST_METHOD"]       = (PhpValue)request.Method;
            array["SCRIPT_NAME"]          = (PhpValue)request.Path.ToString();
            array["SCRIPT_FILENAME"]      = PhpValue.Null; // set in ProcessScript
            array["PHP_SELF"]             = PhpValue.Null; // set in ProcessScript
            array["QUERY_STRING"]         = (PhpValue)(request.QueryString.HasValue ? request.QueryString.Value.Substring(1) : string.Empty);
            array["HTTP_HOST"]            = (PhpValue)request.Headers["Host"].ToString();
            array["HTTP_CONNECTION"]      = (PhpValue)request.Headers["Connection"].ToString();
            array["HTTP_USER_AGENT"]      = (PhpValue)request.Headers["User-Agent"].ToString();
            array["HTTP_ACCEPT"]          = (PhpValue)request.Headers["Accept"].ToString();
            array["HTTP_ACCEPT_ENCODING"] = (PhpValue)request.Headers["Accept-Encoding"].ToString();
            array["HTTP_ACCEPT_LANGUAGE"] = (PhpValue)request.Headers["Accept-Language"].ToString();
            array["HTTP_REFERER"]         = (PhpValue)request.Headers["Referer"].ToString();
            //array["REQUEST_URI"] = (PhpValue)request.RawUrl;
            array["REQUEST_TIME_FLOAT"] = (PhpValue)DateTimeUtils.UtcToUnixTimeStampFloat(DateTime.UtcNow);
            array["REQUEST_TIME"]       = (PhpValue)DateTimeUtils.UtcToUnixTimeStamp(DateTime.UtcNow);
            array["HTTPS"] = PhpValue.Create(request.IsHttps);

            //
            return(array);
        }
예제 #13
0
        /// <inheritDoc />
        public PhpValue fetch(int fetch_style = -1, int cursor_orientation = default(int), int cursor_offet = 0)
        {
            this.m_pdo.ClearError();
            try
            {
                PDO.PDO_FETCH style = this.m_fetchStyle;

                if (fetch_style != -1 && Enum.IsDefined(typeof(PDO.PDO_FETCH), fetch_style))
                {
                    style = (PDO.PDO_FETCH)fetch_style;
                }
                PDO.PDO_FETCH_ORI ori = PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT;
                if (Enum.IsDefined(typeof(PDO.PDO_FETCH_ORI), cursor_orientation))
                {
                    ori = (PDO.PDO_FETCH_ORI)cursor_orientation;
                }

                switch (ori)
                {
                case PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT:
                    break;

                default:
                    throw new NotSupportedException();
                }

                if (!this.m_dr.Read())
                {
                    return(PhpValue.False);
                }

                // Get the column schema, if possible, for the associative fetch
                if (this.m_dr_names == null)
                {
                    this.m_dr_names = new string[m_dr.FieldCount];

                    if (this.m_dr.CanGetColumnSchema())
                    {
                        var columnSchema = this.m_dr.GetColumnSchema();

                        for (int i = 0; i < m_dr.FieldCount; i++)
                        {
                            this.m_dr_names[i] = columnSchema[i].ColumnName;
                        }
                    }
                }

                switch (style)
                {
                case PDO.PDO_FETCH.FETCH_OBJ:
                    return(this.ReadObj());

                case PDO.PDO_FETCH.FETCH_ASSOC:
                    return(PhpValue.Create(this.ReadArray(true, false)));

                case PDO.PDO_FETCH.FETCH_BOTH:
                case PDO.PDO_FETCH.FETCH_USE_DEFAULT:
                    return(PhpValue.Create(this.ReadArray(true, true)));

                case PDO.PDO_FETCH.FETCH_NUM:
                    return(PhpValue.Create(this.ReadArray(false, true)));

                case PDO.PDO_FETCH.FETCH_COLUMN:
                    return(this.ReadArray(false, true)[FetchColNo].GetValue());

                case PDO.PDO_FETCH.FETCH_CLASS:
                default:
                    throw new NotImplementedException();
                }
            }
            catch (System.Exception ex)
            {
                this.m_pdo.HandleError(ex);
                return(PhpValue.False);
            }
        }
예제 #14
0
        /// <summary>
        /// Get the known PDO drivers
        /// </summary>
        /// <returns></returns>
        public static PhpArray pdo_drivers()
        {
            var phpNames = PDOEngine.GetDriverNames().Select(d => PhpValue.Create(d)).ToArray();

            return(PhpArray.New(phpNames));
        }
예제 #15
0
 public override PhpValue ToPhpValue() => PhpValue.Create(SplAutoloadFunction);
예제 #16
0
        protected override void DoAction(int action)
        {
            switch (action)
            {
            case 2: // start -> value
            { Result = (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj; }
                return;

            case 3: // object -> OBJECT_OPEN members OBJECT_CLOSE
            {
                var elements = (List <KeyValuePair <string, PhpValue> >)value_stack.array[value_stack.top - 2].yyval.obj;
                var arr      = new PhpArray(elements.Count);

                foreach (var item in elements)
                {
                    arr.Add(Core.Convert.StringToArrayKey(item.Key), item.Value);
                }

                if (decodeOptions.Assoc)
                {
                    yyval.obj = PhpValue.Create(arr);
                }
                else
                {
                    yyval.obj = PhpValue.FromClass(arr.ToClass());
                }
            }
                return;

            case 4: // object -> OBJECT_OPEN OBJECT_CLOSE
            { yyval.obj = PhpValue.FromClass(new stdClass()); }
                return;

            case 5: // members -> pair ITEMS_SEPARATOR members
            {
                var elements = (List <KeyValuePair <string, PhpValue> >)value_stack.array[value_stack.top - 1].yyval.obj;
                var result   = new List <KeyValuePair <string, PhpValue> >(elements.Count + 1)
                {
                    (KeyValuePair <string, PhpValue>)value_stack.array[value_stack.top - 3].yyval.obj
                };
                result.AddRange(elements);
                yyval.obj = result;
            }
                return;

            case 6: // members -> pair
            { yyval.obj = new List <KeyValuePair <string, PhpValue> >()
              {
                  (KeyValuePair <string, PhpValue>)value_stack.array[value_stack.top - 1].yyval.obj
              }; }
                return;

            case 7: // pair -> STRING NAMEVALUE_SEPARATOR value
            { yyval.obj = new KeyValuePair <string, PhpValue>((string)value_stack.array[value_stack.top - 3].yyval.obj, (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 8: // array -> ARRAY_OPEN elements ARRAY_CLOSE
            {
                var elements = (List <PhpValue>)value_stack.array[value_stack.top - 2].yyval.obj;
                var arr      = new PhpArray(elements.Count);

                foreach (var item in elements)
                {
                    arr.Add(item);
                }

                yyval.obj = arr;
            }
                return;

            case 9: // array -> ARRAY_OPEN ARRAY_CLOSE
            { yyval.obj = PhpArray.NewEmpty(); }
                return;

            case 10: // elements -> value ITEMS_SEPARATOR elements
            {
                var elements = (List <PhpValue>)value_stack.array[value_stack.top - 1].yyval.obj;
                var result   = new List <PhpValue>(elements.Count + 1)
                {
                    (PhpValue)value_stack.array[value_stack.top - 3].yyval.obj
                };
                result.AddRange(elements);
                yyval.obj = result;
            }
                return;

            case 11: // elements -> value
            { yyval.obj = new List <PhpValue>()
              {
                  (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj
              }; }
                return;

            case 12: // value -> STRING
            { yyval.obj = PhpValue.Create((string)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 13: // value -> INTEGER
            { yyval.obj = PhpValue.FromClr(value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 14: // value -> DOUBLE
            { yyval.obj = PhpValue.FromClr(value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 15: // value -> object
            { yyval.obj = (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj; }
                return;

            case 16: // value -> array
            { yyval.obj = PhpValue.Create((PhpArray)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 17: // value -> TRUE
            { yyval.obj = PhpValue.True; }
                return;

            case 18: // value -> FALSE
            { yyval.obj = PhpValue.False; }
                return;

            case 19: // value -> NULL
            { yyval.obj = PhpValue.Null; }
                return;
            }
        }
예제 #17
0
 public virtual PhpValue key()
 {
     return(PhpValue.Create(_index));
 }
예제 #18
0
        static async Task <PhpValue> ProcessResponse(Context ctx, CURLResource ch, HttpWebResponse response)
        {
            // in case we are returning the response value
            var returnstream = ch.ProcessingResponse.Method == ProcessMethodEnum.RETURN
                ? new MemoryStream()
                : null;

            // handle headers
            if (!ch.ProcessingHeaders.IsEmpty)
            {
                var    statusHeaders       = HttpHeaders.StatusHeader(response) + HttpHeaders.HeaderSeparator; // HTTP/1.1 xxx xxx\r\n
                Stream outputHeadersStream = null;

                switch (ch.ProcessingHeaders.Method)
                {
                case ProcessMethodEnum.RETURN:
                case ProcessMethodEnum.STDOUT:
                    outputHeadersStream = (returnstream ?? ctx.OutputStream);
                    goto default;

                case ProcessMethodEnum.FILE:
                    outputHeadersStream = ch.ProcessingHeaders.Stream.RawStream;
                    goto default;

                case ProcessMethodEnum.USER:
                    // pass headers one by one,
                    // in original implementation we should pass them as they are read from socket:

                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClass(ch),
                        PhpValue.Create(statusHeaders)
                    });

                    for (int i = 0; i < response.Headers.Count; i++)
                    {
                        var key   = response.Headers.GetKey(i);
                        var value = response.Headers.Get(i);

                        if (key == null || key.Length != 0)
                        {
                            // header
                            ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                                PhpValue.FromClr(ch),
                                PhpValue.Create(key + ": " + value + HttpHeaders.HeaderSeparator),
                            });
                        }
                    }

                    // \r\n
                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.HeaderSeparator)
                    });

                    break;

                default:
                    if (outputHeadersStream != null)
                    {
                        await outputHeadersStream.WriteAsync(Encoding.ASCII.GetBytes(statusHeaders));

                        await outputHeadersStream.WriteAsync(response.Headers.ToByteArray());
                    }
                    else
                    {
                        Debug.Fail("Unexpected ProcessingHeaders " + ch.ProcessingHeaders.Method);
                    }
                    break;
                }
            }

            var stream = response.GetResponseStream();

            // gzip decode if necessary
            if (response.ContentEncoding == "gzip") // TODO: // && ch.AcceptEncoding.Contains("gzip") ??
            {
                ch.VerboseOutput("Decompressing the output stream using GZipStream.");
                stream = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: false);
            }

            // read into output stream:
            switch (ch.ProcessingResponse.Method)
            {
            case ProcessMethodEnum.STDOUT: await stream.CopyToAsync(ctx.OutputStream); break;

            case ProcessMethodEnum.RETURN: stream.CopyTo(returnstream); break;

            case ProcessMethodEnum.FILE: await stream.CopyToAsync(ch.ProcessingResponse.Stream.RawStream); break;

            case ProcessMethodEnum.USER:
                if (response.ContentLength != 0)
                {
                    // preallocate a buffer to read to,
                    // this should be according to PHP's behavior and slightly more effective than memory stream
                    byte[] buffer = new byte[ch.BufferSize > 0 ? ch.BufferSize : 2048];
                    int    bufferread;

                    while ((bufferread = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ch.ProcessingResponse.User.Invoke(ctx, new[]
                        {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(new PhpString(buffer.AsSpan(0, bufferread).ToArray())),     // clone the array and pass to function
                        });
                    }
                }
                break;

            case ProcessMethodEnum.IGNORE: break;
            }

            //
            stream.Dispose();
            stream = null;

            //

            return((returnstream != null)
                ? PhpValue.Create(new PhpString(returnstream.ToArray()))
                : PhpValue.True);
        }
예제 #19
0
            /// <summary>
            /// Creates expression representing value from [DefaultValueAttribute]
            /// </summary>
            protected Expression BindDefaultValue(DefaultValueAttribute /*!*/ attr)
            {
                Debug.Assert(attr != null);
                Debug.Assert(attr.Type == DefaultValueAttribute.DefaultValueType.PhpArray); // supported values

                if (attr.SerializedValue != null && attr.SerializedValue.Length != 0)
                {
                    // _ctx.Call(string "unserialize", PhpValue[] { SerializedValue });
                    return(Expression.Call(_ctx, "Call", Array.Empty <Type>(),
                                           Expression.Constant("unserialize"),
                                           Expression.NewArrayInit(Cache.Types.PhpValue, Expression.Constant(PhpValue.Create(attr.SerializedValue)))
                                           ));
                }
                else
                {
                    switch (attr.Type)
                    {
                    case DefaultValueAttribute.DefaultValueType.PhpArray:
                        return(Expression.Constant(PhpArray.Empty));    // will be deep-copied if needed

                    default:
                        throw new ArgumentException();
                    }
                }
            }
예제 #20
0
        /// <summary>
        /// Extracts part(s) from a specified path.
        /// </summary>
        /// <param name="path">The path to be parsed.</param>
        /// <param name="options">Flags determining the result.</param>
        /// <returns>
        /// If <paramref name="options"/> is <see cref="PathInfoOptions.All"/> then returns array
        /// keyed by <c>"dirname"</c>, <c>"basename"</c>, and <c>"extension"</c>. Otherwise,
        /// it returns string value containing a single part of the path.
        /// </returns>
        public static PhpValue pathinfo(string path, PathInfoOptions options = PathInfoOptions.All)
        {
            // collect strings
            string dirname = null, basename = null, extension = null, filename = null;

            if ((options & PathInfoOptions.BaseName) != 0 ||
                (options & PathInfoOptions.Extension) != 0 ||
                (options & PathInfoOptions.FileName) != 0)
            {
                basename = PhpPath.basename(path);
            }

            if ((options & PathInfoOptions.DirName) != 0)
            {
                dirname = PhpPath.dirname(path);
            }

            if ((options & PathInfoOptions.Extension) != 0)
            {
                int last_dot = basename.LastIndexOf('.');
                if (last_dot >= 0)
                {
                    extension = basename.Substring(last_dot + 1);
                }
            }

            if ((options & PathInfoOptions.FileName) != 0)
            {
                int last_dot = basename.LastIndexOf('.');
                if (last_dot >= 0)
                {
                    filename = basename.Substring(0, last_dot);
                }
                else
                {
                    filename = basename;
                }
            }

            // return requested value or all of them in an associative array
            if (options == PathInfoOptions.All)
            {
                var result = new PhpArray(4);
                result.Add("dirname", dirname);
                result.Add("basename", basename);
                result.Add("extension", extension);
                result.Add("filename", filename);
                return(PhpValue.Create(result));
            }

            if ((options & PathInfoOptions.DirName) != 0)
            {
                return(PhpValue.Create(dirname));
            }

            if ((options & PathInfoOptions.BaseName) != 0)
            {
                return(PhpValue.Create(basename));
            }

            if ((options & PathInfoOptions.Extension) != 0)
            {
                return(PhpValue.Create(extension));
            }

            if ((options & PathInfoOptions.FileName) != 0)
            {
                return(PhpValue.Create(filename));
            }

            return(PhpValue.Null);
        }
예제 #21
0
 /// <summary>
 /// Converts the character to a value.
 /// </summary>
 public PhpValue AsValue() => IsBinary
     ? PhpValue.Create(new PhpString.Blob(new[] { (byte)_b })) // [0x10, 0xff]
     : PhpValue.Create(AsChar().ToString());                   // Char is preferred if can be used