/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
namespace SF.Snowball
{
public class SnowballProgram
{
/// Get the current string.
virtual public System.String GetCurrent()
{
return current.ToString();
}
protected internal SnowballProgram()
{
current = new System.Text.StringBuilder();
SetCurrent("");
}
/// Set the current string.
public virtual void SetCurrent(System.String value_Renamed)
{
//// current.Replace(current.ToString(0, current.Length - 0), value_Renamed, 0, current.Length - 0);
current.Remove(0, current.Length);
current.Append(value_Renamed);
cursor = 0;
limit = current.Length;
limit_backward = 0;
bra = cursor;
ket = limit;
}
// current string
protected internal System.Text.StringBuilder current;
protected internal int cursor;
protected internal int limit;
protected internal int limit_backward;
protected internal int bra;
protected internal int ket;
protected internal virtual void copy_from(SnowballProgram other)
{
current = other.current;
cursor = other.cursor;
limit = other.limit;
limit_backward = other.limit_backward;
bra = other.bra;
ket = other.ket;
}
protected internal virtual bool in_grouping(char[] s, int min, int max)
{
if (cursor >= limit)
return false;
char ch = current[cursor];
if (ch > max || ch < min)
return false;
ch -= (char) (min);
if ((s[ch >> 3] & (0x1 << (ch & 0x7))) == 0)
return false;
cursor++;
return true;
}
protected internal virtual bool in_grouping_b(char[] s, int min, int max)
{
if (cursor <= limit_backward)
return false;
char ch = current[cursor - 1];
if (ch > max || ch < min)
return false;
ch -= (char) (min);
if ((s[ch >> 3] & (0x1 << (ch & 0x7))) == 0)
return false;
cursor--;
return true;
}
protected internal virtual bool out_grouping(char[] s, int min, int max)
{
if (cursor >= limit)
return false;
char ch = current[cursor];
if (ch > max || ch < min)
{
cursor++;
return true;
}
ch -= (char) (min);
if ((s[ch >> 3] & (0x1 << (ch & 0x7))) == 0)
{
cursor++;
return true;
}
return false;
}
protected internal virtual bool out_grouping_b(char[] s, int min, int max)
{
if (cursor <= limit_backward)
return false;
char ch = current[cursor - 1];
if (ch > max || ch < min)
{
cursor--;
return true;
}
ch -= (char) (min);
if ((s[ch >> 3] & (0x1 << (ch & 0x7))) == 0)
{
cursor--;
return true;
}
return false;
}
protected internal virtual bool in_range(int min, int max)
{
if (cursor >= limit)
return false;
char ch = current[cursor];
if (ch > max || ch < min)
return false;
cursor++;
return true;
}
protected internal virtual bool in_range_b(int min, int max)
{
if (cursor <= limit_backward)
return false;
char ch = current[cursor - 1];
if (ch > max || ch < min)
return false;
cursor--;
return true;
}
protected internal virtual bool out_range(int min, int max)
{
if (cursor >= limit)
return false;
char ch = current[cursor];
if (!(ch > max || ch < min))
return false;
cursor++;
return true;
}
protected internal virtual bool out_range_b(int min, int max)
{
if (cursor <= limit_backward)
return false;
char ch = current[cursor - 1];
if (!(ch > max || ch < min))
return false;
cursor--;
return true;
}
protected internal virtual bool eq_s(int s_size, System.String s)
{
if (limit - cursor < s_size)
return false;
int i;
for (i = 0; i != s_size; i++)
{
if (current[cursor + i] != s[i])
return false;
}
cursor += s_size;
return true;
}
protected internal virtual bool eq_s_b(int s_size, System.String s)
{
if (cursor - limit_backward < s_size)
return false;
int i;
for (i = 0; i != s_size; i++)
{
if (current[cursor - s_size + i] != s[i])
return false;
}
cursor -= s_size;
return true;
}
protected internal virtual bool eq_v(System.Text.StringBuilder s)
{
return eq_s(s.Length, s.ToString());
}
protected internal virtual bool eq_v_b(System.Text.StringBuilder s)
{
return eq_s_b(s.Length, s.ToString());
}
protected internal virtual int find_among(Among[] v, int v_size)
{
int i = 0;
int j = v_size;
int c = cursor;
int l = limit;
int common_i = 0;
int common_j = 0;
bool first_key_inspected = false;
while (true)
{
int k = i + ((j - i) >> 1);
int diff = 0;
int common = common_i < common_j?common_i:common_j; // smaller
Among w = v[k];
int i2;
for (i2 = common; i2 < w.s_size; i2++)
{
if (c + common == l)
{
diff = - 1;
break;
}
diff = current[c + common] - w.s[i2];
if (diff != 0)
break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0)
break; // v->s has been inspected
if (j == i)
break; // only one item in v
// - but now we need to go round once more to get
// v->s inspected. This looks messy, but is actually
// the optimal approach.
if (first_key_inspected)
break;
first_key_inspected = true;
}
}
while (true)
{
Among w = v[i];
if (common_i >= w.s_size)
{
cursor = c + w.s_size;
if (w.method == null)
return w.result;
bool res;
try
{
System.Object resobj = w.method.Invoke(w.methodobject, (System.Object[]) new System.Object[0]);
// {{Aroush}} UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1043_3"'
res = resobj.ToString().Equals("true");
}
catch (System.Reflection.TargetInvocationException e)
{
res = false;
// FIXME - debug message
}
catch (System.UnauthorizedAccessException e)
{
res = false;
// FIXME - debug message
}
cursor = c + w.s_size;
if (res)
return w.result;
}
i = w.substring_i;
if (i < 0)
return 0;
}
}
// find_among_b is for backwards processing. Same comments apply
protected internal virtual int find_among_b(Among[] v, int v_size)
{
int i = 0;
int j = v_size;
int c = cursor;
int lb = limit_backward;
int common_i = 0;
int common_j = 0;
bool first_key_inspected = false;
while (true)
{
int k = i + ((j - i) >> 1);
int diff = 0;
int common = common_i < common_j?common_i:common_j;
Among w = v[k];
int i2;
for (i2 = w.s_size - 1 - common; i2 >= 0; i2--)
{
if (c - common == lb)
{
diff = - 1;
break;
}
diff = current[c - 1 - common] - w.s[i2];
if (diff != 0)
break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0)
break;
if (j == i)
break;
if (first_key_inspected)
break;
first_key_inspected = true;
}
}
while (true)
{
Among w = v[i];
if (common_i >= w.s_size)
{
cursor = c - w.s_size;
if (w.method == null)
return w.result;
bool res;
try
{
System.Object resobj = w.method.Invoke(w.methodobject, (System.Object[]) new System.Object[0]);
// {{Aroush}} UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1043_3"'
res = resobj.ToString().Equals("true");
}
catch (System.Reflection.TargetInvocationException e)
{
res = false;
// FIXME - debug message
}
catch (System.UnauthorizedAccessException e)
{
res = false;
// FIXME - debug message
}
cursor = c - w.s_size;
if (res)
return w.result;
}
i = w.substring_i;
if (i < 0)
return 0;
}
}
/* to replace chars between c_bra and c_ket in current by the
* chars in s.
*/
protected internal virtual int replace_s(int c_bra, int c_ket, System.String s)
{
int adjustment = s.Length - (c_ket - c_bra);
if (current.Length > bra)
current.Replace(current.ToString(bra, ket - bra), s, bra, ket - bra);
else
current.Append(s);
limit += adjustment;
if (cursor >= c_ket)
cursor += adjustment;
else if (cursor > c_bra)
cursor = c_bra;
return adjustment;
}
protected internal virtual void slice_check()
{
if (bra < 0 || bra > ket || ket > limit || limit > current.Length)
// this line could be removed
{
System.Console.Error.WriteLine("faulty slice operation");
// FIXME: report error somehow.
/*
fprintf(stderr, "faulty slice operation:\n");
debug(z, -1, 0);
exit(1);
*/
}
}
protected internal virtual void slice_from(System.String s)
{
slice_check();
replace_s(bra, ket, s);
}
protected internal virtual void slice_from(System.Text.StringBuilder s)
{
slice_from(s.ToString());
}
protected internal virtual void slice_del()
{
slice_from("");
}
protected internal virtual void insert(int c_bra, int c_ket, System.String s)
{
int adjustment = replace_s(c_bra, c_ket, s);
if (c_bra <= bra)
bra += adjustment;
if (c_bra <= ket)
ket += adjustment;
}
protected internal virtual void insert(int c_bra, int c_ket, System.Text.StringBuilder s)
{
insert(c_bra, c_ket, s.ToString());
}
/* Copy the slice into the supplied StringBuffer */
protected internal virtual System.Text.StringBuilder slice_to(System.Text.StringBuilder s)
{
slice_check();
int len = ket - bra;
//// s.Replace(s.ToString(0, s.Length - 0), current.ToString(bra, ket), 0, s.Length - 0);
s.Remove(0, s.Length);
s.Append(current.ToString(bra, ket));
return s;
}
protected internal virtual System.Text.StringBuilder assign_to(System.Text.StringBuilder s)
{
//// s.Replace(s.ToString(0, s.Length - 0), current.ToString(0, limit), 0, s.Length - 0);
s.Remove(0, s.Length);
s.Append(current.ToString(0, limit));
return s;
}
/*
extern void debug(struct SN_env * z, int number, int line_count)
{ int i;
int limit = SIZE(z->p);
//if (number >= 0) printf("%3d (line %4d): '", number, line_count);
if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit);
for (i = 0; i <= limit; i++)
{ if (z->lb == i) printf("{");
if (z->bra == i) printf("[");
if (z->c == i) printf("|");
if (z->ket == i) printf("]");
if (z->l == i) printf("}");
if (i < limit)
{ int ch = z->p[i];
if (ch == 0) ch = '#';
printf("%c", ch);
}
}
printf("'\n");
}*/
}
}