Пример #1
0
            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);
            }
Пример #2
0
            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);
            }