private void _read() { _code = ((RubyMarshal.Codes)m_io.ReadU1()); switch (Code) { case RubyMarshal.Codes.PackedInt: { _body = new PackedInt(m_io, this, m_root); break; } case RubyMarshal.Codes.Bignum: { _body = new Bignum(m_io, this, m_root); break; } case RubyMarshal.Codes.RubyArray: { _body = new RubyArray(m_io, this, m_root); break; } case RubyMarshal.Codes.RubySymbolLink: { _body = new PackedInt(m_io, this, m_root); break; } case RubyMarshal.Codes.RubyStruct: { _body = new RubyStruct(m_io, this, m_root); break; } case RubyMarshal.Codes.RubyString: { _body = new RubyString(m_io, this, m_root); break; } case RubyMarshal.Codes.InstanceVar: { _body = new InstanceVar(m_io, this, m_root); break; } case RubyMarshal.Codes.RubyHash: { _body = new RubyHash(m_io, this, m_root); break; } case RubyMarshal.Codes.RubySymbol: { _body = new RubySymbol(m_io, this, m_root); break; } case RubyMarshal.Codes.RubyObjectLink: { _body = new PackedInt(m_io, this, m_root); break; } } }
/// <summary> /// static VALUE r_string(struct load_arg *arg) /// </summary> /// <returns></returns> public RubyString ReadString() { var raw = ReadBytes(); var v = new RubyString(raw); if (raw.Length > 2 && raw[0] == 120 && raw[1] == 156) { v.Encoding = Encoding.Default; } else { v.Encoding = Encoding.UTF8; } return(v); }
/// <summary> /// static ID r_symreal(struct load_arg *arg, int ivar) /// </summary> /// <param name="ivar"></param> /// <returns></returns> public RubySymbol ReadSymbolReal(bool ivar) { var s = ReadBytes(); var n = _m_symbols.Count; RubySymbol id; var idx = Encoding.UTF8; _m_symbols.Add(n, null); if (ivar) { var num = ReadLong(); while (num-- > 0) { id = ReadSymbol(); idx = GetEncoding(id, ReadObject()); } } var str = new RubyString(s, idx); id = RubySymbol.GetSymbol(str); _m_symbols[n] = id; return(id); }
/// <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 (_m_objects.TryGetValue(obj, out num)) { WriteByte(RubyMarshal.Types.LINK); WriteLong(num); return; } if (obj == null || obj == RubyNil.Instance) { WriteByte(RubyMarshal.Types.NIL); } else if (obj is bool && (bool)obj) { WriteByte(RubyMarshal.Types.TRUE); } else if (obj is bool && (bool)obj == false) { WriteByte(RubyMarshal.Types.FALSE); } else if (obj is RubyBool ruby_bool) { WriteByte(ruby_bool.Value ? RubyMarshal.Types.TRUE : RubyMarshal.Types.FALSE); } else if (obj is int || obj is long || obj is RubyFixnum) { long v; if (obj is int | obj is long) { v = (long)obj; } else { v = ((RubyFixnum)obj).Value; } // (2**30).class => Bignum // (2**30-1).class => Fixnum // (-2**30-1).class=> Bignum // (-2**30).class => Fixnum if (v <= RubyFixnum.MaxValue && v >= RubyFixnum.MinValue) { WriteByte(RubyMarshal.Types.FIXNUM); WriteLong((int)v); } else { WriteObject(RubyBignum.Create(v)); } } else if (obj is RubySymbol ruby_symbol) { WriteSymbol(ruby_symbol); } else { var fobj = obj as RubyObject; var hasiv = false; if (fobj != null) { hasiv = (obj is RubyArray || obj is RubyHash) && fobj.InstanceVariables.Count > 0; } if (fobj is RubyString ruby_string) { hasiv |= StringStyle == RubyMarshal.StringStyleType.Style19 && fobj.Encoding != null && ruby_string.Text.Length > 0; } if (obj is DefaultRubyUserDefinedMarshalDumpObject default_ruby_user_defined_marshal_dump_object) { if (hasiv) { WriteByte(RubyMarshal.Types.INSTANCE_VARIABLE); } WriteClass(RubyMarshal.Types.USER_MARSHAL, obj, false); default_ruby_user_defined_marshal_dump_object.Write(_m_writer); if (hasiv) { WriteObjectInstanceVariable(fobj); } _m_objects.Add(obj, _m_objects.Count); return; } if (obj is RubyUserDefinedObject ruby_user_defined_object) { if (hasiv) { WriteByte(RubyMarshal.Types.INSTANCE_VARIABLE); } _m_writer.Write(RubyMarshal.Types.USER_DEFINED); WriteSymbol(fobj.ClassName); ruby_user_defined_object.Write(_m_writer); if (hasiv) { WriteObjectInstanceVariable(fobj); } _m_objects.Add(obj, _m_objects.Count); return; } _m_objects.Add(obj, _m_objects.Count); if (hasiv) { WriteByte(RubyMarshal.Types.INSTANCE_VARIABLE); } if (obj is RubyClass ruby_class) { WriteByte(RubyMarshal.Types.CLASS); WriteCString(ruby_class.Name); } else if (obj is RubyModule ruby_module) { WriteByte(RubyMarshal.Types.MODULE); WriteCString(ruby_module.Name); } else if (obj is float _float) { WriteByte(RubyMarshal.Types.FLOAT); WriteFloat(_float); } else if (obj is double _double) { WriteByte(RubyMarshal.Types.FLOAT); WriteFloat(_double); } else if (obj is RubyFloat ruby_float) { WriteByte(RubyMarshal.Types.FLOAT); WriteFloat(ruby_float); } else if (obj is RubyBignum ruby_bignum) { char ch; if (ruby_bignum.Sign > 0) { ch = '+'; } else if (ruby_bignum.Sign < 0) { ch = '-'; } else { ch = '0'; } _m_writer.Write((byte)ch); var words = ruby_bignum.GetWords(); var num2 = words.Length * 2; var index = words.Length - 1; /* * var flag = false; * if (words.Length > 0 && words[index] >> 0x10 == 0) * { * num--; * flag = true; * }*/ var flag = words.Length > 0 && words[index] >> 0x10 == 0; WriteLong(num2); for (var i = 0; i < words.Length; i++) { if (flag && i == index) { _m_writer.Write((ushort)words[i]); } else { _m_writer.Write(words[i]); } } } else if (obj is RubyString || obj is string) { RubyString v; if (obj is string _string) { v = new RubyString(_string); } else { v = (RubyString)obj; } WriteUserClass(v, RubyClass.GetClass("String")); WriteByte(RubyMarshal.Types.STRING); WriteBytes(v.Raw); } else if (obj is RubyRegexp ruby_regexp) { WriteUserClass(obj, RubyClass.GetClass("Regexp")); WriteByte(RubyMarshal.Types.REGEXP); WriteBytes(ruby_regexp.pattern.Raw); WriteByte((byte)ruby_regexp.options); } else if (obj is RubyArray || obj is List <object> ) { RubyArray v; if (obj is List <object> list) { v = new RubyArray(list); } else { v = (RubyArray)obj; } WriteUserClass(v, RubyClass.GetClass("Array")); WriteByte(RubyMarshal.Types.ARRAY); WriteLong(v.Length); foreach (var t in v) { WriteObject(t); } } else if (obj is RubyHash ruby_hash) { WriteUserClass(obj, RubyClass.GetClass("Hash")); WriteByte(ruby_hash.DefaultValue != null ? RubyMarshal.Types.HASH_WITH_DEFAULT : RubyMarshal.Types.HASH); WriteLong(ruby_hash.Length); foreach (var item in ruby_hash) { WriteObject(item.Key); WriteObject(item.Value); } if (ruby_hash.DefaultValue != null) { WriteObject(ruby_hash.DefaultValue); } } else if (obj is RubyStruct ruby_struct) { WriteUserClass(obj, RubyClass.GetClass("Struct")); WriteLong(ruby_struct.InstanceVariables.Count); foreach (var item in ruby_struct.InstanceVariables) { WriteObject(item.Key); WriteObject(item.Value); } } else if (obj is RubyObject ruby_object) { WriteClass(RubyMarshal.Types.OBJECT, obj, true); WriteObjectInstanceVariable(ruby_object); } else { throw new InvalidDataException($"can't dump {obj.GetType().FullName}"); } if (hasiv) { WriteInstanceVariable(fobj, fobj.InstanceVariables); } } }
public static string TransformToNativeModel(this RubyString self) { return(self.Text); }