private static object _deserialize(Type T, Type container, byte[] bytes, out int amountread, bool sizeknown) { if (bytes.Length == 0 && !WHAT_IS_HAPPENING) { // Console.WriteLine("Deserializing empty array?"); amountread = 0; return(null); } object thestructure = null; if (T.FullName.Contains("System.") && !T.IsCOMObject && !T.IsArray && T != typeof(string)) { thestructure = new object(); int size = Marshal.SizeOf(T); IntPtr mem = IntPtr.Zero; if (bytes.Length != 0) { mem = Marshal.AllocHGlobal(size); Marshal.Copy(bytes, 0, mem, size); } amountread = size; if (WHAT_IS_HAPPENING) { /* * Console.WriteLine("//deserialize: " + T.FullName); * /*Console.WriteLine(string.Format(@" $A = new {0}(); * IntPtr $B = Marshal.AllocHGlobal({1}) * Marshal.Copy(bytes, 0, $B, {1}); * $A = Marshal.PtrToStructure($B, typeof({0})); * ", T.FullName, Marshal.SizeOf(T)));*/ } return(mem != IntPtr.Zero ? Marshal.PtrToStructure(mem, T) : null); } IRosMessage MSG; int startingpos = 0, currpos = 0; /*if (container==null) * currpos = 4;*/ MsgTypes MT = MsgTypes.Unknown; FieldInfo[] infos = GetFields(T, ref thestructure, out MSG); if (MSG != null) { MT = MSG.msgtype; } startingpos = currpos; int currinfo = 0; while ((currpos < bytes.Length || WHAT_IS_HAPPENING) && currinfo < infos.Length) { // Console.WriteLine(infos[currinfo].Name + "(" + currpos + "/" + bytes.Length + ")"); Type type = GetType(infos[currinfo].FieldType.FullName); //Console.WriteLine("GetType returned: " + type.FullName); Type realtype = infos[currinfo].FieldType; MsgTypes msgtype = GetMessageType(type); bool knownpiecelength = IsSizeKnown(realtype, true) && MSG.Fields != null && !MSG.Fields[infos[currinfo].Name].IsArray || MSG.Fields[infos[currinfo].Name].Length != -1; if (knownpiecelength) { if (infos[currinfo].FieldType.IsArray && msgtype == MsgTypes.std_msgs__Byte) { Array vals = (infos[currinfo].GetValue(thestructure) as Array); if (vals != null) { int num = vals.Length; byte[] PWNED = new byte[num]; Array.Copy(bytes, currpos, PWNED, 0, num); currpos += num; infos[currinfo].SetValue(thestructure, PWNED); } } else if (infos[currinfo].FieldType.IsArray && msgtype != MsgTypes.std_msgs__String) //must have length defined, or else knownpiecelength would be false... so look it up in the dict! { Type TT = GetType(infos[currinfo].FieldType.GetElementType().FullName); if (TT.IsArray) { throw new Exception("ERIC, YOU NEED TO MAKE DESERIALIZATION RECURSE!!!"); } Array vals = (infos[currinfo].GetValue(thestructure) as Array); if (vals != null) { for (int i = 0; i < vals.Length; i++) { MsgTypes mt = GetMessageType(TT); int leng = 0; Type et = realtype.GetElementType(); if (mt == MsgTypes.Unknown) { leng = Marshal.SizeOf(et); } if (leng == 0) { leng = Marshal.SizeOf(vals.GetValue(i)); } if (leng == 0) { throw new Exception("LENGTH ENUMERATION FAIL IN DESERIALIZE!"); } if (leng + currpos <= bytes.Length) { IntPtr pIP = Marshal.AllocHGlobal(leng); Marshal.Copy(bytes, currpos, pIP, leng); object o = Marshal.PtrToStructure(pIP, TT); vals.SetValue(o, i); } else { vals.SetValue(null, i); } currpos += leng; } } infos[currinfo].SetValue(thestructure, vals); } else { if (type.FullName != null && type.FullName.Contains("Message")) { if (GetMessageType(realtype) == MsgTypes.std_msgs__Time || GetMessageType(realtype) == MsgTypes.std_msgs__Duration || infos[currinfo].FieldType == typeof(TimeData)) { TimeData td; if (currpos + 8 <= bytes.Length) { uint u1 = BitConverter.ToUInt32(bytes, currpos); uint u2 = BitConverter.ToUInt32(bytes, currpos + 4); td = new TimeData(u1, u2); } else { td = new TimeData(0, 0); } currpos += 8; if (infos[currinfo].FieldType == typeof(TimeData)) { infos[currinfo].SetValue(thestructure, td); } else if (GetMessageType(realtype) == MsgTypes.std_msgs__Time) { infos[currinfo].SetValue(thestructure, (object)new std_msgs.Time(td)); } else { infos[currinfo].SetValue(thestructure, (object)new std_msgs.Duration(td)); } } else { byte[] piece = new byte[bytes.Length != 0 ? bytes.Length - currpos : 0]; if (bytes.Length != 0) { Array.Copy(bytes, currpos, piece, 0, piece.Length); } int len = 0; object obj = _deserialize(realtype, T, piece, out len, IsSizeKnown(realtype, true)); //if ((int)(infos[currinfo].Attributes & FieldAttributes.InitOnly) != 0) infos[currinfo].SetValue(thestructure, obj); currpos += len; } } else { int len = Marshal.SizeOf(infos[currinfo].GetValue(thestructure)); IntPtr pIP = Marshal.AllocHGlobal(len); object obj = null; if (currpos + len <= bytes.Length) { Marshal.Copy(bytes, currpos, pIP, len); obj = Marshal.PtrToStructure(pIP, infos[currinfo].FieldType); } infos[currinfo].SetValue(thestructure, obj); currpos += len; } } } else { Type ft = realtype; if (ft.IsArray) { Type TT = ft.GetElementType(); Array val = infos[currinfo].GetValue(thestructure) as Array; int chunklen = 0; if (val == null) { if (currpos + 4 <= bytes.Length) { chunklen = BitConverter.ToInt32(bytes, currpos); currpos += 4; val = Array.CreateInstance(TT, chunklen); } else { currpos += 4; val = Array.CreateInstance(TT, 0); } } else { chunklen = val.Length; } if (TT == null) { throw new Exception("LENGTHLESS ARRAY FAIL -- ELEMENT TYPE IS NULL!"); } if (TT == typeof(string) || TT.FullName.Contains("Message.")) { throw new Exception("NOT YET, YOUNG PATAWAN"); } MsgTypes mt = GetMessageType(TT); if (mt == MsgTypes.std_msgs__Byte) { int num = val.Length; byte[] PWNED = new byte[num]; if (currpos + num <= bytes.Length) { Array.Copy(bytes, currpos, PWNED, 0, num); } currpos += num; infos[currinfo].SetValue(thestructure, PWNED); } else if (TT.FullName != null && TT.FullName.Contains("Message")) { for (int i = 0; i < chunklen; i++) { byte[] chunk = new byte[bytes.Length - currpos]; Array.Copy(bytes, currpos, chunk, 0, chunk.Length); int len = 0; object data = _deserialize(TT, T, chunk, out len, IsSizeKnown(TT, false)); val.SetValue(data, i); currpos += len; } infos[currinfo].SetValue(thestructure, val); } else { int len = Marshal.SizeOf(TT); IntPtr pIP = IntPtr.Zero; if (currpos + len * chunklen <= bytes.Length) { pIP = Marshal.AllocHGlobal(len * chunklen); Marshal.Copy(bytes, currpos, pIP, len * chunklen); } object o = null; for (int i = 0; i < chunklen * len; i += len) { if (pIP != IntPtr.Zero) { o = Marshal.PtrToStructure(pIP, TT); } val.SetValue(o, i / len); if (pIP != IntPtr.Zero) { pIP = new IntPtr(pIP.ToInt32() + len); } } infos[currinfo].SetValue(thestructure, val); currpos += chunklen * len; } } else { if (ft.FullName != null && ft.FullName.Contains("Message")) { IRosMessage msg = (IRosMessage)Activator.CreateInstance(ft); Type t = GetType(msg.GetType().FullName); bool knownsize = IsSizeKnown(t, false) && MSG.Fields != null && !MSG.Fields[infos[currinfo].Name].IsArray || MSG.Fields[infos[currinfo].Name].Length != -1; if (!knownsize && t.GetField("data").FieldType == typeof(string)) { int len = -4; if (currpos + 4 <= bytes.Length) { len = BitConverter.ToInt32(bytes, currpos); } byte[] smallerpiece = new byte[len + 4]; if (currpos + 4 <= bytes.Length) { Array.Copy(bytes, currpos, smallerpiece, 0, smallerpiece.Length); } int dontcare = 0; msg = _deserialize(t, T, smallerpiece, out dontcare, false) as IRosMessage; if (bytes.Length != 0 && dontcare != len + 4) { throw new Exception("WTF?!"); } infos[currinfo].SetValue(thestructure, msg); currpos += len + 4; } else // if (!knownsize) { byte[] smallerpiece = new byte[bytes.Length != 0 ? bytes.Length - currpos : 0]; if (bytes.Length != 0) { Array.Copy(bytes, currpos, smallerpiece, 0, smallerpiece.Length); } int len = 0; msg = _deserialize(t, T, smallerpiece, out len, knownsize) as IRosMessage; infos[currinfo].SetValue(thestructure, msg); currpos += len; } /*else * { * throw new Exception("THIS BROKE SOMEHOW! FIX IT!"); * }*/ } else { if (infos[currinfo].FieldType == typeof(string)) { int len = 0; if (currpos + 4 <= bytes.Length) { len = BitConverter.ToInt32(bytes, currpos); } byte[] piece = new byte[len]; currpos += 4; if (currpos + len <= bytes.Length) { Array.Copy(bytes, currpos, piece, 0, len); } string str = Encoding.ASCII.GetString(piece); infos[currinfo].SetValue(thestructure, str); currpos += len; } else { //Console.WriteLine("ZOMG HANDLE: " + infos[currinfo].FieldType.FullName); amountread = currpos - startingpos; return(thestructure); } } } } currinfo++; } amountread = currpos - startingpos; return(thestructure); }
private void RandomizeField(Type T, ref object target, int hardcodedarraylength=-1) { if (!T.IsArray) { if (T != typeof(TimeData) && T.Namespace.Contains("Message")) { //Create a new object of the same type as target? object msg = Activator.CreateInstance(T); FieldInfo[] infos = GetFields(T, ref target); if (msg == null) { GetFields(T, ref target); throw new Exception("SOMETHING AIN'T RIGHT"); } foreach (FieldInfo info in infos) { if (info.Name.Contains("(")) continue; if (msg.GetType().GetField(info.Name).IsLiteral) continue; if (info.GetValue(target) == null) { if (info.FieldType == typeof(string)) info.SetValue(target, ""); else if (info.FieldType.IsArray) info.SetValue(target, Array.CreateInstance(info.FieldType.GetElementType(), 0)); else if (info.FieldType.FullName != null && !info.FieldType.FullName.Contains("Messages.")) info.SetValue(target, 0); else info.SetValue(target, Activator.CreateInstance(info.FieldType)); } object field = info.GetValue(target); //Randomize(info.FieldType, ref field, -1); info.SetValue(target, field); } } else if (target is byte || T == typeof(byte)) { target = (byte)r.Next(255); } else if (target is string || T == typeof(string)) { //create a string of random length [1,100], composed of random chars int length = r.Next(100) + 1; byte[] buf = new byte[length]; r.NextBytes(buf); //fill the whole buffer with random bytes for (int i = 0; i < length; i++) if (buf[i] == 0) //replace null chars with non-null random ones buf[i] = (byte)(r.Next(254) + 1); buf[length - 1] = 0; //null terminate target = Encoding.ASCII.GetString(buf); } else if (target is bool || T == typeof(bool)) { target = r.Next(2) == 1; } else if (target is int || T == typeof(int)) { target = r.Next(); } else if (target is uint || T == typeof(int)) { target = (uint)r.Next(); } else if (target is double || T == typeof(double)) { target = r.NextDouble(); } else if (target is TimeData || T == typeof(TimeData)) { target = new TimeData((uint)r.Next(), (uint)r.Next()); } else if (target is float || T == typeof(float)) { target = (float)r.NextDouble(); } else if (target is Int16 || T == typeof(Int16)) { target = (Int16)r.Next(Int16.MaxValue + 1); } else if (target is UInt16 || T == typeof(UInt16)) { target = (UInt16)r.Next(UInt16.MaxValue + 1); } else if (target is SByte || T == typeof(SByte)) { target = (SByte)(r.Next(255) - 127); } else if (target is UInt64 || T == typeof(UInt64)) { target = (UInt64)((uint)(r.Next() << 32)) | (uint)r.Next(); } else if (target is Int64 || T == typeof(Int64)) { target = (Int64)(r.Next() << 32) | r.Next(); } else if (target is char || T == typeof(char)) { target = (char)(byte)(r.Next(254) + 1); } else { throw new Exception("Unhandled randomization: " + T); } } else { int length = hardcodedarraylength != -1 ? hardcodedarraylength : r.Next(10); Type elem = T.GetElementType(); Array field = Array.CreateInstance(elem, new int[] { length }, new int[] { 0 }); for (int i = 0; i < length; i++) { object val = field.GetValue(i); RandomizeField(elem, ref val); field.SetValue(val, i); } target = field; } }