public interface GenericConstraints {
bool HasConstructor { get; }
- Type[] Types { get; }
+ bool IsReferenceType { get; }
+ bool IsValueType { get; }
+ bool HasClassConstraint { get; }
+ Type ClassConstraint { get; }
+ Type[] InterfaceConstraints { get; }
}
public interface ParameterData {
public class ReflectionParameters : ParameterData {
ParameterInfo [] pi;
bool last_arg_is_params = false;
+ bool is_varargs = false;
ParameterData gpd;
- public ReflectionParameters (MethodBase method)
+ public ReflectionParameters (MethodBase mb)
{
object [] attrs;
- this.pi = method.GetParameters ();
+ ParameterInfo [] pi = mb.GetParameters ();
+ is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0;
+
+ this.pi = pi;
int count = pi.Length-1;
if (count < 0)
return;
- if (method.HasGenericParameters) {
- MethodInfo generic = method.GetGenericMethodDefinition ();
- if (generic != method) {
- gpd = Invocation.GetParameterData (generic);
+ if (mb.Mono_IsInflatedMethod) {
+ MethodInfo generic = mb.GetGenericMethodDefinition ();
+ gpd = Invocation.GetParameterData (generic);
- last_arg_is_params = gpd.HasArrayParameter;
- return;
- }
+ last_arg_is_params = gpd.HasArrayParameter;
+ return;
}
attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
{
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)
{
int len = pi.Length;
- if (pos >= len - 1)
- if (last_arg_is_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;
}
}
protected class ReflectionConstraints : GenericConstraints
{
bool has_ctor;
- Type[] types;
+ bool is_reference_type;
+ bool is_value_type;
+ Type class_constraint;
+ Type[] iface_constraints;
- protected ReflectionConstraints (bool has_ctor, Type[] types)
+ protected ReflectionConstraints (bool has_ctor, Type class_constr,
+ Type[] iface_constrs)
{
this.has_ctor = has_ctor;
- this.types = types;
+ this.class_constraint = class_constr;
+ this.iface_constraints = iface_constrs;
+
+ if (class_constraint != null) {
+ if (class_constraint == TypeManager.object_type)
+ is_reference_type = true;
+ else if (class_constraint == TypeManager.value_type)
+ is_value_type = true;
+ }
}
public static GenericConstraints Create (Type t)
{
- Type[] types;
- Type[] ifaces = t.GetInterfaces ();
- if (t.BaseType != TypeManager.object_type) {
- types = new Type [ifaces.Length + 1];
- types [0] = t.BaseType;
- ifaces.CopyTo (types, 1);
- } else {
- types = new Type [ifaces.Length];
- ifaces.CopyTo (types, 0);
- }
+ Type class_constr = null;
+ Type[] iface_constrs = t.GetInterfaces ();
+ if (iface_constrs == null)
+ iface_constrs = Type.EmptyTypes;
+ if (t.BaseType != TypeManager.object_type)
+ class_constr = t.BaseType;
+
+ return new ReflectionConstraints (
+ false, class_constr, iface_constrs);
+ }
+
+ public bool HasConstructor {
+ get { return has_ctor; }
+ }
- if (types.Length == 0)
- return null;
+ public bool HasClassConstraint {
+ get { return class_constraint != null; }
+ }
- return new ReflectionConstraints (false, types);
+ public bool IsReferenceType {
+ get { return is_reference_type; }
}
- public bool HasConstructor {
- get {
- return has_ctor;
- }
+ public bool IsValueType {
+ get { return is_value_type; }
}
- public Type[] Types {
- get {
- return types;
- }
+ public Type ClassConstraint {
+ get { return class_constraint; }
+ }
+
+ public Type[] InterfaceConstraints {
+ get { return iface_constraints; }
}
}
}
public class InternalParameters : ParameterData {
Type [] param_types;
+ bool has_varargs;
+ int count;
public readonly 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 param_types.Length;
+ return has_varargs ? count + 1 : count;
}
}
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)
{
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
return;
}
+
+ if (value == 0) // Skip preamble
+ value = preamble_size;
// Ok, now we need to seek.
reader.DiscardBufferedData ();