Example #1
0
        public static int Parse(string /*!*/ str, DateTime utcStart, out string error)
        {
            Debug.Assert(str != null);

            StrToTime.Scanner scanner = new StrToTime.Scanner(new StringReader(str.ToLower()));
            error = null;

            for (; ;)
            {
                Tokens token = scanner.GetNextToken();

                if (token == Tokens.ERROR || scanner.Errors > 0)
                {
                    error = LibResources.GetString("parse_error", scanner.Position, str.Substring(scanner.Position));
                    return(0);
                }

                if (token == Tokens.EOF)
                {
                    return(scanner.Time.GetUnixTimeStamp(utcStart, out error));
                }
            }
            //error = "unknown error of datetime parsing";
            //return 0;
        }
Example #2
0
        /// <summary>
        /// Implementation of <c>mb_str[i]pos</c> functions.
        /// </summary>
        private static int Strpos(object haystack, object needle, int offset, getEncoding encodingGetter, bool ignoreCase)
        {
            string uhaystack = ObjectToString(haystack, encodingGetter);
            string uneedle   = ObjectToString(needle, encodingGetter);

            if (uhaystack == null || uneedle == null)
            {
                return(-1);
            }

            if (offset < 0 || offset >= uhaystack.Length)
            {
                if (offset != uhaystack.Length)
                {
                    PhpException.InvalidArgument("offset", LibResources.GetString("arg:out_of_bounds"));
                }
                return(-1);
            }

            if (uneedle == String.Empty)
            {
                PhpException.InvalidArgument("needle", LibResources.GetString("arg:empty"));
                return(-1);
            }

            if (ignoreCase)
            {
                return(uhaystack.ToLower().IndexOf(uneedle.ToLower(), offset));
            }
            else
            {
                return(uhaystack.IndexOf(uneedle, offset));
            }
        }
Example #3
0
        /// <summary>
        /// Opens a database connection if it has not been opened yet.
        /// </summary>
        /// <returns><B>true</B> if successful.</returns>
        /// <exception cref="PhpException">Attempt to connect the database failed (Warning).</exception>
        /// <remarks>
        /// Sets <see cref="LastException"/> to <B>null</B> (on success) or to the exception object (on failure).
        /// </remarks>
        public bool Connect()
        {
            Debug.Assert(connection != null);

            if (connection.State == ConnectionState.Open)
            {
                return(true);
            }

            connection.ConnectionString = this.ConnectionString;
            try
            {
                connection.Open();
                lastException = null;
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("cannot_open_connection",
                                                                            GetExceptionMessage(e)));

                return(false);
            }

            return(true);
        }
Example #4
0
        public static bool Bind(PhpResource statement, string parameterName, PhpReference variable, VariableType type,
                                bool isOutput, bool isNullable, int maxLength)
        {
            PhpSqlDbProcedure procedure = PhpSqlDbProcedure.ValidProcedure(statement);

            if (procedure == null)
            {
                return(false);
            }

            if (parameterName == null)
            {
                PhpException.ArgumentNull("parameterName");
                return(false);
            }

            PhpSqlDbProcedure.ParameterType param_type = PhpSqlDbProcedure.VariableTypeToParamType(type);
            if (param_type == PhpSqlDbProcedure.ParameterType.Invalid)
            {
                PhpException.ArgumentValueNotSupported("type", (int)type);
                return(false);
            }

            SqlParameter parameter = new SqlParameter();

            parameter.ParameterName = parameterName;

            // it is necessary to set size for in-out params as the results are truncated to this size;
            // 8000 is maximal size of the data according to the doc:
            if (maxLength >= 0)
            {
                parameter.Size = maxLength;
            }
            else
            {
                parameter.Size = 8000;
            }

            if (String.Compare(parameterName, "RETVAL", true) == 0)
            {
                parameter.Direction = ParameterDirection.ReturnValue;
            }
            else if (isOutput)
            {
                parameter.Direction = ParameterDirection.InputOutput;
            }
            else
            {
                parameter.Direction = ParameterDirection.Input;
            }

            if (!procedure.AddBinding(parameter, variable, param_type))
            {
                PhpException.Throw(PhpError.Notice, LibResources.GetString("parameter_already_bound", parameterName));
                return(false);
            }

            return(true);
        }
Example #5
0
        /// <summary>
        /// Checks whether a row index is valid for the current result set.
        /// </summary>
        /// <param name="rowIndex">Row index to check.</param>
        /// <returns>Whether the index is in the range [0, <see cref="RowCount"/>).</returns>
        /// <exception cref="PhpException">Invalid row index (Warning).</exception>
        public bool CheckRowIndex(int rowIndex)
        {
            if (rowIndex < 0 || rowIndex >= RowCount)
            {
                PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_data_result_row_index",
                                                                            rowIndex, this.TypeName, this.Id));
                return(false);
            }

            return(true);
        }
Example #6
0
        /// <summary>
        /// Validates whether the specified handler is instance of PhpDbConnection type.
        /// </summary>
        /// <param name="handle"></param>
        /// <returns></returns>
        internal static PhpSqlDbConnection ValidConnection(PhpResource handle)
        {
            PhpSqlDbConnection connection = handle as PhpSqlDbConnection;

            if (connection != null && connection.IsValid)
            {
                return(connection);
            }

            PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_connection_resource"));
            return(null);
        }
Example #7
0
        internal static PhpSqlDbProcedure ValidProcedure(PhpResource handle)
        {
            PhpSqlDbProcedure result = handle as PhpSqlDbProcedure;

            if (result != null && result.IsValid)
            {
                return(result);
            }

            PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_stored_procedure_resource"));
            return(null);
        }
Example #8
0
 /// <summary>
 /// Serializes a graph of connected objects to a string (unicode or binary) using a given formatter.
 /// </summary>
 /// <param name="ctx">Runtime context.</param>
 /// <param name="variable">The variable to serialize.</param>
 /// <param name="caller">Caller's class context.</param>
 /// <returns>
 /// The serialized representation of the <paramref name="variable"/> or a <B>null</B> reference on error.
 /// </returns>
 /// <exception cref="PhpException">Serialization failed (Notice).</exception>
 public PhpString Serialize(Context ctx, PhpValue variable, RuntimeTypeHandle caller)
 {
     try
     {
         return(CommonSerialize(ctx, variable, caller));
     }
     catch (Exception e)
     {
         PhpException.Throw(PhpError.Notice, LibResources.GetString("serialization_failed", e.Message));
         return(null);
     }
 }
Example #9
0
        /// <summary>
        /// Checks whether a field index is valid for the current result set.
        /// </summary>
        /// <param name="fieldIndex">Field index to check.</param>
        /// <returns>Whether the index is in the range [0, <see cref="FieldCount"/>).</returns>
        /// <exception cref="PhpException">Invalid field index (Warning).</exception>
        public bool CheckFieldIndex(int fieldIndex)
        {
            if (fieldIndex < 0 || fieldIndex >= FieldCount)
            {
                PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_data_result_field_index",
                                                                            fieldIndex, this.TypeName, this.Id));

                return(false);
            }

            return(true);
        }
Example #10
0
        internal static PhpMyDbResult ValidResult(PhpResource handle)
        {
            PhpMyDbResult result = handle as PhpMyDbResult;

            if (result != null && result.IsValid)
            {
                return(result);
            }

            PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_result_resource"));
            return(null);
        }
Example #11
0
            /// <summary>
            /// Deserializes a graph of connected object from a byte array using a given formatter.
            /// </summary>
            /// <param name="ctx">Runtime context.</param>
            /// <param name="data">The string to deserialize the graph from.</param>
            /// <param name="caller">Caller's class context.</param>
            /// <returns>The deserialized object graph or <B>false</B> on error.</returns>
            public PhpValue Deserialize(Context ctx, PhpString data, RuntimeTypeHandle caller /*, allowed_classes */)
            {
                var stream = new MemoryStream(data.ToBytes(ctx));

                try
                {
                    return(CommonDeserialize(ctx, stream, caller));
                }
                catch (Exception e)
                {
                    PhpException.Throw(PhpError.Notice, LibResources.GetString("deserialization_failed", e.Message, stream.Position, stream.Length));
                    return(PhpValue.False);
                }
            }
Example #12
0
        /// <summary>
        /// Gets a value of a specified field of the result.
        /// </summary>
        /// <param name="rowIndex">Row index.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns>The value or a <B>null</B> reference if row or index are out of range.</returns>
        public object GetFieldValue(int rowIndex, string fieldName)
        {
            if (!CheckRowIndex(rowIndex))
            {
                return(false);
            }

            for (int i = 0; i < CurrentSet.Names.Length; i++)
            {
                if (String.Compare(CurrentSet.Names[i], fieldName, true) == 0)
                {
                    return(((object[])CurrentSet.Rows[rowIndex])[i]);
                }
            }

            PhpException.Throw(PhpError.Notice, LibResources.GetString("field_not_exists", fieldName));
            return(null);
        }
Example #13
0
        /// <summary>
        /// Retrieves an argument passed to the current user-function.
        /// </summary>
        /// <remarks><seealso cref="PhpStack.GetArgument"/></remarks>
        public static PhpValue func_get_arg([ImportCallerArgs] PhpValue[] args, int index)
        {
            // checks correctness of the argument:
            if (index < 0)
            {
                PhpException.InvalidArgument(nameof(index), LibResources.arg_negative);
                return(PhpValue.False);
            }

            if (args == null || index >= args.Length)
            {
                PhpException.Throw(PhpError.Warning, LibResources.GetString("argument_not_passed_to_function", index));
                return(PhpValue.False);
            }

            //
            return(args[index].DeepCopy());
        }
Example #14
0
        /// <summary>
        /// mb_strstr() finds the first occurrence of needle in haystack  and returns the portion of haystack. If needle is not found, it returns FALSE.
        /// </summary>
        /// <param name="haystack">The string from which to get the first occurrence of needle</param>
        /// <param name="needle">The string to find in haystack</param>
        /// <param name="part">Determines which portion of haystack  this function returns. If set to TRUE, it returns all of haystack  from the beginning to the first occurrence of needle. If set to FALSE, it returns all of haystack  from the first occurrence of needle to the end.</param>
        /// <param name="encodingGetter">Character encoding name to use. If it is omitted, internal character encoding is used. </param>
        /// <param name="ignoreCase">Case insensitive.</param>
        /// <returns>Returns the portion of haystack, or FALSE (-1) if needle is not found.</returns>
        private static string StrStr(object haystack, object needle, bool part /* = false*/, getEncoding encodingGetter, bool ignoreCase)
        {
            string uhaystack = ObjectToString(haystack, encodingGetter);
            string uneedle   = ObjectToString(needle, encodingGetter);

            if (uhaystack == null || uneedle == null)   // never happen
            {
                return(null);
            }

            if (uneedle == String.Empty)
            {
                PhpException.InvalidArgument("needle", LibResources.GetString("arg:empty"));
                return(null);
            }

            int index = (ignoreCase) ? uhaystack.ToLower().IndexOf(uneedle.ToLower()) : uhaystack.IndexOf(uneedle);

            return((index == -1) ? null : (part ? uhaystack.Substring(0, index) : uhaystack.Substring(index)));
        }
Example #15
0
        /// <summary>
        /// Reexecutes a command associated with a specified result resource to get schema of the command result.
        /// </summary>
        /// <param name="result">The result resource.</param>
        internal void ReexecuteSchemaQuery(PhpDbResult /*!*/ result)
        {
            if (!Connect() || result.Command == null)
            {
                return;
            }

            ClosePendingReader();

            try
            {
                result.Reader = pendingReader = result.Command.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly);
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("command_execution_failed",
                                                                            GetExceptionMessage(e)));
            }
        }
Example #16
0
        /// <summary>
        /// Establishes a connection if a connection with the same connection string doesn't exist yet.
        /// </summary>
        /// <param name="connectionString">Connection string.</param>
        /// <param name="newConnection">Whether to create a new connection even if there exists one with same string.</param>
        /// <param name="limit">Maximal number of connections. Negative value means no limit.</param>
        /// <param name="success"><B>true</B> on success, <B>false</B> on failure.</param>
        /// <returns>The connection (opened or not) or a <B>null</B> reference on failure.</returns>
        public PhpDbConnection OpenConnection(string /*!*/ connectionString, bool newConnection, int limit, out bool success)
        {
            if (connectionString == null)
            {
                throw new ArgumentNullException("connectionString");
            }

            PhpDbConnection connection;

            if (!newConnection)
            {
                connection = GetConnectionByString(connectionString);
                if (connection != null)
                {
                    success = true;
                    return(connection);
                }
            }

            int count = Interlocked.Increment(ref AppConnectionCount);

            if (limit >= 0 && count > limit)
            {
                Interlocked.Decrement(ref AppConnectionCount);

                PhpException.Throw(PhpError.Warning, LibResources.GetString("connection_limit_reached", limit));
                success = false;
                return(null);
            }

            connection = CreateConnection(connectionString);
            if (!connection.Connect())
            {
                success = false;
                return(connection);
            }

            connections.Add(connection);
            success = true;
            return(connection);
        }
Example #17
0
        internal static PhpSQLiteDbConnection ValidConnection(PhpResource handle)
        {
            PhpSQLiteDbConnection connection;

            if (handle != null && handle.GetType() == typeof(PhpSQLiteDbConnection))
            {
                connection = (PhpSQLiteDbConnection)handle;
            }
            else
            {
                connection = null;
            }

            if (connection != null && connection.IsValid)
            {
                return(connection);
            }

            PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_connection_resource"));
            return(null);
        }
Example #18
0
        public static int Parse(string /*!*/ str, DateTime utcStart, out string error)
        {
            Debug.Assert(str != null);

            var scanner = new Scanner(new StringReader(str.ToLowerInvariant()));

            while (true)
            {
                Tokens token = scanner.GetNextToken();
                if (token == Tokens.ERROR || scanner.Errors > 0)
                {
                    error = LibResources.GetString("parse_error", scanner.Position, str.Substring(scanner.Position));
                    return(0);
                }

                if (token == Tokens.EOF)
                {
                    return(scanner.Time.GetUnixTimeStamp(utcStart, out error));
                }
            }
        }
Example #19
0
        private ArrayList schemaTables = null;               // GENERICS: List<DataTable>

        /// <summary>
        /// Gets information about schema of the current result set.
        /// </summary>
        /// <returns>Schema table.</returns>
        public DataTable GetSchemaTable()
        {
            // loads schema if not loaded yet:
            if (schemaTables == null)
            {
                connection.ReexecuteSchemaQuery(this);
                if (reader.IsClosed)
                {
                    PhpException.Throw(PhpError.Warning, LibResources.GetString("cannot_retrieve_schema"));
                    return(null);
                }

                schemaTables = new ArrayList();
                do
                {
                    schemaTables.Add(reader.GetSchemaTable());
                }while (reader.NextResult());
            }

            return((DataTable)schemaTables[currentSetIndex]);
        }
Example #20
0
        public static string GuidToString(PhpBytes binary, bool shortFormat)
        {
            if (binary == null || binary.Length == 0)
            {
                return(String.Empty);
            }

            if (binary.Length != 16)
            {
                PhpException.InvalidArgument("binary", LibResources.GetString("arg:invalid_length"));
                return(null);
            }

            if (shortFormat)
            {
                return(new Guid(binary.ReadonlyData).ToString("D").ToUpper());
            }
            else
            {
                return(PHP.Core.StringUtils.BinToHex(binary.ReadonlyData, null).ToUpper());
            }
        }
Example #21
0
        /// <summary>
        /// Closes connection and releases the resource.
        /// </summary>
        protected override void FreeManaged()
        {
            base.FreeManaged();

            ClosePendingReader();

            try
            {
                if (connection != null)
                {
                    connection.Close();
                }
                lastException = null;
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("error_closing_connection",
                                                                            GetExceptionMessage(e)));
            }
            connection = null;
        }
Example #22
0
        /// <summary>
        /// Changes the active database on opened connection.
        /// </summary>
        /// <param name="databaseName"></param>
        /// <returns>true if databse was changed; otherwise returns false</returns>
        public bool SelectDb(string databaseName)
        {
            ClosePendingReader();

            try
            {
                if (this.connection.State == ConnectionState.Open)
                {
                    connection.ChangeDatabase(databaseName);
                    lastException = null;
                    return(true);
                }
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("database_selection_failed",
                                                                            GetExceptionMessage(e)));
            }

            return(false);
        }
Example #23
0
        /// <summary>
        /// Implementation of <c>mb_strr[i]pos</c> functions.
        /// </summary>
        private static int Strrpos(object haystack, object needle, int offset, getEncoding encodingGetter, bool ignoreCase)
        {
            string uhaystack = ObjectToString(haystack, encodingGetter);
            string uneedle   = ObjectToString(needle, encodingGetter);

            if (uhaystack == null || uneedle == null)
            {
                return(-1);
            }

            int end = uhaystack.Length - 1;

            if (offset > end || offset < -end - 1)
            {
                PhpException.InvalidArgument("offset", LibResources.GetString("arg:out_of_bounds"));
                return(-1);
            }

            if (offset < 0)
            {
                end   += uneedle.Length + offset;
                offset = 0;
            }

            if (uneedle.Length == 0)
            {
                PhpException.InvalidArgument("needle", LibResources.GetString("arg:empty"));
                return(-1);
            }

            if (ignoreCase)
            {
                return(uhaystack.ToLower().LastIndexOf(uneedle.ToLower(), end, end - offset + 1));
            }
            else
            {
                return(uhaystack.LastIndexOf(uneedle, end, end - offset + 1));
            }
        }
Example #24
0
        protected virtual PhpDbResult ExecuteCommandInternal(string /*!*/ commandText, CommandType commandType, bool convertTypes, IEnumerable <IDataParameter> parameters, bool skipResults)
        {
            ClosePendingReader();

            // IDbCommand
            IDbCommand command = CreateCommand();

            command.Connection  = connection;
            command.CommandText = commandText;
            command.CommandType = commandType;

            if (parameters != null)
            {
                command.Parameters.Clear();
                foreach (IDataParameter parameter in parameters)
                {
                    command.Parameters.Add(parameter);
                }
            }

            // ExecuteReader
            PhpDbResult result = null;

            try
            {
                var /*!*/ reader = this.pendingReader = command.ExecuteReader();

                if (skipResults)
                {
                    // reads all data:
                    do
                    {
                        while (reader.Read())
                        {
                            ;
                        }
                    } while (reader.NextResult());
                }
                else
                {
                    lastResult = null;

                    // read all data into PhpDbResult:
                    result         = GetResult(this, reader, convertTypes);
                    result.command = command;

                    lastResult = result;
                }

                lastException = null;
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("command_execution_failed",
                                                                            GetExceptionMessage(e)));
            }

            //
            return(result);
        }
Example #25
0
        /// <summary>
        /// Parses pack format. Stores specifiers and repeaters into the respective arrays.
        /// Repeaters are ensured to be finite and non-negative (infinite repeaters are converted to finite).
        /// Some arguments are also converted to another form (e.g. to string) because we will need that form later.
        /// </summary>
        /// <returns>Returns the number of parsed specifiers or 0 on error.</returns>
        static int ParseFormat(Context ctx, string format, PhpValue[] args, char[] specifiers, int[] repeaters)
        {
            var encoding = ctx.StringEncoding;

            int i      = 0;  // current position in format
            int a      = 0;  // current argument index
            int result = 0;  // number of parsed specifiers

            while (i < format.Length)
            {
                char specifier = format[i++];
                int  repeater  = ParseRepeater(format, ref i);

                switch (specifier)
                {
                case 'x':     // NUL byte
                case '@':     // NUL-fill to absolute position
                case 'X':     // Back up one byte

                    // consumes no arguments => repeater cannot be '*'
                    if (repeater == InfiniteRepeater)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("asterisk_ignored", specifier));
                        repeater = 1;
                    }
                    break;

                case 'Z':     // equivalent functionality to "a" for Perl compatibility
                case 'a':     // NUL-padded string
                case 'A':     // SPACE-padded string
                case 'h':     // Hex string, low/high nibble first - converts to a string, takes n hex digits:
                case 'H':
                {
                    // consumes one argument:
                    if (a == args.Length)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_arguments", specifier));
                        return(0);
                    }

                    // converts the current argument to a string and stores it back:
                    string s = args[a].ToString(ctx);
                    args[a] = (PhpValue)s;
                    a++;

                    if (specifier == 'h' || specifier == 'H')
                    {
                        if (repeater > s.Length)
                        {
                            PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_characters", specifier));
                            repeater = s.Length;
                        }
                    }
                    else
                    {
                        if (encoding.GetByteCount(s) != s.Length)
                        {
                            PhpException.Throw(PhpError.Warning, LibResources.GetString("multibyte_chars_unsupported", specifier));
                            return(0);
                        }
                    }

                    // adjusts infinite repeater to the string length:
                    if (repeater == InfiniteRepeater)
                    {
                        repeater = s.Length;
                    }

                    break;
                }

                case 'c':     // signed char
                case 'C':     // unsigned char
                case 's':     // signed short (always 16 bit, machine byte order)
                case 'S':     // unsigned short (always 16 bit, machine byte order)
                case 'n':     // unsigned short (always 16 bit, big endian byte order)
                case 'v':     // unsigned short (always 16 bit, little endian byte order)
                case 'i':     // signed integer (machine dependent size and byte order)
                case 'I':     // unsigned integer (machine dependent size and byte order)
                case 'l':     // signed long (always 32 bit, machine byte order)
                case 'L':     // unsigned long (always 32 bit, machine byte order)
                case 'N':     // unsigned long (always 32 bit, big endian byte order)
                case 'V':     // unsigned long (always 32 bit, little endian byte order)
                case 'f':     // float (machine dependent size and representation)
                case 'd':     // double (machine dependent size and representation)

                    if (repeater == InfiniteRepeater)
                    {
                        // infinite repeater is converted to the number of remaining arguments (can be zero):
                        repeater = args.Length - a;
                    }
                    else if (repeater > args.Length - a)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_arguments", specifier));
                        return(0);
                    }

                    // consume arguments:
                    a += repeater;
                    break;

                default:
                    PhpException.Throw(PhpError.Warning, LibResources.GetString("unknown_format_code", specifier));
                    return(0);
                }

                specifiers[result] = specifier;
                repeaters[result]  = repeater;
                result++;
            }

            // reports unused arguments:
            if (a < args.Length)
            {
                PhpException.Throw(PhpError.Warning, LibResources.GetString("unused_arguments", args.Length - a));
            }

            return(result);
        }
Example #26
0
        /// <summary>
        /// Unpacks data from a string of bytes into <see cref="PhpArray"/>.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="format">The string defining the items of the result. See PHP manual for details.</param>
        /// <param name="data">The string of bytes to be unpacked.</param>
        /// <returns>The <see cref="PhpArray"/> containing unpacked data.</returns>
        public static PhpArray unpack(Context ctx, string format, PhpString data)
        {
            if (format == null)
            {
                return(null);
            }
            byte[] buffer = data.ToBytes(ctx);

            var encoding = ctx.StringEncoding;

            byte[] reversed = new byte[4]; // used for reversing the order of bytes in buffer

            int      i      = 0;
            int      pos    = 0;
            PhpArray result = new PhpArray();

            while (i < format.Length)
            {
                string name;
                int    repeater;
                char   specifier;

                // parses specifier, repeater, and name from the format string:
                ParseFormatToken(format, ref i, out specifier, out repeater, out name);

                int remains = buffer.Length - pos;          // the number of bytes remaining in the buffer
                int size;                                   // a size of data to be extracted corresponding to the specifier

                // repeater of '@' specifier has a special meaning:
                if (specifier == '@')
                {
                    if (repeater > buffer.Length || repeater == InfiniteRepeater)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier));
                    }
                    else
                    {
                        pos = repeater;
                    }

                    continue;
                }

                // number of operations:
                int op_count;

                // gets the size of the data to read and adjust repeater:
                if (!GetSizeToUnpack(specifier, remains, repeater, out op_count, out size))
                {
                    PhpException.Throw(PhpError.Warning, LibResources.GetString("unknown_format_code", specifier));
                    return(null);
                }

                // repeats operation determined by specifier "op_count" times;
                // if op_count is infinite then stops when the number of remaining characters is zero:
                for (int j = 0; j < op_count || op_count == InfiniteRepeater; j++)
                {
                    if (size > remains)
                    {
                        // infinite means "while data are available":
                        if (op_count == InfiniteRepeater)
                        {
                            break;
                        }

                        PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_input", specifier, size, remains));
                        return(null);
                    }

                    PhpValue item;
                    switch (specifier)
                    {
                    case 'X':     // decreases position, no value stored:
                        if (pos == 0)
                        {
                            PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier));
                        }
                        else
                        {
                            pos--;
                        }
                        continue;

                    case 'x':     // advances position, no value stored
                        pos++;
                        continue;

                    case 'a':     // NUL-padded string
                    case 'A':     // SPACE-padded string
                    {
                        byte pad = (byte)(specifier == 'a' ? 0x00 : 0x20);

                        int last = pos + size - 1;
                        while (last >= pos && buffer[last] == pad)
                        {
                            last--;
                        }

                        item = (PhpValue)encoding.GetString(buffer, pos, last - pos + 1);
                        break;
                    }

                    case 'h':     // Hex string, low/high nibble first - converts to a string, takes n hex digits from string:
                    case 'H':
                    {
                        int p            = pos;
                        int nibble_shift = (specifier == 'h') ? 0 : 4;

                        var sb = StringBuilderUtilities.Pool.Get();
                        for (int k = 0; k < size; k++)
                        {
                            const string hex_digits = "0123456789ABCDEF";

                            sb.Append(hex_digits[(buffer[p] >> nibble_shift) & 0x0f]);

                            // beware of odd repeaters!
                            if (repeater == InfiniteRepeater || repeater > sb.Length)
                            {
                                sb.Append(hex_digits[(buffer[p] >> (4 - nibble_shift)) & 0x0f]);
                            }
                            p++;
                        }

                        item = StringBuilderUtilities.GetStringAndReturn(sb);
                        break;
                    }

                    case 'c':     // signed char
                        item = (PhpValue)(int)unchecked ((sbyte)buffer[pos]);
                        break;

                    case 'C':     // unsigned char
                        item = (PhpValue)(int)buffer[pos];
                        break;

                    case 's':     // signed short (always 16 bit, machine byte order)
                        item = (PhpValue)(int)BitConverter.ToInt16(buffer, pos);
                        break;

                    case 'S':     // unsigned short (always 16 bit, machine byte order)
                        item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos);
                        break;

                    case 'n':     // unsigned short (always 16 bit, big endian byte order)
                        if (BitConverter.IsLittleEndian)
                        {
                            item = (PhpValue)(int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0);
                        }
                        else
                        {
                            item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos);
                        }
                        break;

                    case 'v':     // unsigned short (always 16 bit, little endian byte order)
                        if (!BitConverter.IsLittleEndian)
                        {
                            item = (PhpValue)(int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0);
                        }
                        else
                        {
                            item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos);
                        }
                        break;

                    case 'i':     // signed integer (machine dependent size and byte order - always 32 bit)
                    case 'I':     // unsigned integer (machine dependent size and byte order - always 32 bit)
                    case 'l':     // signed long (always 32 bit, machine byte order)
                    case 'L':     // unsigned long (always 32 bit, machine byte order)
                        item = (PhpValue)BitConverter.ToInt32(buffer, pos);
                        break;

                    case 'N':     // unsigned long (always 32 bit, big endian byte order)
                        item = (PhpValue) unchecked (((int)buffer[pos] << 24) + (buffer[pos + 1] << 16) + (buffer[pos + 2] << 8) + buffer[pos + 3]);
                        break;

                    case 'V':     // unsigned long (always 32 bit, little endian byte order)
                        item = (PhpValue) unchecked (((int)buffer[pos + 3] << 24) + (buffer[pos + 2] << 16) + (buffer[pos + 1] << 8) + buffer[pos + 0]);
                        break;

                    case 'f':     // float (machine dependent size and representation - size is always 4B)
                        item = (PhpValue)(double)BitConverter.ToSingle(buffer, pos);
                        break;

                    case 'd':     // double (machine dependent size and representation - size is always 8B)
                        item = (PhpValue)BitConverter.ToDouble(buffer, pos);
                        break;

                    default:
                        Debug.Fail("Invalid specifier.");
                        return(null);
                    }

                    AddValue(result, name, item, op_count, j);

                    pos     += size;
                    remains -= size;
                }
            }

            return(result);
        }
Example #27
0
        /// <summary>
        /// Computes the total size of binary data according to given specifiers and repeaters.
        /// Only <c>count</c> of them are valid.
        /// </summary>
        static void GetPackedDataSize(char[] specifiers, int[] repeaters, int count, out int resultLength, out int maxLength)
        {
            long result = 0;

            maxLength = 0;

            for (int i = 0; i < count; i++)
            {
                long repeater  = repeaters[i];
                char specifier = specifiers[i];

                switch (specifier)
                {
                case 'x':
                    // NUL byte repeated for "repeater" count:
                    result += repeater;
                    break;

                case '@':
                    // NUL-fill to absolute position;
                    // if it is less then the current position the result is shortened
                    result = repeater;
                    break;

                case 'X':
                    // shortens the result by "repeater" bytes (underflow has to be checked):
                    if (result < repeater)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier));
                        result = 0;
                    }
                    else
                    {
                        result -= repeater;
                    }
                    break;

                case 'a':     // NUL-padded string
                case 'A':     // SPACE-padded string
                case 'c':     // signed char
                case 'C':     // unsigned char
                    result += repeater;
                    break;

                case 's':     // signed short (always 16 bit, machine byte order)
                case 'S':     // unsigned short (always 16 bit, machine byte order)
                case 'n':     // unsigned short (always 16 bit, big endian byte order)
                case 'v':     // unsigned short (always 16 bit, little endian byte order)
                    result += repeater * 2;
                    break;

                case 'i':     // signed integer (machine dependent size and byte order - always 32 bit)
                case 'I':     // unsigned integer (machine dependent size and byte order - always 32 bit)
                case 'l':     // signed long (always 32 bit, machine byte order)
                case 'L':     // unsigned long (always 32 bit, machine byte order)
                case 'N':     // unsigned long (always 32 bit, big endian byte order)
                case 'V':     // unsigned long (always 32 bit, little endian byte order)
                case 'f':     // float (machine dependent size and representation)
                    result += repeater * 4;
                    break;

                case 'd':     // double (machine dependent size and representation)
                    result += repeater * 8;
                    break;

                case 'h':     // Hex string, low/high nibble first - converts to a string, takes n hex digits from it:
                case 'H':
                    result += (repeater + 1) / 2;
                    break;

                default:
                    Debug.Fail("Invalid repeater");
                    break;
                }

                // checks for overflow:
                if (result > Int32.MaxValue)
                {
                    PhpException.Throw(PhpError.Warning, LibResources.GetString("binary_data_overflown", specifier));
                    result = Int32.MaxValue;
                }

                // expands the max length:
                if (result > maxLength)
                {
                    maxLength = unchecked ((int)result);
                }
            }

            resultLength = unchecked ((int)result);
        }
Example #28
0
        /// <summary>
        /// Executes a command on the connection.
        /// </summary>
        /// <param name="commandText">Command text.</param>
        /// <param name="convertTypes">Whether to convert data types to PHP ones.</param>
        /// <param name="commandType">Command type.</param>
        /// <param name="parameters">Parameters.</param>
        /// <param name="skipResults">Whether to load results.</param>
        /// <returns>PhpDbResult class representing the data read from database.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="commandText"/> is a <B>null</B> reference.</exception>
        /// <exception cref="PhpException">Command execution failed (Warning).</exception>
        public PhpDbResult ExecuteCommand(string /*!*/ commandText, CommandType commandType, bool convertTypes,
                                          IEnumerable <IDataParameter> parameters, bool skipResults)
        {
            if (commandText == null)
            {
                throw new ArgumentNullException("commandText");
            }

            if (!Connect())
            {
                return(null);
            }

            ClosePendingReader();

            IDbCommand command = CreateCommand();

            command.Connection  = connection;
            command.CommandText = commandText;
            command.CommandType = commandType;

            if (parameters != null)
            {
                command.Parameters.Clear();
                foreach (IDataParameter parameter in parameters)
                {
                    command.Parameters.Add(parameter);
                }
            }

            try
            {
                if (skipResults)
                {
                    pendingReader = command.ExecuteReader();

                    // reads all data:
                    do
                    {
                        while (pendingReader.Read())
                        {
                            ;
                        }
                    } while (pendingReader.NextResult());

                    lastException = null;
                    return(null);
                }
                else
                {
                    lastResult = null;

                    pendingReader = command.ExecuteReader();
                    PhpDbResult result = GetResult(this, pendingReader, convertTypes);
                    result.command = command;

                    lastException = null;
                    lastResult    = result;
                    return(result);
                }
            }
            catch (Exception e)
            {
                lastException = e;
                PhpException.Throw(PhpError.Warning, LibResources.GetString("command_execution_failed",
                                                                            GetExceptionMessage(e)));
                return(null);
            }
        }
Example #29
0
 /// <summary>
 /// Serializes null and throws an exception.
 /// </summary>
 /// <param name="TypeName"></param>
 private object BindUnsupported(string TypeName)
 {
     PhpException.Throw(PhpError.Warning, LibResources.GetString("serialization_unsupported_type", TypeName));
     return(null);
 }
Example #30
0
        /// <summary>
        /// Packs arguments into the buffer according to given specifiers and repeaters.
        /// Count specifies the number of valid specifiers/repeaters.
        /// </summary>
        static void PackInternal(Context ctx, byte[] buffer, PhpValue[] args, char[] specifiers, int[] repeaters, int count)
        {
            var  encoding = ctx.StringEncoding;
            bool le       = BitConverter.IsLittleEndian;
            int  a        = 0;    // index of the current argument
            int  pos      = 0;    // the position in the buffer

            PhpNumber num;
            bool      le2;

            for (int i = 0; i < count; i++)
            {
                char specifier = specifiers[i];
                int  repeater  = repeaters[i];

                switch (specifier)
                {
                case 'x':
                    // NUL byte repeated for "repeater" count:
                    ArrayUtils.Fill(buffer, 0, pos, repeater);
                    pos += repeater;
                    break;

                case '@':
                    // NUL-fill to absolute position;
                    // if it is less then the current position the result is shortened
                    if (repeater > pos)
                    {
                        ArrayUtils.Fill(buffer, 0, pos, repeater - pos);
                    }
                    pos = repeater;
                    break;

                case 'X':
                    pos = Math.Max(0, pos - repeater);
                    break;

                case 'a':     // NUL-padded string
                case 'A':     // SPACE-padded string
                {
                    // argument has already been converted to string:
                    string s = args[a++].ToString(ctx);

                    int length     = Math.Min(s.Length, repeater);
                    int byte_count = encoding.GetBytes(s, 0, length, buffer, pos);
                    Debug.Assert(byte_count == length, "Multibyte characters not supported");

                    // padding:
                    if (repeater > length)
                    {
                        ArrayUtils.Fill(buffer, (byte)((specifier == 'a') ? 0x00 : 0x20), pos + length, repeater - length);
                    }

                    pos += repeater;
                    break;
                }

                case 'h':     // Hex string, low/high nibble first - converts to a string, takes n hex digits from string:
                case 'H':
                {
                    // argument has already been converted to string:
                    string s = args[a++].ToString(ctx);

                    int nibble_shift = (specifier == 'h') ? 0 : 4;

                    for (int j = 0; j < repeater; j++)
                    {
                        int digit = Core.Convert.AlphaNumericToDigit(s[j]);
                        if (digit > 15)
                        {
                            PhpException.Throw(PhpError.Warning, LibResources.GetString("illegal_hex_digit", specifier, s[j]));
                            digit = 0;
                        }

                        if (j % 2 == 0)
                        {
                            buffer[pos] = unchecked ((byte)(digit << nibble_shift));
                        }
                        else
                        {
                            buffer[pos] |= unchecked ((byte)(digit << (4 - nibble_shift)));
                            pos++;
                        }
                    }

                    // odd number of hex digits (append '0' digit):
                    if (repeater % 2 == 1)
                    {
                        pos++;
                    }

                    break;
                }

                case 'c':     // signed char
                case 'C':     // unsigned char
                    while (repeater-- > 0)
                    {
                        buffer[pos++] = unchecked ((byte)args[a++].ToLong());
                    }
                    break;

                case 's':     // signed short (always 16 bit, machine byte order)
                case 'S':     // unsigned short (always 16 bit, machine byte order)
                    while (repeater-- > 0)
                    {
                        var ni = args[a++].ToNumber(out num);
                        PackNumber(BitConverter.GetBytes(unchecked ((ushort)num.ToLong())), le, buffer, ref pos);
                    }
                    break;

                case 'n':     // unsigned short (always 16 bit, big endian byte order)
                case 'v':     // unsigned short (always 16 bit, little endian byte order)
                    while (repeater-- > 0)
                    {
                        PackNumber(BitConverter.GetBytes(unchecked ((ushort)args[a++].ToLong())), specifier == 'v', buffer, ref pos);
                    }
                    break;

                case 'i':     // signed integer (machine dependent size and byte order - always 32 bit)
                case 'I':     // signed integer (machine dependent size and byte order - always 32 bit)
                case 'l':     // signed long (always 32 bit, machine byte order)
                case 'L':     // unsigned long (always 32 bit, machine byte order)
                    while (repeater-- > 0)
                    {
                        PackNumber(BitConverter.GetBytes((int)args[a++].ToLong()), le, buffer, ref pos);
                    }
                    break;

                case 'N':     // unsigned long (always 32 bit, big endian byte order)
                case 'V':     // unsigned long (always 32 bit, little endian byte order)
                    while (repeater-- > 0)
                    {
                        PackNumber(BitConverter.GetBytes((int)args[a++].ToLong()), specifier == 'V', buffer, ref pos);
                    }
                    break;

                case 'f':     // float (machine dependent size and representation - size is always 4B)
                case 'g':     // float (machine dependent size, little endian byte order)
                case 'G':     // float (machine dependent size, big endian byte order)
                    le2 = specifier == 'f' ? le : (specifier == 'g');
                    while (repeater-- > 0)
                    {
                        PackNumber(BitConverter.GetBytes(unchecked ((float)args[a++].ToDouble())), le2, buffer, ref pos);
                    }
                    break;

                case 'd':     // double (machine dependent size and representation - size is always 8B)
                case 'e':     // double (machine dependent size, little endian byte order)
                case 'E':     // double (machine dependent size, big endian byte order)
                    le2 = specifier == 'd' ? le : (specifier == 'e');
                    while (repeater-- > 0)
                    {
                        PackNumber(BitConverter.GetBytes(args[a++].ToDouble()), le2, buffer, ref pos);
                    }
                    break;

                default:
                    Debug.Fail("Invalid specifier");
                    break;
                }
            }
        }