public interface ParameterData {
Type ParameterType (int pos);
int Count { get; }
+ bool HasParams { get; }
string ParameterName (int pos);
string ParameterDesc (int pos);
Parameter.Modifier ParameterModifier (int pos);
public class ReflectionParameters : ParameterData {
ParameterInfo [] pi;
bool last_arg_is_params = false;
+ bool is_varargs = false;
- public ReflectionParameters (ParameterInfo [] pi)
+ public ReflectionParameters (MethodBase mb)
{
object [] attrs;
+
+ ParameterInfo [] pi = mb.GetParameters ();
+ is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0;
this.pi = pi;
int count = pi.Length-1;
{
if (last_arg_is_params && pos >= pi.Length - 1)
return pi [pi.Length - 1].ParameterType;
+ else if (is_varargs && pos >= pi.Length)
+ return TypeManager.runtime_argument_handle_type;
else {
Type t = pi [pos].ParameterType;
{
if (last_arg_is_params && pos >= pi.Length - 1)
return pi [pi.Length - 1].Name;
+ else if (is_varargs && pos >= pi.Length)
+ return "__arglist";
else
return pi [pos].Name;
}
public string ParameterDesc (int pos)
{
+ if (is_varargs && pos >= pi.Length)
+ return "";
+
StringBuilder sb = new StringBuilder ();
if (pi [pos].IsIn)
public Parameter.Modifier ParameterModifier (int pos)
{
- int len = pi.Length;
-
- if (pos >= len - 1)
- if (last_arg_is_params)
- return Parameter.Modifier.PARAMS;
+ if (last_arg_is_params && pos >= pi.Length - 1)
+ return Parameter.Modifier.PARAMS;
+ else if (is_varargs && pos >= pi.Length)
+ return Parameter.Modifier.ARGLIST;
Type t = pi [pos].ParameterType;
if (t.IsByRef){
public int Count {
get {
- return pi.Length;
+ return is_varargs ? pi.Length + 1 : pi.Length;
+ }
+ }
+
+ public bool HasParams {
+ get {
+ return this.last_arg_is_params;
}
}
public class InternalParameters : ParameterData {
Type [] param_types;
+ bool has_varargs;
+ int count;
public readonly Parameters Parameters;
{
this.param_types = param_types;
this.Parameters = parameters;
- }
- public InternalParameters (DeclSpace ds, Parameters parameters)
- : this (parameters.GetParameterInfo (ds), parameters)
- {
+ has_varargs = parameters.HasArglist;
+
+ if (param_types == null)
+ count = 0;
+ else
+ count = param_types.Length;
}
public int Count {
get {
- if (param_types == null)
- return 0;
+ return has_varargs ? count + 1 : count;
+ }
+ }
- return param_types.Length;
+ public bool HasParams {
+ get {
+ return Parameters.ArrayParameter != null;
}
}
public Type ParameterType (int pos)
{
+ if (has_varargs && pos >= count)
+ return TypeManager.runtime_argument_handle_type;
+
if (param_types == null)
return null;
public string ParameterName (int pos)
{
+ if (has_varargs && pos >= count)
+ return "__arglist";
+
return GetParameter (pos).Name;
}
public string ParameterDesc (int pos)
{
+ if (has_varargs && pos >= count)
+ return "__arglist";
+
string tmp = String.Empty;
Parameter p = GetParameter (pos);
public Parameter.Modifier ParameterModifier (int pos)
{
+ if (has_varargs && pos >= count)
+ return Parameter.Modifier.ARGLIST;
+
Parameter.Modifier mod = GetParameter (pos).ModFlags;
if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
}
}
- //
- // Compares member infos based on their name and
- // also allows one argument to be a string
- //
- class MemberInfoCompare : IComparer {
-
- public int Compare (object a, object b)
- {
- if (a == null || b == null){
- Console.WriteLine ("Invalid information passed");
- throw new Exception ();
- }
-
- if (a is string)
- return String.Compare ((string) a, ((MemberInfo)b).Name, false, CultureInfo.InvariantCulture);
-
- if (b is string)
- return String.Compare (((MemberInfo)a).Name, (string) b, false, CultureInfo.InvariantCulture);
-
- return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name, false, CultureInfo.InvariantCulture);
- }
- }
-
struct Pair {
public object First;
public object Second;
{
this.reader = reader;
this.buffer = new char [DefaultCacheSize];
+
+ // Compute the preamble size
+
+ // Let the StreamWriter autodetect the encoder
+ reader.Peek ();
+
+ reader.BaseStream.Position = 0;
+ Encoding enc = reader.CurrentEncoding;
+ // First of all, get at least a char
+
+ byte[] auxb = new byte [50];
+ int num_bytes = 0;
+ int num_chars = 0;
+ int br = 0;
+ do {
+ br = reader.BaseStream.Read (auxb, num_bytes, auxb.Length - num_bytes);
+ num_bytes += br;
+ num_chars = enc.GetCharCount (auxb, 0, num_bytes);
+ }
+ while (num_chars == 0 && br > 0);
+
+ if (num_chars != 0)
+ {
+ // Now, check which bytes at the beginning have no effect in the
+ // char count
+
+ int p = 0;
+ while (enc.GetCharCount (auxb, p, num_bytes-p) >= num_chars)
+ p++;
+
+ preamble_size = p - 1;
+ reader.BaseStream.Position = 0;
+ reader.DiscardBufferedData ();
+
+ buffer_start = preamble_size;
+ }
}
public SeekableStreamReader (Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks)
int buffer_size; // in bytes
int char_count; // count buffer[] valid characters
int pos; // index into buffer[]
+ int preamble_size;
/// <remarks>
/// The difference to the StreamReader's BaseStream.Position is that this one is reliable; ie. it
// buffer.
if ((value >= buffer_start) && (value < buffer_start + buffer_size)) {
int byte_offset = value - buffer_start;
+
+ // pos is an index into a char
+ // buffer so it might be
+ // greater than the buffer
+ // length now, if the buffer
+ // contains multibyte chars
pos = byte_offset;
- // encoded characters can take more than 1 byte length
- while (reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset)
+
+ // encoded characters can take
+ // more than 1 byte length.
+ while ((pos > buffer.Length) ||
+ reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset) {
pos--;
+ }
return;
}
+
+ if (value == 0) // Skip preamble
+ value = preamble_size;
// Ok, now we need to seek.
reader.DiscardBufferedData ();