/// <summary> /// static void w_ivar(VALUE obj, st_table *tbl, struct dump_call_arg *arg) /// </summary> /// <param name="obj"></param> public void WriteInstanceVariable(RubyObject obj, Dictionary <RubySymbol, object> tbl) { var num = tbl?.Count ?? 0; if (tbl != null && tbl.ContainsKey(RubyMarshal.Ds.encoding) && num > 0) { num -= 1; } if (tbl != null && tbl.ContainsKey(RubyMarshal.Ds.e) && num > 0) { num -= 1; } WriteEncoding(obj, num); if (tbl == null) { return; } foreach (var item in tbl) { if (item.Key == RubyMarshal.Ds.encoding) { continue; } if (item.Key == RubyMarshal.Ds.e) { continue; } WriteSymbol(item.Key); WriteObject(item.Value); } }
public static RubyObject Decode(BinaryReader reader) { var ruby = new RubyObject { Properties = new Dictionary <string, RubyToken>(5) { ["reserved"] = new RubyValue(reader.ReadInt32()), ["xsize"] = new RubyValue(reader.ReadInt32()), ["ysize"] = new RubyValue(reader.ReadInt32()), ["zsize"] = new RubyValue(reader.ReadInt32()) } }; var size = reader.ReadInt32(); var data = new RubyArray { Array = new List <RubyToken>(size) }; for (var index = 0; index < size; index++) { data.Array.Add(new RubyValue(reader.ReadInt16())); } ruby.Properties["data"] = data; return(ruby); }
public static byte[] Encode(RubyObject ruby) { var xsize = ruby["xsize"].GetValue <int>(); var ysize = ruby["ysize"].GetValue <int>(); var zsize = ruby["zsize"].GetValue <int>(); var size = xsize * ysize * zsize; var bytes = new byte[size * 2 + 20]; using (var stream = new MemoryStream(bytes)) { using (var writer = new BinaryWriter(stream)) { writer.Write(ruby["reserved"].GetValue <int>()); writer.Write(xsize); writer.Write(ysize); writer.Write(zsize); writer.Write(size); foreach (var value in ruby["data"]) { writer.Write(value.GetValue <short>()); } } } return(bytes); }
public static object TransformToNativeModel(this RubyObject self) { object result = null; if (self is RubyArray ruby_array) { result = ruby_array.TransformToNativeModel(); } else if (self is RubyBignum ruby_bignum) { result = ruby_bignum.TransformToNativeModel(); } else if (self is RubyBool ruby_bool) { result = ruby_bool.TransformToNativeModel(); } else if (self is RubyClass ruby_class) { result = ruby_class.TransformToNativeModel(); } else if (self is RubyFixnum ruby_fixnum) { result = ruby_fixnum.TransformToNativeModel(); } else if (self is RubyFloat ruby_float) { result = ruby_float.TransformToNativeModel(); } else if (self is RubyHash ruby_hash) { result = ruby_hash.TransformToNativeModel(); } else if (self is RubyNil ruby_nil) { result = ruby_nil.TransformToNativeModel(); } else if (self is RubyRegexp ruby_regexp) { result = ruby_regexp.TransformToNativeModel(); } else if (self is RubyString ruby_string) { result = ruby_string.TransformToNativeModel(); } else if (self is RubyStruct ruby_struct) { result = ruby_struct.TransformToNativeModel(); } else if (self is RubySymbol ruby_symbol) { result = ruby_symbol.TransformToNativeModel(); } else if (self is RubyUserDefinedObject ruby_user_defined) { result = ruby_user_defined.TransformToNativeModel(); } return(result); }
public RubyObject ToRubyObject() { RubyObject obj = new RubyObject(); obj.ClassName = RubySymbol.GetSymbol("RPG::AudioFile"); obj.InstanceVariable["@name"] = this.Name; obj.InstanceVariable["@volume"] = this.Volume; obj.InstanceVariable["@pitch"] = this.Pitch; return(obj); }
internal RubyGlobalScope(RubyContext /*!*/ context, Scope /*!*/ scope, RubyObject /*!*/ mainObject, bool isHosted) : base(scope) { Assert.NotNull(context, scope, mainObject); Debug.Assert(mainObject.ImmediateClass.IsSingletonClass); _context = context; _mainObject = mainObject; _isHosted = isHosted; }
public string FormatParams(RubyObject ev) { object o = ev.InstanceVariable["@parameters"]; if (o == null) return this.Group.Provider.Format.ParseFormat(this.Format, null); List<object> param = o as List<object>; if (param.Count == 0) return this.Group.Provider.Format.ParseFormat(this.Format, null); return this.Group.Provider.Format.ParseFormat(this.Format, param); }
private RubyObject CreateRubyObject(string className, ObjectEditor.Struct item) { RubyObject obj = new RubyObject(); obj.ClassName = RubySymbol.GetSymbol(className); foreach (var kv in item) { if (kv.Key.ID.StartsWith("@")) { obj.InstanceVariables[RubySymbol.GetSymbol(kv.Key.ID)] = kv.Value; } } return(obj); }
protected override void InitControl() { orig = this.selectedItem as RubyObject; RubyObject obj = orig; if (obj != null) { this.audioFile = new AudioFile(obj); } else { this.audioFile = new AudioFile(); } btn.Text = this.audioFile.ToString(); }
public static byte[] Encode(RubyObject ruby) { var bytes = new byte[32]; using (var stream = new MemoryStream(bytes)) { using (var writer = new BinaryWriter(stream)) { writer.Write(ruby["red"].GetValue <double>()); writer.Write(ruby["green"].GetValue <double>()); writer.Write(ruby["blue"].GetValue <double>()); writer.Write(ruby["gray"].GetValue <double>()); } } return(bytes); }
public string FormatParams(RubyObject ev) { object o = ev.InstanceVariable["@parameters"]; if (o == null) { return(this.Group.Provider.Format.ParseFormat(this.Format, null)); } List <object> param = o as List <object>; if (param.Count == 0) { return(this.Group.Provider.Format.ParseFormat(this.Format, null)); } return(this.Group.Provider.Format.ParseFormat(this.Format, param)); }
public RubyToken Convert(JToken json) { switch (json.Type) { case JTokenType.Array: var arrayToken = new RubyArray(); foreach (var item in (JArray)json) { arrayToken.Add(Convert(item)); } return(arrayToken); case JTokenType.Object: var objectToken = new RubyObject(); var jsonObject = (JObject)json; foreach (var property in jsonObject) { if (property.Key == "typeName") { objectToken.RubyClass.Name = property.Value.Value <string>(); } else { objectToken[property.Key] = Convert(property.Value); } } return(objectToken); case JTokenType.Null: return(new RubyValue((object)null)); case JTokenType.Boolean: return(new RubyValue(json.Value <bool>())); case JTokenType.String: return(new RubyValue(json.Value <string>())); default: return(new RubyValue(((JValue)json).Value)); } }
private void LoadInfo() { RGSSTable data; infoLoaded = true; raw = NekoKun.Serialization.RubyMarshal.RubyMarshal.Load(new System.IO.FileStream(this.filename, System.IO.FileMode.Open, System.IO.FileAccess.Read)) as RubyObject; this.TilesetID = (int)raw.InstanceVariable["@tileset_id"] - 1; var j = raw.InstanceVariable["@data"] as NekoKun.Serialization.RubyMarshal.RubyUserdefinedDumpObject; data = new RGSSTable(j.DumpedObject as byte[]); this.Size = new System.Drawing.Size((int)raw.InstanceVariable["@width"], (int)raw.InstanceVariable["@height"]); this.Layers = new List <MapLayer>(); for (int z = 0; z < data.ZSize; z++) { MapLayer layer = new MapLayer(); layer.Data = new short[this.Size.Width, this.Size.Height]; for (int x = 0; x < this.Size.Width; x++) { for (int y = 0; y < this.Size.Height; y++) { layer.Data[x, y] = data[x, y, z]; } } layer.Type = MapLayerType.Tile; this.Layers.Add(layer); } if (this.Layers.Count == 4) { MapLayer layer = this.Layers[3]; this.Layers.Remove(layer); this.Layers.Insert(2, layer); layer.Type = MapLayerType.HalfBlockShadow; } raw.InstanceVariable["@data"] = null; }
public static string CreateFromDefaultValue(object value) { if (value is RubyString || value is string) { return(typeof(SingleTextEditor).FullName); } if (value is int) { return(typeof(DecimalEditor).FullName); } if (value is RubyObject) { RubyObject obj = value as RubyObject; //if (obj.ClassName.GetString() == "RPG::AudioFile") // return typeof(RPGMaker.AudioFileEditor).FullName; } return(typeof(UnknownEditor).FullName); }
/// <summary> /// static void w_objivar(VALUE obj, struct dump_call_arg *arg) /// </summary> /// <param name="obj"></param> public void WriteObjectInstanceVariable(RubyObject obj) { WriteInstanceVariable(obj, obj.InstanceVariables); }
public AudioFile(RubyObject obj) { this.Name = (obj.InstanceVariable["@name"] as string) ?? ""; this.Volume = Int32.Parse((obj.InstanceVariable["@volume"] ?? 100).ToString()); this.Pitch = Int32.Parse((obj.InstanceVariable["@pitch"] ?? 100).ToString()); }
internal static RubyToken ReadEntry(ReadContext context, RubyDecoderOptions options) { RubyClass rubyClass; int fieldCount; RubyObject objectEntry; var type = (RubyType)context.Reader.ReadByte(); switch (type) { case RubyType.Nil: return(new RubyValue((object)null)); case RubyType.TypeLink: var dataId = (int)ReadNumber(context); if (context.Data.Count > dataId) { return(context.Data[dataId]); } else { throw new Exception("Failed to locate linked data"); } case RubyType.Array: var length = (int)ReadNumber(context); var arrayEntry = new RubyArray { Array = new List <RubyToken>(length) }; context.Data.Add(arrayEntry); for (var index = 0; index < length; index++) { arrayEntry.Array.Add(ReadEntry(context, options)); } return(arrayEntry); case RubyType.Object: rubyClass = ReadSymbolDefinition(context); fieldCount = (int)ReadNumber(context); objectEntry = new RubyObject { RubyClass = rubyClass, Properties = new Dictionary <string, RubyToken>(fieldCount) }; context.Data.Add(objectEntry); for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { var keySymbol = ReadSymbolDefinition(context); var value = ReadEntry(context, options); objectEntry.Properties.Add(keySymbol.Name.TrimStart('@'), value); } return(objectEntry); case RubyType.UserDefined: rubyClass = ReadSymbolDefinition(context); if (options.UserDecoders != null && options.UserDecoders.TryGetValue(rubyClass.Name, out var decoder)) { ReadNumber(context); var userDefinedEntry = decoder(context.Reader); userDefinedEntry.RubyClass = rubyClass; context.Data.Add(userDefinedEntry); return(userDefinedEntry); } else { throw new Exception($"User defined type not handled: {rubyClass.Name}"); } case RubyType.Hash: fieldCount = (int)ReadNumber(context); objectEntry = new RubyObject { RubyClass = new RubyClass { Name = "encoder:Hash" }, Properties = new Dictionary <string, RubyToken>(fieldCount) }; context.Data.Add(objectEntry); for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { var key = ReadEntry(context, options); var value = ReadEntry(context, options); objectEntry.Properties.Add(key.ToString(), value); } return(objectEntry); case RubyType.Number: return(new RubyValue(ReadNumber(context))); case RubyType.Decimal: var rubyFloat = new RubyValue(ReadFloat(context)); context.Data.Add(rubyFloat); return(rubyFloat); case RubyType.String: var stringEntry = ReadStringValue(context); context.Data.Add(stringEntry); return(stringEntry); case RubyType.True: return(new RubyValue(true)); case RubyType.False: return(new RubyValue(false)); default: throw new Exception($"Unknown type: {type}"); } }
private void LoadInfo() { RGSSTable data; infoLoaded = true; raw = NekoKun.Serialization.RubyMarshal.RubyMarshal.Load(new System.IO.FileStream(this.filename, System.IO.FileMode.Open, System.IO.FileAccess.Read)) as RubyObject; this.TilesetID = (int)raw.InstanceVariable["@tileset_id"] - 1; var j = raw.InstanceVariable["@data"] as NekoKun.Serialization.RubyMarshal.RubyUserdefinedDumpObject; data = new RGSSTable(j.DumpedObject as byte[]); this.Size = new System.Drawing.Size((int)raw.InstanceVariable["@width"], (int)raw.InstanceVariable["@height"]); this.Layers = new List<MapLayer>(); for (int z = 0; z < data.ZSize; z++) { MapLayer layer = new MapLayer(); layer.Data = new short[this.Size.Width, this.Size.Height]; for (int x = 0; x < this.Size.Width; x++) { for (int y = 0; y < this.Size.Height; y++) { layer.Data[x, y] = data[x, y, z]; } } layer.Type = MapLayerType.Tile; this.Layers.Add(layer); } if (this.Layers.Count == 4) { MapLayer layer = this.Layers[3]; this.Layers.Remove(layer); this.Layers.Insert(2, layer); layer.Type = MapLayerType.HalfBlockShadow; } raw.InstanceVariable["@data"] = null; }
public MapInfoFile(Dictionary <string, object> node) : base( System.IO.Path.Combine( ProjectManager.ProjectDir, node["FileName"].ToString() ) ) { this.maps = new Dictionary <string, MapFile>(); this.IsSubfileProvider = true; this.TilesetFile = ProjectManager.Components[node["TilesetProvider"].ToString()] as TilesetFile; RubyHash mapHash = NekoKun.Serialization.RubyMarshal.RubyMarshal.Load( new System.IO.FileStream(this.filename, System.IO.FileMode.Open, System.IO.FileAccess.Read) ) as RubyHash; foreach (var item in mapHash) { string key = null; string filename; MapFile map = null; if (item.Key is int) { key = item.Key.ToString(); filename = String.Format(node["FileNameFormat"].ToString(), (int)item.Key); map = new MapFile(System.IO.Path.Combine(ProjectManager.ProjectDir, filename), this.TilesetFile); } else { this.MakeDirty(); continue; } this.maps.Add(key, map); RubyObject info = item.Value as RubyObject; map.Title = (info.InstanceVariable["@name"] as RubyString).Text; map.ParentID = info.InstanceVariable["@parent_id"].ToString(); map.Order = (int)info.InstanceVariable["@order"]; /* * parent_id * The parent map ID. * * order * The map tree display order, which is used internally. * * expanded * The map tree expansion flag, which is used internally. * * scroll_x * The x-axis scroll position, which is used internally. * * scroll_y * The y-axis scroll position, which is used internally. */ } this.maps.ToString(); nodes = new Dictionary <string, System.Windows.Forms.TreeNode>(); List <System.Windows.Forms.TreeNode> order = new List <System.Windows.Forms.TreeNode>(); foreach (var item in maps) { System.Windows.Forms.TreeNode node2 = new System.Windows.Forms.TreeNode(item.Value.Title); node2.Tag = item.Value; nodes.Add(item.Key, node2); order.Add(node2); } order.Sort( delegate(System.Windows.Forms.TreeNode me, System.Windows.Forms.TreeNode other) { return((me.Tag as MapFile).Order.CompareTo((other.Tag as MapFile).Order)); } ); foreach (System.Windows.Forms.TreeNode item in order) { MapFile map = item.Tag as MapFile; if (map.ParentID != null && nodes.ContainsKey(map.ParentID)) { nodes[map.ParentID].Nodes.Add(item); } } }
/// <summary> /// static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod) /// </summary> /// <param name="hasivp"></param> /// <param name="ivp"></param> /// <param name="extmod"></param> /// <returns></returns> public object ReadObject0(bool hasivp, ref bool ivp, List <RubyModule> extmod) { object v = null; var type = ReadByte(); switch (type) { case RubyMarshal.Types.LINK: var id = ReadLong(); object link; if (!_m_objects.TryGetValue(id, out link)) { throw new InvalidDataException("dump format error (unlinked)"); } v = link; if (_m_proc != null) { v = _m_proc(v); } break; case RubyMarshal.Types.INSTANCE_VARIABLE: { var ivar = true; v = ReadObject0(ref ivar, extmod); var hasenc = false; if (ivar) { ReadInstanceVariable(v, ref hasenc); } } break; case RubyMarshal.Types.EXTENDED: { var m = RubyModule.GetModule(ReadUnique()); if (extmod == null) { extmod = new List <RubyModule>(); } extmod.Add(m); v = ReadObject0(extmod); if (v is RubyObject fobj) { fobj.ExtendModules.AddRange(extmod); } } break; case RubyMarshal.Types.USER_CLASS: { var c = RubyClass.GetClass(ReadUnique()); v = ReadObject0(extmod); if (v is RubyObject) { (v as RubyObject).ClassName = c.Symbol; } } break; case RubyMarshal.Types.NIL: v = RubyNil.Instance; v = Leave(v); break; case RubyMarshal.Types.TRUE: v = RubyBool.True; v = Leave(v); break; case RubyMarshal.Types.FALSE: v = RubyBool.False; v = Leave(v); break; case RubyMarshal.Types.FIXNUM: v = ReadLong(); v = new RubyFixnum(Convert.ToInt64(v)); v = Leave(v); break; case RubyMarshal.Types.FLOAT: { double d; var fstr = ReadString(); var str = fstr.Text; switch (str) { case "inf": d = double.PositiveInfinity; break; case "-inf": d = double.NegativeInfinity; break; case "nan": d = double.NaN; break; default: if (str.Contains("\0")) { str = str.Remove(str.IndexOf("\0", StringComparison.Ordinal)); } d = Convert.ToDouble(str); break; } v = new RubyFloat(d); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.BIGNUM: { var sign = 0; switch (ReadByte()) { case 0x2b: sign = 1; break; case 0x2d: sign = -1; break; default: sign = 0; break; } var num3 = ReadLong(); var index = num3 / 2; var num5 = (num3 + 1) / 2; var data = new uint[num5]; for (var i = 0; i < index; i++) { data[i] = _m_reader.ReadUInt32(); } if (index != num5) { data[index] = _m_reader.ReadUInt16(); } v = new RubyBignum(sign, data); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.STRING: v = Entry(ReadString()); v = Leave(v); break; case RubyMarshal.Types.REGEXP: { var str = ReadString(); var options = ReadByte(); var has_encoding = false; var idx = Prepare(); if (hasivp) { ReadInstanceVariable(str, ref has_encoding); ivp = false; } if (!has_encoding) { // TODO: 1.8 compatibility; remove escapes undefined in 1.8 /* * char *ptr = RSTRING_PTR(str), *dst = ptr, *src = ptr; * long len = RSTRING_LEN(str); * long bs = 0; * for (; len-- > 0; *dst++ = *src++) { * switch (*src) { * case '\\': bs++; break; * case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': * case 'm': case 'o': case 'p': case 'q': case 'u': case 'y': * case 'E': case 'F': case 'H': case 'I': case 'J': case 'K': * case 'L': case 'N': case 'O': case 'P': case 'Q': case 'R': * case 'S': case 'T': case 'U': case 'V': case 'X': case 'Y': * if (bs & 1) --dst; * default: bs = 0; break; * } * } * rb_str_set_len(str, dst - ptr); */ } v = Entry0(new RubyRegexp(str, (RubyRegexpOptions)options), idx); v = Leave(v); } break; case RubyMarshal.Types.ARRAY: { var len = ReadLong(); var ary = new RubyArray(); v = ary; v = Entry(v); while (len-- > 0) { ary.Push(ReadObject()); } v = Leave(v); } break; case RubyMarshal.Types.HASH: case RubyMarshal.Types.HASH_WITH_DEFAULT: { var len = ReadLong(); var hash = new RubyHash(); v = hash; v = Entry(v); while (len-- > 0) { var key = ReadObject(); var value = ReadObject(); hash.Add(key, value); } if (type == RubyMarshal.Types.HASH_WITH_DEFAULT) { hash.DefaultValue = ReadObject(); } v = Leave(v); } break; case RubyMarshal.Types.STRUCT: { var idx = Prepare(); var obj = new RubyStruct(); var klass = ReadUnique(); obj.ClassName = klass; var len = ReadLong(); v = obj; v = Entry0(v, idx); while (len-- > 0) { var key = ReadSymbol(); var value = ReadObject(); obj.InstanceVariable[key] = value; } v = Leave(v); } break; case RubyMarshal.Types.USER_DEFINED: { var klass = ReadUnique(); var obj = RubyUserDefinedObject.TryGetUserDefinedObject(klass.Name); if (obj == null) { var data = ReadString(); if (hasivp) { ReadInstanceVariable(data); ivp = false; } obj = new DefaultRubyUserDefinedDumpObject { Raw = data.Raw }; } else { obj.Read(_m_reader); } obj.ClassName = klass; v = obj; v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.USER_MARSHAL: { var klass = ReadUnique(); var obj = new DefaultRubyUserDefinedMarshalDumpObject(); v = obj; if (extmod != null) { AppendExtendedModule(obj, extmod); } v = Entry(v); var data = ReadObject(); obj.ClassName = klass; obj.DumpedObject = data; v = Leave(v); extmod?.Clear(); } break; case RubyMarshal.Types.OBJECT: { var idx = Prepare(); var obj = new RubyObject(); var klass = ReadUnique(); obj.ClassName = klass; v = obj; v = Entry0(v, idx); ReadInstanceVariable(v); v = Leave(v); } break; case RubyMarshal.Types.CLASS: { var str = ReadString(); v = RubyClass.GetClass(RubySymbol.GetSymbol(str)); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.MODULE: { var str = ReadString(); v = RubyModule.GetModule(RubySymbol.GetSymbol(str)); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.SYMBOL: if (hasivp) { v = ReadSymbolReal(ivp); ivp = false; } else { v = ReadSymbolReal(false); } v = Leave(v); break; case RubyMarshal.Types.SYMBOL_LINK: v = ReadSymbolLink(); break; case RubyMarshal.Types.DATA: /* TODO: Data Support * { * VALUE klass = path2class(r_unique(arg)); * VALUE oldclass = 0; * * v = obj_alloc_by_klass(klass, arg, &oldclass); * if (!RB_TYPE_P(v, T_DATA)) { * rb_raise(rb_eArgError, "dump format error"); * } * v = r_entry(v, arg); * if (!rb_respond_to(v, s_load_data)) { * rb_raise(rb_eTypeError, "class %s needs to have instance method `_load_data'", rb_class2name(klass)); * } * rb_funcall(v, s_load_data, 1, r_object0(arg, 0, extmod)); * check_load_arg(arg, s_load_data); * v = r_leave(v, arg); * } */ case RubyMarshal.Types.MODULE_OLD: /* * TODO: ModuleOld Support * { * volatile VALUE str = r_bytes(arg); * v = rb_path_to_class(str); * v = r_entry(v, arg); * v = r_leave(v, arg); * } */ default: throw new InvalidDataException($"dump format error(0x{type:X2})"); } return(v); }
/// <summary> /// static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod) /// </summary> /// <param name="hasivp"></param> /// <param name="ivp"></param> /// <param name="extmod"></param> /// <returns></returns> public object ReadObject0(bool hasivp, ref bool ivp, List<RubyModule> extmod) { object v = null; int type = ReadByte(); int id; object link; switch (type) { case RubyMarshal.Types.Link: id = ReadLong(); if (!this.m_objects.TryGetValue(id, out link)) { throw new InvalidDataException("dump format error (unlinked)"); } v = link; if (this.m_proc != null) v = this.m_proc(v); break; case RubyMarshal.Types.InstanceVariable: { bool ivar = true; v = ReadObject0(ref ivar, extmod); bool hasenc = false; if (ivar) ReadInstanceVariable(v, ref hasenc); } break; case RubyMarshal.Types.Extended: { RubyModule m = RubyModule.GetModule(ReadUnique()); if (extmod == null) extmod = new List<RubyModule>(); extmod.Add(m); v = ReadObject0(extmod); RubyObject fobj = v as RubyObject; if (fobj != null) { fobj.ExtendModules.AddRange(extmod); } } break; case RubyMarshal.Types.UserClass: { RubyClass c = RubyClass.GetClass(ReadUnique()); v = ReadObject0(extmod); if (v is RubyObject) (v as RubyObject).ClassName = c.Symbol; } break; case RubyMarshal.Types.Nil: v = RubyNil.Instance; v = Leave(v); break; case RubyMarshal.Types.True: v = true; v = Leave(v); break; case RubyMarshal.Types.False: v = false; v = Leave(v); break; case RubyMarshal.Types.Fixnum: v = ReadLong(); v = Leave(v); break; case RubyMarshal.Types.Float: { double d; RubyString fstr = ReadString(); string str = fstr.Text; if (str == "inf") d = double.PositiveInfinity; else if (str == "-inf") d = double.NegativeInfinity; else if (str == "nan") d = double.NaN; else { if (str.Contains("\0")) { str = str.Remove(str.IndexOf("\0")); } d = Convert.ToDouble(str); } v = new RubyFloat(d); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.Bignum: { int sign = 0; switch (ReadByte()) { case 0x2b: sign = 1; break; case 0x2d: sign = -1; break; default: sign = 0; break; } int num3 = ReadLong(); int index = num3 / 2; int num5 = (num3 + 1) / 2; uint[] data = new uint[num5]; for (int i = 0; i < index; i++) { data[i] = m_reader.ReadUInt32(); } if (index != num5) { data[index] = m_reader.ReadUInt16(); } v = new RubyBignum(sign, data); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.String: v = Entry(ReadString()); v = Leave(v); break; case RubyMarshal.Types.Regexp: { RubyString str = ReadString(); int options = ReadByte(); bool has_encoding = false; int idx = Prepare(); if (hasivp) { ReadInstanceVariable(str, ref has_encoding); ivp = false; } if (!has_encoding) { // TODO: 1.8 compatibility; remove escapes undefined in 1.8 /* char *ptr = RSTRING_PTR(str), *dst = ptr, *src = ptr; long len = RSTRING_LEN(str); long bs = 0; for (; len-- > 0; *dst++ = *src++) { switch (*src) { case '\\': bs++; break; case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'o': case 'p': case 'q': case 'u': case 'y': case 'E': case 'F': case 'H': case 'I': case 'J': case 'K': case 'L': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'X': case 'Y': if (bs & 1) --dst; default: bs = 0; break; } } rb_str_set_len(str, dst - ptr); */ } v = Entry0(new RubyRegexp(str, (RubyRegexpOptions)options), idx); v = Leave(v); } break; case RubyMarshal.Types.Array: { int len = ReadLong(); RubyArray ary = new RubyArray(); v = ary; v = Entry(v); while (len-- > 0) { ary.Push(ReadObject()); } v = Leave(v); } break; case RubyMarshal.Types.Hash: case RubyMarshal.Types.HashWithDefault: { int len = ReadLong(); RubyHash hash = new RubyHash(); v = hash; v = Entry(v); while (len-- > 0) { object key = ReadObject(); object value = ReadObject(); hash.Add(key, value); } if (type == RubyMarshal.Types.HashWithDefault) { hash.DefaultValue = ReadObject(); } v = Leave(v); } break; case RubyMarshal.Types.Struct: { int idx = Prepare(); RubyStruct obj = new RubyStruct(); RubySymbol klass = ReadUnique(); obj.ClassName = klass; int len = ReadLong(); v = obj; v = Entry0(v, idx); while (len-- > 0) { RubySymbol key = ReadSymbol(); object value = ReadObject(); obj.InstanceVariable[key] = value; } v = Leave(v); } break; case RubyMarshal.Types.UserDefined: { RubySymbol klass = ReadUnique(); RubyString data = ReadString(); if (hasivp) { ReadInstanceVariable(data); ivp = false; } RubyUserdefinedDumpObject obj = new RubyUserdefinedDumpObject(); obj.ClassName = klass; obj.DumpedObject = data.Raw; v = obj; v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.UserMarshal: { RubySymbol klass = ReadUnique(); FuzzyUserdefinedMarshalDumpObject obj = new FuzzyUserdefinedMarshalDumpObject(); v = obj; if (extmod != null) AppendExtendedModule(obj, extmod); v = Entry(v); object data = ReadObject(); obj.ClassName = klass; obj.DumpedObject = data; v = Leave(v); if (extmod != null) { extmod.Clear(); } } break; case RubyMarshal.Types.Object: { int idx = Prepare(); RubyObject obj = new RubyObject(); RubySymbol klass = ReadUnique(); obj.ClassName = klass; v = obj; v = Entry0(v, idx); ReadInstanceVariable(v); v = Leave(v); } break; case RubyMarshal.Types.Class: { RubyString str = ReadString(); v = RubyClass.GetClass(RubySymbol.GetSymbol(str)); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.Module: { RubyString str = ReadString(); v = RubyModule.GetModule(RubySymbol.GetSymbol(str)); v = Entry(v); v = Leave(v); } break; case RubyMarshal.Types.Symbol: if (hasivp) { v = ReadSymbolReal(ivp); ivp = false; } else { v = ReadSymbolReal(false); } v = Leave(v); break; case RubyMarshal.Types.SymbolLink: v = ReadSymbolLink(); break; case RubyMarshal.Types.Data: /* TODO: Data Support { VALUE klass = path2class(r_unique(arg)); VALUE oldclass = 0; v = obj_alloc_by_klass(klass, arg, &oldclass); if (!RB_TYPE_P(v, T_DATA)) { rb_raise(rb_eArgError, "dump format error"); } v = r_entry(v, arg); if (!rb_respond_to(v, s_load_data)) { rb_raise(rb_eTypeError, "class %s needs to have instance method `_load_data'", rb_class2name(klass)); } rb_funcall(v, s_load_data, 1, r_object0(arg, 0, extmod)); check_load_arg(arg, s_load_data); v = r_leave(v, arg); } */ case RubyMarshal.Types.ModuleOld: /* TODO: ModuleOld Support { volatile VALUE str = r_bytes(arg); v = rb_path_to_class(str); v = r_entry(v, arg); v = r_leave(v, arg); } */ default: throw new InvalidDataException(string.Format("dump format error(0x{0:X2})", type)); } return v; }
private RubyObject CreateRubyObject(string className, ObjectEditor.Struct item) { RubyObject obj = new RubyObject(); obj.ClassName = RubySymbol.GetSymbol(className); foreach (var kv in item) { if (kv.Key.ID.StartsWith("@")) obj.InstanceVariables[RubySymbol.GetSymbol(kv.Key.ID)] = kv.Value; } return obj; }
/// <summary> /// static void w_ivar(VALUE obj, st_table *tbl, struct dump_call_arg *arg) /// </summary> /// <param name="obj"></param> public void WriteInstanceVariable(RubyObject obj, Dictionary<RubySymbol, object> tbl) { int num = tbl != null ? tbl.Count : 0; WriteEncoding(obj, num); if (tbl != null) { foreach (KeyValuePair<RubySymbol, object> item in tbl) { if (item.Key == RubyMarshal.IDs.encoding) continue; if (item.Key == RubyMarshal.IDs.E) continue; WriteSymbol(item.Key); WriteObject(item.Value); } } }