Esempio n. 1
0
        internal static void w_object(object obj, dump_arg arg, int limit, Frame caller)
        {
            dump_call_arg c_arg = new dump_call_arg();
            System.Collections.Generic.Dictionary<string, object> ivtbl = null; 
            //    st_data_t num;

            if (limit == 0)
            {
                throw new ArgumentError("exceed depth limit").raise(caller);
            }

            limit--;
            c_arg.limit = limit;
            c_arg.arg = arg;

            if (obj != null && arg.data.ContainsKey(obj))
            {
                int num = arg.data[obj];
                w_byte(TYPE_LINK, arg, caller);
                w_long(num, arg, caller);
                return;
            }
                               
            ivtbl = Object.get_generic_ivars(obj);
            if (ivtbl != null)
            {
                w_byte(TYPE_IVAR, arg, caller);
            }

            if (obj == null)
            {
                w_byte(TYPE_NIL, arg, caller);
            }
            else if (obj is bool && (bool)obj == true)
            {
                w_byte(TYPE_TRUE, arg, caller);
            }
            else if (obj is bool && (bool)obj == false)
            {
                w_byte(TYPE_FALSE, arg, caller);
            }
            else if (obj is int)
            {
                w_byte((char)TYPE_FIXNUM, arg, caller);
                w_long((int)obj, arg, caller);
            }
            else if (obj is Symbol)
            {
                //FIXME: This code isn't being reached at the moment.
                //should be ok since the latest fixes - haven't tested this though
                w_symbol((int)((Symbol)obj).id_new, arg, caller);
            }
            else
            {
                if (((Basic)obj).Tainted)
                {
                    arg.taint = true;
                }

                arg.data[obj] = arg.data.Count;

                if (Eval.RespondTo(obj, s_mdump))
                {
                    object v;

                    v = Eval.CallPublic0(obj, caller, s_mdump, null);
                    w_class(TYPE_USRMARSHAL, obj, arg, false, caller);
                    w_object(v, arg, limit, caller);
                    if (ivtbl != null) w_ivar(null, c_arg, caller);
                    return;
                }
                if (Eval.RespondTo(obj, s_dump)) //TEST:
                {
                    object v;

                    v = Eval.CallPrivate(obj, caller, s_dump, null, limit);
                    if (!(v is String))
                    {
                        throw new TypeError("_dump() must return string").raise(caller);
                    }

                    if (ivtbl == null && (ivtbl = Object.get_generic_ivars(v)) != null)
                    {
                        w_byte(TYPE_IVAR, arg, caller);
                    }
                    w_class(TYPE_USERDEF, obj, arg, false, caller);
                    w_bytes(((String)v).value, ((String)v).value.Length, arg, caller);
                    if (ivtbl != null)
                    {
                        w_ivar(ivtbl, c_arg, caller);
                    }
                    return;              
                }


                if (obj is Class)
                {
                    if (((Class)obj)._type == Class.Type.Class)
                    {
                        if (((Class)obj)._type == Class.Type.Singleton)
                        {
                            throw new TypeError("singleton class can't be dumped").raise(caller);
                        }
                        w_byte(TYPE_CLASS, arg, caller);
                        {
                            object path = class2path(obj, caller);
                            w_bytes(((String)path).value, ((String)path).value.Length, arg, caller);
                        }
                    }
                    else if (((Class)obj)._type == Class.Type.Module)//TEST:
                    {
                        w_byte(TYPE_MODULE, arg, caller);
                        {
                            object path = class2path(obj, caller);
                            w_bytes(((String)path).value, ((String)path).value.Length, arg, caller);
                        }
                    }
                }
                else if (obj is Float)
                {
                    w_byte((char)TYPE_FLOAT, arg, caller);
                    w_float(((Float)obj).value, arg, caller);
                }
                else if (obj is Bignum)
                {
                    w_byte((char)TYPE_BIGNUM, arg, caller);
                    {
                        char sign = ((Bignum)(obj)).value.Sign < 0 ? '-' : '+';
                        long len = ((Bignum)(obj)).value.length;
                        uint[] d = ((Bignum)(obj)).value.Data;

                        w_byte((char)sign, arg, caller);
                        w_long(shortlen(len, d), arg, caller); /* w_short? */
                        int dIndex = 0;
                        while (len-- > 0)
                        {
                            uint num = d[dIndex];
                            int i;

                            for (i = 0; i < SIZEOF_BDIGITS; i += SIZEOF_SHORT)
                            {
                                w_short((int)num & SHORTMASK, arg, caller);
                                num = num >> BITSPERSHORT;
                                if (len == 0 && num == 0) break;
                            }
                            dIndex++;
                        }
                    }
                }
                else if (obj is Struct)
                {
                    w_class(TYPE_STRUCT, obj, arg, true, caller);
                    {
                        int len;
                        object mem;

                        len = StructLen(obj, caller);
                        mem = rb_struct_members(obj, caller);

                        w_long(len, arg, caller);
                        for (int i = 0; i < len; i++)
                        {
                            string symbolString = (string)((Array)mem).value[i]; //no interning atm
                            w_symbol((int)Symbol.rb_intern(symbolString), arg, caller);
                            w_object(((Struct)obj).instance_vars[symbolString], arg, limit, caller);
                        }
                    }
                }

                else if (obj is String)
                {
                    w_uclass(obj, Ruby.Runtime.Init.rb_cString, arg, caller);
                    w_byte((char)TYPE_STRING, arg, caller);
                    w_bytes(((String)obj).value, ((String)obj).value.Length, arg, caller);
                }
                else if (obj is Regexp)
                {
                    w_uclass(obj, Ruby.Runtime.Init.rb_cRegexp, arg, caller);
                    w_byte(TYPE_REGEXP, arg, caller);
                    string regExpStr = ((Regexp)obj).value.ToString();
                    w_bytes(regExpStr, regExpStr.Length, arg, caller);
                    w_byte((char)Regexp.rb_reg_options(caller, (Regexp)obj), arg, caller);
                }
                else if (obj is Array)
                {
                    w_uclass(obj, Ruby.Runtime.Init.rb_cArray, arg, caller);
                    w_byte((char)TYPE_ARRAY, arg, caller);
                    {
                        int len = ((Array)obj).Count;
                        System.Collections.ArrayList ptr = ((Array)obj).value;
                        w_long(len, arg, caller);
                        foreach (object arrObj in ptr)
                        {
                            w_object(arrObj, arg, limit, caller);
                        }
                    }
                }
                else if (obj is Hash)
                {
                    w_uclass(obj, Ruby.Runtime.Init.rb_cHash, arg, caller);
                    if (((Hash)obj).defaultProc != null)
                        throw new TypeError("cannot dump hash with default proc").raise(caller);
                    else if (((Hash)obj).defaultValue == null)
                        w_byte(TYPE_HASH, arg, caller);
                    else
                        w_byte(TYPE_HASH_DEF, arg, caller);
                    w_long(((Hash)(obj)).value.Count, arg, caller);
                    foreach (HashKeyValuePair pair in ((Hash)obj).value)
                    {
                        w_object(pair.Key.key, c_arg.arg, c_arg.limit, caller);
                        w_object(pair.Value, c_arg.arg, c_arg.limit, caller);
                    }
                    if (((Hash)obj).defaultValue != null)
                        w_object(((Hash)obj).defaultValue, arg, limit, caller);
                }
                else if (obj is Data) //TEST:
                {               
                    object v;
                        
                    w_class(TYPE_DATA, obj, arg, true, caller);
                    if (!Eval.RespondTo(obj, s_dump_data))
                        throw new TypeError(string.Format(CultureInfo.InvariantCulture, "no marshal_dump is defined for class {0}", rb_obj_classname(obj, caller))).raise(caller);

                    v = Eval.CallPrivate0(obj, caller, s_dump_data, null);
                    w_object(v, arg, limit, caller);
                }
                else if (obj is Object)//TEST:
                {
                    w_class(TYPE_OBJECT, obj, arg, true, caller);
                    w_ivar(((Object)obj).instance_vars, c_arg, caller);
                }
                else
                    throw new TypeError(string.Format(CultureInfo.InvariantCulture, "can't dump {0}", ((Basic)obj).my_class.classname())).raise(caller);
            }

            if (ivtbl != null)
            {
                w_ivar(ivtbl, c_arg, caller);
            }
        }
Esempio n. 2
0
        internal static void w_extended(Class klass, dump_arg arg, bool check, Frame caller)
        {
            string path; 

            if (klass._type == Class.Type.Singleton)
            {
                if (check && klass._methods.Count > 0 ||
                    (klass.instance_vars.Count > 0))
                {
                    throw new TypeError("singleton can't be dumped").raise(caller);
                }
                klass = klass.super;
            }
            while (klass._type == Class.Type.IClass) //TEST:
            {
                path = rb_class2name(((Basic)klass).my_class, caller);
                w_byte(TYPE_EXTENDED, arg, caller);
                w_unique(path, arg, caller);
                klass = ((Class)klass).super;
            }
        }
Esempio n. 3
0
        internal static void w_class(char type, object obj, dump_arg arg, bool check, Frame caller)
        {
            string path;

            object klass = Class.CLASS_OF(obj);
            w_extended((Class)klass, arg, check, caller);
            w_byte(type, arg, caller);
            path = ((String)class2path(((Class)klass).class_real(), caller)).value;
            w_unique(path, arg, caller);
        }
Esempio n. 4
0
 internal static void w_unique(string s, dump_arg arg, Frame caller)
 {
     if (s.Length > 0 && s[0] == '#')
     {
         throw new TypeError(string.Format(CultureInfo.InvariantCulture, "can't dump anonymous class {0}", s)).raise(caller);
     }
     w_symbol((int)Symbol.rb_intern(s), arg, caller);
 }
Esempio n. 5
0
        internal static void w_uclass(object obj, Class base_klass, dump_arg arg, Frame caller)
        {
            Class klass = Class.CLASS_OF(obj);

            w_extended(klass, arg, true, caller);
            klass = klass.class_real();
            if (klass != base_klass)
            {
                w_byte((char)TYPE_UCLASS, arg, caller);
                w_unique(klass.classname(), arg, caller);
            }
        }
Esempio n. 6
0
 internal static void w_float(double d, dump_arg arg, Frame caller)
 {
     System.Text.StringBuilder buf = new System.Text.StringBuilder();
     if (double.IsInfinity(d))
     {
         if (double.IsNegativeInfinity(d))
         {
             buf.Append("-inf");
         }
         else
         {
             buf.Append("inf");
         }
     }
     else if (double.IsNaN(d))
     {
         buf.Append("nan");
     }
     else if (d == 0.00)
     {
         if (1.0 / d < 0)//TEST: will this behave correctly in C#???
         {
             buf.Append("-0");
         }
         else
         {
             buf.Append("0");
         }
     }
     else
     {
         int len;
         buf.Append(d.ToString("r", CultureInfo.InvariantCulture));
         len = buf.Length;
         char[] bufArray = new char[20];
         int manLength = save_mantissa(d, bufArray);
         len += manLength;
         buf.Append(new System.String(bufArray, 0, manLength));
         w_bytes(buf.ToString(), len, arg, caller);
         return;
     }
     string bufString = buf.ToString();
     w_bytes(bufString, bufString.Length, arg, caller);
 }
Esempio n. 7
0
        internal static void w_symbol(int id, dump_arg arg, Frame caller)
        {
            string sym = Symbol.rb_id2name((uint) id);
            int num;

            if (arg.symbols.ContainsKey(id))
            {
                num = arg.symbols[id];
                w_byte(TYPE_SYMLINK, arg, caller);
                w_long(num, arg, caller);
            }
            else
            {
                w_byte(TYPE_SYMBOL, arg, caller);
                w_bytes(sym, sym.Length, arg, caller);
                arg.symbols.Add(id, arg.symbols.Count);
            }
        }
Esempio n. 8
0
 internal static void w_short(int x, dump_arg arg, Frame caller)
 {
     w_byte((char)((x >> 0) & 0xff), arg, caller);
     w_byte((char)((x >> 8) & 0xff), arg, caller);
 }
Esempio n. 9
0
        internal static void w_long(int x, dump_arg arg, Frame caller)
        {
            int sizeOfInt = 4;
            char[] buf = new char[sizeOfInt + 1];
            int i = 0;
            int len = 0;

            if (x == 0)
            {
                w_byte((char)0, arg, caller);
                return;
            }
            if (0 < x && x < 123)
            {
                w_byte((char)(x + 5), arg, caller);
                return;
            }
            if (-124 < x && x < 0)
            {
                w_byte((char)((x - 5) & 0xff), arg, caller);
                return;
            }
            for (i = 1; i < sizeOfInt + 1; i++)
            {
                buf[i] = (char)(x & 0xff);
                x = x >> 8;
                if (x == 0)
                {
                    buf[0] = (char)(byte)i;
                    break;
                }

                if (x == 0)
                {
                    buf[0] = (char)(byte)i;
                    break;
                }
                if (x == -1)
                {
                    buf[0] = (char)(byte)-i;
                    break;
                }
            }
            len = i;
            for (i = 0; i <= len; i++)
            {
                w_byte(buf[i], arg, caller);
            }
        }
Esempio n. 10
0
 internal static void w_bytes(string s, int n, dump_arg arg, Frame caller)
 {
     w_long(n, arg, caller);
     w_nbyte(s, n, arg, caller);
 }
Esempio n. 11
0
 internal static void w_nbyte(string s, int n, dump_arg arg, Frame caller)
 {
     object buf = arg.str;
     ((String)buf).value = ((String)buf).value + s.Substring(0, n);
     if (arg.dest != null && ((String)buf).value.Length >= BUFSIZ)
     {
         if (arg.taint)
         {
             ((Basic)buf).Tainted = true;
         }
         rb_io_write(arg.dest, buf, caller);
         ((String)buf).value = "";
     }
 }
Esempio n. 12
0
        //----------------------------------------------------------------------------------

        internal static void w_byte(char c, dump_arg arg, Frame caller)
        {
            w_nbyte(c.ToString(), 1, arg, caller);
        }
Esempio n. 13
0
 internal static object dump_ensure(dump_arg arg)
 {
     arg.symbols = null;
     arg.data = null; 
     if (arg.taint)
     {
         ((Basic)arg.str).Tainted = true;
     }
     return null;
 }
Esempio n. 14
0
 internal dump_call_arg()
 {
     obj = null;
     arg = null;
     limit = 0;
 }