public object Deserialize(SPEEmulator.IEndianBitConverter conv, ObjectTableEntry e, object storage) { Type arrtype; uint elsize; if (e.KnownType == AccCIL.KnownObjectTypes.String) { throw new InvalidProgramException("Something is wrong here"); } if (e.Type == 0) { arrtype = AccCIL.AccCIL.GetObjType(e.KnownType).MakeArrayType(); elsize = 1u << (int)BuiltInSPEMethods.get_array_elem_len_mult((uint)e.KnownType); } else { arrtype = Type.GetType((string)m_parent.ReadObjectFromLS(e.Type)); elsize = 4; } Type eltype = arrtype.GetElementType(); uint arraylen = e.Size / elsize; Array arr; if (storage == null) { arr = Array.CreateInstance(eltype, arraylen); } else { arr = (Array)storage; if (storage.GetType().GetElementType() != eltype || arr.Length != arraylen) { throw new Exception("Unexpected difference in storage object and actual object"); } } if (eltype.IsPrimitive) { ISerializer elserializer; m_parent.Serializers.TryGetValue(eltype, out elserializer); if (elserializer == null) { throw new Exception("Unsupported inner type: " + eltype.FullName); } for (int i = 0; i < arr.Length; i++) { arr.SetValue(elserializer.Deserialize(conv, null, arr.GetValue(i)), i); } } else { //In this case elements may have a different type than what the array states, //because the array elements can be interface or object type, and the actual //instance type is unknown ISerializer uintd = m_parent.Serializers[typeof(uint)]; for (int i = 0; i < arr.Length; i++) { arr.SetValue(m_parent.ReadObjectFromLS((uint)uintd.Deserialize(conv, null, null), arr.GetValue(i)), i); } } return(arr); }
public byte[] Serialize(object element, out uint size) { if (element == null) { throw new ArgumentNullException("element"); } Array arr = (Array)element; Type eltype = element.GetType().GetElementType(); AccCIL.KnownObjectTypes objt; uint elsize; string typename; if (eltype.IsPrimitive) { objt = AccCIL.AccCIL.GetObjType(eltype); elsize = 1u << (int)BuiltInSPEMethods.get_array_elem_len_mult((uint)objt); typename = null; } else { elsize = 4; objt = AccCIL.KnownObjectTypes.Object; typename = element.GetType().FullName; } size = (uint)arr.Length * elsize; uint alignedSize = ((size + 15) >> 4) << 4; SPEEmulator.EndianBitConverter c = new SPEEmulator.EndianBitConverter(new byte[alignedSize]); if (eltype.IsPrimitive) { ISerializer elserializer; m_parent.Serializers.TryGetValue(eltype, out elserializer); if (elserializer == null) { throw new Exception("Unsupported inner type: " + eltype.FullName); } for (int i = 0; i < arr.Length; i++) { //TODO: This is inefficient, it should write directly into the target buffer uint s; byte[] localdata = elserializer.Serialize(arr.GetValue(i), out s); Array.Copy(localdata, 0, c.Data, c.Position, localdata.Length); c.Position += s; } } else { for (int i = 0; i < arr.Length; i++) { object value = arr.GetValue(i); if (value == null) { c.WriteUInt(0); } else { //If we are writing back the array, write back the element as well if (m_parent.KnownObjectsByObj.ContainsKey(element) && m_parent.KnownObjectsByObj.ContainsKey(value)) { m_parent.WriteObjectToLS(m_parent.KnownObjectsByObj[value], value); } else { c.WriteUInt(m_parent.CreateObjectOnLS(value)); } } } } return(c.Data); }