예제 #1
0
        /// <summary>
        /// static void w_object(VALUE obj, struct dump_arg *arg, int limit)
        /// </summary>
        /// <param name="obj"></param>
        public void WriteObject(object obj)
        {
            int num;

            if (this.m_objects.TryGetValue(obj, out num))
            {
                WriteByte(RubyMarshal.Types.Link);
                WriteLong(num);
                return;
            }
            if (obj == null || obj == FuzzyNil.Instance)
            {
                WriteByte(RubyMarshal.Types.Nil);
            }
            else if (obj is bool && (bool)obj == true)
            {
                WriteByte(RubyMarshal.Types.True);
            }
            else if (obj is bool && (bool)obj == false)
            {
                WriteByte(RubyMarshal.Types.False);
            }
            else if (obj is FuzzyBool && (obj as FuzzyBool).Value)
            {
                WriteByte(RubyMarshal.Types.True);
            }
            else if (obj is FuzzyBool && !(obj as FuzzyBool).Value)
            {
                WriteByte(RubyMarshal.Types.False);
            }
            else if (obj is int || obj is long || obj is FuzzyFixnum)
            {
                long v;
                if (obj is int | obj is long)
                {
                    v = (long)obj;
                }
                else
                {
                    v = (obj as FuzzyFixnum).Value;
                }
                // (2**30).class   => Bignum
                // (2**30-1).class => Fixnum
                // (-2**30-1).class=> Bignum
                // (-2**30).class  => Fixnum
                if (v <= 1073741823 && v >= -1073741824)
                {
                    WriteByte(RubyMarshal.Types.Fixnum);
                    WriteLong((int)v);
                }
                else
                {
                    WriteObject(FuzzyBignum.Create(v));
                }
            }
            else if (obj is FuzzySymbol)
            {
                WriteSymbol(obj as FuzzySymbol);
            }
            else
            {
                FuzzyObject fobj  = obj as FuzzyObject;
                bool        hasiv = false;
                if (fobj != null)
                {
                    hasiv = (obj as FuzzyObject).InstanceVariables.Count > 0 || fobj.Encoding != null;
                }
                var factor = Serialization.Factory <byte[]> .Factor(fobj.GetType());

                if (factor != null)
                {
                    WriteSymbol(fobj.ClassName);
                    factor.dump(m_stream, fobj, null);
                }
                if (obj is IRubyUserdefinedMarshalDumpObject)
                {
                    this.m_objects.Add(obj, this.m_objects.Count);
                    object result = (obj as IRubyUserdefinedMarshalDumpObject).Dump();
                    if (hasiv)
                    {
                        WriteByte(RubyMarshal.Types.InstanceVariable);
                    }
                    WriteClass(RubyMarshal.Types.UserMarshal, obj, false);
                    WriteObject(result);
                    if (hasiv)
                    {
                        WriteObjectInstanceVariable(fobj);
                    }
                    return;
                }
                if (obj is IRubyUserdefinedDumpObject)
                {
                    byte[] result = (obj as IRubyUserdefinedDumpObject).Dump();
                    if (hasiv)
                    {
                        WriteByte(RubyMarshal.Types.InstanceVariable);
                    }
                    WriteClass(RubyMarshal.Types.UserDefined, obj, false);
                    WriteBytes(result, result.Length);
                    if (hasiv)
                    {
                        WriteObjectInstanceVariable(fobj);
                    }
                    this.m_objects.Add(obj, this.m_objects.Count);
                    return;
                }

                this.m_objects.Add(obj, this.m_objects.Count);


                if (hasiv)
                {
                    WriteByte(RubyMarshal.Types.InstanceVariable);
                }

                if (obj is FuzzyClass)
                {
                    WriteByte(RubyMarshal.Types.Class);
                    WriteCString((obj as FuzzyClass).Name);
                }
                else if (obj is FuzzyModule)
                {
                    WriteByte(RubyMarshal.Types.Module);
                    WriteCString((obj as FuzzyModule).Name);
                }
                else if (obj is float)
                {
                    WriteByte(RubyMarshal.Types.Float);
                    WriteFloat((float)obj);
                }
                else if (obj is double)
                {
                    WriteByte(RubyMarshal.Types.Float);
                    WriteFloat((double)obj);
                }
                else if (obj is FuzzyFloat)
                {
                    WriteByte(RubyMarshal.Types.Float);
                    WriteFloat((FuzzyFloat)obj);
                }
                else if (obj is FuzzyBignum || obj is FuzzyBignumAdapter)
                {
                    FuzzyBignum value;
                    if (obj is FuzzyBignumAdapter)
                    {
                        value = (obj as FuzzyBignumAdapter).Value;
                    }
                    else
                    {
                        value = (FuzzyBignum)obj;
                    }
                    char ch;
                    if (value.Sign > 0)
                    {
                        ch = '+';
                    }
                    else if (value.Sign < 0)
                    {
                        ch = '-';
                    }
                    else
                    {
                        ch = '0';
                    }
                    this.m_writer.Write((byte)ch);
                    uint[] words = value.GetWords();
                    int    num2  = words.Length * 2;
                    int    index = words.Length - 1;
                    bool   flag  = false;
                    if ((words.Length > 0) && ((words[index] >> 0x10) == 0))
                    {
                        num--;
                        flag = true;
                    }
                    this.WriteLong(num2);
                    for (int i = 0; i < words.Length; i++)
                    {
                        if (flag && (i == index))
                        {
                            this.m_writer.Write((ushort)words[i]);
                        }
                        else
                        {
                            this.m_writer.Write(words[i]);
                        }
                    }
                }
                else if (obj is FuzzyString || obj is string)
                {
                    FuzzyString v;
                    if (obj is string)
                    {
                        v = new FuzzyString(obj as string);
                    }
                    else
                    {
                        v = (FuzzyString)obj;
                    }
                    WriteUserClass(v, FuzzyClass.GetClass("String"));
                    WriteByte(RubyMarshal.Types.String);
                    WriteBytes(v.Raw);
                }
                else if (obj is FuzzyRegexp)
                {
                    FuzzyRegexp v = (FuzzyRegexp)obj;
                    WriteUserClass(obj, FuzzyClass.GetClass("Regexp"));
                    WriteByte(RubyMarshal.Types.Regexp);
                    WriteBytes(v.Pattern.Raw);
                    WriteByte((byte)v.Options);
                }
                else if (obj is FuzzyArray || obj is List <object> )
                {
                    FuzzyArray v;
                    if (obj is List <object> )
                    {
                        v = new FuzzyArray(obj as List <object>);
                    }
                    else
                    {
                        v = (FuzzyArray)obj;
                    }
                    WriteUserClass(v, FuzzyClass.GetClass("Array"));
                    WriteByte(RubyMarshal.Types.Array);
                    WriteLong(v.Length);
                    for (int i = 0; i < v.Count; i++)
                    {
                        WriteObject(v[i]);
                    }
                }
                else if (obj is FuzzyHash)
                {
                    FuzzyHash v = (FuzzyHash)obj;
                    WriteUserClass(obj, FuzzyClass.GetClass("Hash"));
                    WriteByte(v.DefaultValue != null ? RubyMarshal.Types.HashWithDefault : RubyMarshal.Types.Hash);
                    WriteLong(v.Length);
                    foreach (KeyValuePair <object, object> item in v)
                    {
                        WriteObject(item.Key);
                        WriteObject(item.Value);
                    }
                    if (v.DefaultValue != null)
                    {
                        WriteObject(v.DefaultValue);
                    }
                }
                else if (obj is FuzzyStruct)
                {
                    FuzzyStruct v = (FuzzyStruct)obj;
                    WriteUserClass(obj, FuzzyClass.GetClass("Struct"));
                    WriteLong(v.InstanceVariables.Count);
                    foreach (KeyValuePair <FuzzySymbol, object> item in v.InstanceVariables)
                    {
                        WriteObject(item.Key);
                        WriteObject(item.Value);
                    }
                }
                else if (obj is FuzzyObject)
                {
                    WriteClass(RubyMarshal.Types.Object, obj, true);
                    WriteObjectInstanceVariable((FuzzyObject)obj);
                }
                else
                {
                    throw new InvalidDataException(string.Format("can't dump {0}", obj.GetType().FullName));
                }
                if (hasiv)
                {
                    WriteInstanceVariable(fobj, fobj.InstanceVariables);
                }
            }
        }
예제 #2
0
        public void WriteObject(object obj)
        {
            int num;

            if (this.x_objects.TryGetValue(obj, out num))
            {
                WriteNode(XML.Types.Link, num.ToString());
                return;
            }
            if (obj == null || obj == FuzzyNil.Instance)
            {
                WriteNode(XML.Types.Nil, "");
            }
            else if (obj is bool && (bool)obj == true)
            {
                WriteNode(XML.Types.True, "");
            }
            else if (obj is bool && (bool)obj == false)
            {
                WriteNode(XML.Types.False, "");
            }
            else if (obj is int || obj is long || obj is FuzzyFixnum)
            {
                long v;
                if (obj is FuzzyFixnum)
                {
                    v = (obj as FuzzyFixnum).Value;
                }
                else
                {
                    v = (long)obj;
                }
                if (v <= 1073741823 && v >= -1073741824)
                {
                    WriteNode(XML.Types.Fixnum, obj.ToString());
                }
                else
                {
                    WriteObject(FuzzyBignum.Create(v));
                }
            }
            else if (obj is FuzzySymbol)
            {
                WriteSymbol(obj as FuzzySymbol);
            }
            else
            {
                FuzzyObject fobj  = obj as FuzzyObject;
                bool        hasiv = false;
                if (fobj != null)
                {
                    hasiv = (obj as FuzzyObject).InstanceVariables.Count > 0 || fobj.Encoding != null;
                }
                if (obj is IXMLUserdefinedDumpObject)
                {
                    this.x_objects.Add(obj, this.x_objects.Count);
                    object result = (obj as IXMLUserdefinedMarshalDumpObject).Dump();
                    WritePopNode(XML.Types.UserMarshal, "");
                    WriteObject(result);
                    x_parent_node.Pop();
                    return;
                }
                if (obj is IXMLUserdefinedDumpObject)
                {
                    XmlNode result = (obj as IXMLUserdefinedDumpObject).Dump();
                    WritePopNode(XML.Types.UserDefined, "").AppendChild(result);
                    this.x_objects.Add(obj, this.x_objects.Count);
                    return;
                }
                this.x_objects.Add(obj, this.x_objects.Count);
                if (obj is FuzzyClass)
                {
                    WriteNode(XML.Types.Class, (obj as FuzzyClass).Name);
                }
                else if (obj is FuzzyModule)
                {
                    WriteNode(XML.Types.Module, (obj as FuzzyClass).Name);
                }
                else if (obj is float)
                {
                    WriteFloat((float)obj);
                }
                else if (obj is double)
                {
                    WriteFloat((double)obj);
                }
                else if (obj is FuzzyFloat)
                {
                    WriteFloat((obj as FuzzyFloat).Value);
                }
                else if (obj is FuzzyBignum)
                {
                    WriteNode(XML.Types.Bignum, obj.ToString());
                }
                else if (obj is FuzzyBignumAdapter)
                {
                    WriteNode(XML.Types.Bignum, (obj as FuzzyBignumAdapter).Value.ToString());
                }
                else if (obj is FuzzyString || obj is string)
                {
                    FuzzyString v;
                    if (obj is string)
                    {
                        v = new FuzzyString(obj as string);
                    }
                    else
                    {
                        v = (FuzzyString)obj;
                    }
                    WritePopNode(XML.Types.String);
                    WriteString(v.Text, v.Encoding);
                    x_parent_node.Pop();
                }
                else if (obj is FuzzyRegexp)
                {
                    FuzzyRegexp v = (FuzzyRegexp)obj;
                    WritePopNode(XML.Types.Regexp);
                    WriteString(v.Pattern.Text, v.Pattern.Encoding);
                    WriteNode("Options", ((int)v.Options).ToString());
                }
                else if (obj is FuzzyArray || obj is List <object> )
                {
                    FuzzyArray v;
                    if (obj is List <object> )
                    {
                        v = new FuzzyArray(obj as List <object>);
                    }
                    else
                    {
                        v = (FuzzyArray)obj;
                    }
                    WritePopNode(XML.Types.Array);
                    for (int i = 0; i < v.Count; i++)
                    {
                        WriteObject(v[i]);
                    }
                    x_parent_node.Pop();
                }
                else if (obj is FuzzyHash)
                {
                    FuzzyHash v = (FuzzyHash)obj;
                    if (v.DefaultValue == null)
                    {
                        WritePopNode(XML.Types.Hash);
                    }
                    else
                    {
                        WritePopNode(XML.Types.HashWithDefault);
                        WritePopNode("Default");
                        WriteObject(v.DefaultValue);
                        x_parent_node.Pop();
                    }
                    foreach (KeyValuePair <object, object> item in v)
                    {
                        WriteObject(item.Key);
                        WriteObject(item.Value);
                    }
                    x_parent_node.Pop();
                }

                else if (obj is FuzzyObject || obj is FuzzyStruct)
                {
                    FuzzyObject v = fobj;
                    if (obj is FuzzyObject)
                    {
                        WritePopNode(XML.Types.Object);
                    }
                    else
                    {
                        WritePopNode(XML.Types.Struct);
                    }
                    if (XML.Options.IgnoreSymbolEncoding)
                    {
                        WriteAttribute("Name", v.ClassName.Name);
                        foreach (KeyValuePair <FuzzySymbol, object> item in v.InstanceVariables)
                        {
                            WritePopNode("Data");
                            WriteAttribute("Name", item.Key.Name);
                            WriteObject(item.Value);
                            x_parent_node.Pop();
                        }
                    }
                    else
                    {
                        var factor = Serialization.Factory <XmlNode> .Factor(fobj.GetType());

                        if (factor == null)
                        {
                            factor = Serialization.Factory <XmlNode> .Factor(fobj.ClassName.Name);
                        }
                        if (factor != null)
                        {
                            WritePopNode(XML.Types.UserDefined);
                            XmlNode node = factor.dump(x_stream, fobj, null);
                            node = x_document.ImportNode(node, true);
                            x_parent_node.Pop().AppendChild(node);
                        }
                        else
                        {
                            WritePopNode("Name");
                            WriteObject(v.ClassName);
                            x_parent_node.Pop();
                            foreach (KeyValuePair <FuzzySymbol, object> item in v.InstanceVariables)
                            {
                                WriteSymbol(item.Key);
                                WriteObject(item.Value);
                            }
                        }
                    }
                    x_parent_node.Pop();
                }
                else
                {
                    throw new InvalidDataException(string.Format("can't dump {0}", obj.GetType().FullName));
                }
            }
        }