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]); }
internal static PhpMyDbConnection ValidConnection(PhpResource handle) { PhpMyDbConnection connection; if (handle != null && handle.GetType() == typeof(PhpMyDbConnection)) { connection = (PhpMyDbConnection)handle; } else { connection = null; } if (connection != null && connection.IsValid) { return(connection); } PhpException.Throw(PhpError.Warning, LibResources.GetString("invalid_connection_resource")); return(null); }
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)); } } }
/// <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)); } }
/// <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); }
/// <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; }
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()); } }
/// <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); }
/// <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); }
/// <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; } } }
/// <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); }
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); }
/// <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); }
/// <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); } }