static object UnserializeInternal(int version, JSONNode node, Type type) { if (type == typeof(bool)) { return(node.AsBool); } else if (type == typeof(sbyte)) { return(short.Parse(node.Value)); } else if (type == typeof(int)) { return(int.Parse(node.Value)); } else if (type == typeof(long)) { return(long.Parse(node.Value)); } else if (type == typeof(byte)) { return(byte.Parse(node.Value)); } else if (type == typeof(ushort)) { return(ushort.Parse(node.Value)); } else if (type == typeof(uint)) { return(uint.Parse(node.Value)); } else if (type == typeof(ulong)) { return(ulong.Parse(node.Value)); } else if (type == typeof(float)) { return(node.AsFloat); } else if (type == typeof(double)) { return(node.AsDouble); } else if (type == typeof(string)) { return(node.Value); } else if (type == typeof(global::Ros.PartialByteArray)) { var nodeArr = node.AsArray; if (type.GetElementType() == typeof(byte) && nodeArr == null) { var array = System.Convert.FromBase64String(node.Value); return(new global::Ros.PartialByteArray() { Array = array, Length = array.Length, }); } else { var array = new global::Ros.PartialByteArray() { Array = new byte[node.Count], Length = node.Count, }; for (int i = 0; i < node.Count; i++) { array.Array[i] = byte.Parse(nodeArr[i].Value); } return(array); } } else if (type.IsArray) { var nodeArr = node.AsArray; if (type.GetElementType() == typeof(byte) && nodeArr == null) { return(System.Convert.FromBase64String(node.Value)); } var arr = Array.CreateInstance(type.GetElementType(), node.Count); for (int i = 0; i < node.Count; i++) { arr.SetValue(UnserializeInternal(version, nodeArr[i], type.GetElementType()), i); } return(arr); } else if (type == typeof(global::Ros.Time)) { var nodeObj = node.AsObject; var obj = new global::Ros.Time(); if (version == 1) { obj.secs = uint.Parse(nodeObj["secs"].Value); obj.nsecs = uint.Parse(nodeObj["nsecs"].Value); } else { obj.secs = int.Parse(nodeObj["sec"].Value); obj.nsecs = uint.Parse(nodeObj["nanosec"].Value); } return(obj); } else if (type.IsEnum) { var value = node.AsInt; var obj = Enum.ToObject(type, value); return(obj); } else { var nodeObj = node.AsObject; var obj = Activator.CreateInstance(type); foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) { // UnityEngine.Debug.Log(nodeObj.ToString()); if (nodeObj[field.Name] != null) { var fieldType = field.FieldType; if (fieldType.IsNullable()) { fieldType = Nullable.GetUnderlyingType(fieldType); } var value = UnserializeInternal(version, nodeObj[field.Name], fieldType); field.SetValue(obj, value); } } return(obj); } }
public static void SerializeInternal(int version, StringBuilder sb, Type type, object message, string keyName = "") { if (type.IsNullable()) { type = Nullable.GetUnderlyingType(type); } if (message == null) { message = type.TypeDefaultValue(); //only underlying value type will be given a default value } if (type == typeof(string)) { sb.Append('"'); if (!string.IsNullOrEmpty((string)message)) { Escape(sb, message.ToString()); } sb.Append('"'); } else if (type.IsEnum) { var etype = type.GetEnumUnderlyingType(); SerializeInternal(version, sb, etype, Convert.ChangeType(message, etype)); } else if (BuiltinMessageTypes.ContainsKey(type)) { if (type == typeof(bool)) { sb.Append(string.Format(CultureInfo.InvariantCulture, "{0}", message).ToLowerInvariant()); } else { sb.Append(string.Format(CultureInfo.InvariantCulture, "{0}", message)); } } else if (type == typeof(global::Ros.PartialByteArray)) { var arr = (global::Ros.PartialByteArray)message; if (version == 1) { sb.Append('"'); if (arr.Base64 == null) { sb.Append(System.Convert.ToBase64String(arr.Array, 0, arr.Length)); } else { sb.Append(arr.Base64); } sb.Append('"'); } else { sb.Append('['); for (int i = 0; i < arr.Length; i++) { sb.Append(arr.Array[i]); if (i < arr.Length - 1) { sb.Append(','); } } sb.Append(']'); } } else if (type.IsArray) { if (type.GetElementType() == typeof(byte) && version == 1) { sb.Append('"'); sb.Append(System.Convert.ToBase64String((byte[])message)); sb.Append('"'); } else { Array arr = (Array)message; sb.Append('['); for (int i = 0; i < arr.Length; i++) { SerializeInternal(version, sb, type.GetElementType(), arr.GetValue(i)); if (i < arr.Length - 1) { sb.Append(','); } } sb.Append(']'); } } else if (type.IsGenericList()) { IList list = (IList)message; sb.Append('['); for (int i = 0; i < list.Count; i++) { SerializeInternal(version, sb, list[i].GetType(), list[i]); if (i < list.Count - 1) { sb.Append(','); } } sb.Append(']'); } else if (type == typeof(global::Ros.Time)) { global::Ros.Time t = (global::Ros.Time)message; if (version == 1) { sb.AppendFormat("{{\"secs\":{0},\"nsecs\":{1}}}", (uint)t.secs, (uint)t.nsecs); } else { sb.AppendFormat("{{\"sec\":{0},\"nanosec\":{1}}}", (int)t.secs, (uint)t.nsecs); } } else { var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); sb.Append('{'); for (int i = 0; i < fields.Length; i++) { var field = fields[i]; if (version == 2 && type == typeof(global::Ros.Header) && field.Name == "seq") { continue; } var fieldType = field.FieldType; var fieldValue = field.GetValue(message); if (fieldValue != null && typeof(IOneOf).IsAssignableFrom(fieldType)) //only when it is a OneOf field { var oneof = fieldValue as IOneOf; if (oneof != null) //only when this is a non-null OneOf { var oneInfo = oneof.GetOne(); if (oneInfo.Value != null) //only hwne at least one subfield assgined { var oneFieldName = oneInfo.Key; var oneFieldValue = oneInfo.Value; var oneFieldType = oneInfo.Value.GetType(); sb.Append('"'); sb.Append(oneFieldName); sb.Append('"'); sb.Append(':'); SerializeInternal(version, sb, oneFieldType, oneFieldValue); sb.Append(','); } } } else if (fieldValue != null || (fieldType.IsNullable() && Attribute.IsDefined(field, typeof(global::Apollo.RequiredAttribute)))) { sb.Append('"'); sb.Append(field.Name); sb.Append('"'); sb.Append(':'); SerializeInternal(version, sb, fieldType, fieldValue); sb.Append(','); } } if (sb[sb.Length - 1] == ',') { sb.Remove(sb.Length - 1, 1); } sb.Append('}'); } }