//
// System.Data.ProviderBase.regex.cs
//
// Authors:
// Konstantin Triger <kostat@mainsoft.com>
//
// (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);
}
}
}
|