public void AddUsingMask(string mask)
{
if (mask == null) return;
// implemented by automaton with the following states:
const int char_empty = 0; // no character read - initial state and after interval read state
const int char_read = 1; // one char read into buffer, no dots read
const int dot_read = 2; // one char read into buffer, one dot read
const int dot_dot_read = 3; // one char read into buffer, two dots read
// the interval constructing character:
const char dot = '.';
int state = char_empty; // initial state
char first = '\0'; // the first character of an interval being processed
char last; // the last character of an interval being processed
for (int i = 0; i < mask.Length; i++)
{
last = mask[i];
switch (state)
{
case char_empty:
first = last;
state = char_read;
break;
case char_read:
if (last != dot)
{
Add(first);
first = last;
state = char_read;
}
else
state = dot_read;
break;
case dot_read:
if (last != dot)
{
if (first == dot) //eg: "..x" or "x.y"
//PhpException.Throw(PhpError.Warning, LibResources.GetString("char_range_no_char_on_left", ".."));
throw new NotImplementedException();
else
Add(first);
// The dot will be added and the last char read may be init char of an interval:
Add(dot);
first = last;
state = char_read;
}
else
state = dot_dot_read;
break;
case dot_dot_read:
if (first > last) //eg: "a..b" or "b..a"
{
// the first character will be added and the last char read may be init char of an interval:
Add(first);
Add(dot);
first = last;
state = char_read;
//PhpException.Throw(PhpError.Warning, LibResources.GetString("char_range_not_incrementing", ".."));
throw new NotImplementedException();
}
else
{
AddRange(first, last);
}
state = char_empty;
break;
} //switch
} //for
// postprocessing:
if (state != char_empty) Add(first);
if (state == dot_read || state == dot_dot_read)
{
Add(dot);
if (state == dot_dot_read)
//PhpException.Throw(PhpError.Warning, LibResources.GetString("char_range_no_char_on_right", ".."));
throw new NotImplementedException();
}
}