// // System.Data.ProviderBase.regex.cs // // Authors: // Konstantin Triger // // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.Data; using System.Data.Common; using System.Data.OleDb; namespace System.Data.ProviderBase { public abstract class SimpleRegex { abstract protected internal SimpleMatch Match(string input, int beginning, int length); protected internal SimpleMatch Match(string input) { return Match(input, 0, input.Length); } protected bool IsWordChar(char c) { //regexp w ([a-zA-Z_0-9]) + #@$ if (c < '@') { return (c >= '0' && c <= '9') || (c == '#' || c == '$'); } else { return (c <= 'Z') || (c <= 'z' && c >= '_' && c != '`'); } } } public class SimpleCapture { readonly int _index; readonly int _length; readonly string _input; protected SimpleCapture(int index, int length, string input) { _index = index; _length = length; _input = input; } protected internal int Index { get { return _index; } } protected internal int Length { get { return _length; } } protected internal string Value { get { return Input.Substring(Index, Length); } } protected string Input { get { return _input; } } } public class SimpleMatch : SimpleCapture { readonly bool _success; readonly SimpleRegex _regex; readonly int _total; readonly int _skip; public SimpleMatch(SimpleRegex regex, int total, bool success, int index, int length, string input) : this(regex, total, success, index, length, 0, input) {} public SimpleMatch(SimpleRegex regex, int total, bool success, int index, int length, int skip, string input) : base(index, length, input) { _success = success; _regex = regex; _total = total; _skip = skip; } protected internal SimpleMatch NextMatch() { return _regex.Match(Input, Index+Length+_skip, _total); } protected internal bool Success { get { return _success; } } } internal class OleDbParamsRegex : SimpleRegex { protected internal override SimpleMatch Match(string input, int beginning, int length) { for (int i = beginning; i < length; i++) { char ch = input[i]; switch(ch) { case '\'': { int end = input.IndexOf('\'', i+1); if (end < 0) break; i = end; break; } case '"': { int end = input.IndexOf('"', i+1); if (end < 0) break; i = end; break; } case '[': { int end = input.IndexOf(']', i+1); if (end < 0) break; i = end; break; } case '?': { return new SimpleMatch(this, length, true, i, 1, input); } } } return new SimpleMatch(this, length, false, length, 0, input); } } internal class SqlParamsRegex : SimpleRegex { //static readonly char[] charsEnd = new char[] {' ', '\f', '\t', '\v', '\r', '\n', ',', ';', '(', ')', '[', ']','='}; protected internal override SimpleMatch Match(string input, int beginning, int length) { int actualLen = length-1; //there must be something after @ for (int i = beginning; i < actualLen; i++) { char ch = input[i]; switch(ch) { case '\'': { int end = input.IndexOf('\'', i+1); if (end < 0) break; i = end; break; } case '"': { int end = input.IndexOf('"', i+1); if (end < 0) break; i = end; break; } case '[': { int end = input.IndexOf(']', i+1); if (end < 0) break; i = end; break; } case '@': { int start = i; do { i++; }while (i < length && input[i] == '@'); if (i - start > 1) break; while (i < length && IsWordChar(input[i])) i++; return new SimpleMatch(this, length, true, start, i-start, input); } } } return new SimpleMatch(this, length, false, length, 0, input); } } internal class CharacterSplitterRegex : SimpleRegex { char _delimiter; internal CharacterSplitterRegex(char delimiter) { _delimiter = delimiter; } protected internal override SimpleMatch Match(string input, int beginning, int length) { for (int i = beginning; i < length; i++) { char ch = input[i]; switch(ch) { case '\'': { int end = input.IndexOf('\'', i+1); if (end < 0) break; i = end; break; } case '"': { int end = input.IndexOf('"', i+1); if (end < 0) break; i = end; break; } case '[': { int end = input.IndexOf(']', i+1); if (end < 0) break; i = end; break; } default: { if (ch != _delimiter) break; return new SimpleMatch(this, length, true, beginning, i-beginning, 1, input); } } } int matchLength = length-beginning; return new SimpleMatch(this, length, matchLength > 0, beginning, matchLength, input); } } }