示例#1
0
        /// <summary>
        /// Tries to find a serializer for the specified type. To do so, it looks for the <c>SLVSerializable</c> attribute
        /// in both the type attributes and <c>StdLogicVector</c> attributes.
        /// </summary>
        /// <param name="type">type of object to serialize/deserialize</param>
        /// <returns>a suitable serializer instance, or <c>null</c> if noch such was found</returns>
        public static ISerializer TryGetSerializer(Type type)
        {
            object[]        tattrs = type.GetCustomAttributes(typeof(SLVSerializable), false);
            object[]        sattrs = typeof(StdLogicVector).GetCustomAttributes(typeof(SLVSerializable), false);
            SLVSerializable result = tattrs.Union(sattrs).Cast <SLVSerializable>().Where(a => a.ObjectType.Equals(type)).FirstOrDefault();

            if (result == null)
            {
                return(null);
            }
            else
            {
                return((ISerializer)Activator.CreateInstance(result.SerializerType));
            }
        }
示例#2
0
        /// <summary>
        /// Computes a memory layout for a given type descriptor.
        /// </summary>
        /// <param name="td">type descriptor to layout</param>
        /// <param name="info">marshalling information</param>
        /// <returns>memory layout</returns>
        public static MemoryLayout Layout(TypeDescriptor td, IMarshalInfo info)
        {
            Type        type = td.CILType;
            ISerializer ser  = SLVSerializable.TryGetSerializer(type);

            if (ser != null)
            {
                object sample = td.GetSampleInstance();
                return(CreatePrimLayout(ser.Serialize(sample).Size, td, info));
            }
            if (ser == null && td.HasIntrinsicTypeOverride)
            {
                throw new InvalidOperationException("Type " + type.Name + " has intrinsic type override but no serializer");
            }
            if (type.IsEnum)
            {
                return(new EnumMemoryLayout(td, info));
            }
            if (type.IsArray)
            {
                td.AssertStatic();
                TypeDescriptor elemTd     = td.Element0Type;
                MemoryLayout   elemLayout = Layout(elemTd, info);
                ulong          subStride  = elemLayout.SizeInBits;
                if (subStride == 0)
                {
                    return(new EmptyMemoryLayout(td)
                    {
                        Size = 0,
                        SizeInBits = 0
                    });
                }
                ulong[] strides      = new ulong[type.GetArrayRank()];
                ulong   elemsPerWord = (ulong)info.WordSize / elemLayout.SizeInBits;
                ulong   wordsPerElem = elemLayout.Size;
                if (elemsPerWord > 1)
                {
                    if (info.UseArraySubWordAlignment)
                    {
                        if (info.UseArrayDimPow2Alignment)
                        {
                            elemsPerWord = MathExt.FloorPow2(elemsPerWord);
                            subStride    = info.WordSize / elemsPerWord;
                        }
                    }
                    else
                    {
                        elemsPerWord = 1;
                    }
                }
                ulong dimSize = (ulong)(int)td.TypeParams.Last();
                ulong dimWords;
                if (elemsPerWord <= 1)
                {
                    subStride = 0;
                    if (info.UseArrayDimPow2Alignment)
                    {
                        wordsPerElem = MathExt.CeilPow2(wordsPerElem);
                    }
                    dimWords = wordsPerElem * dimSize;
                }
                else
                {
                    wordsPerElem = 0;
                    dimWords     = (dimSize + elemsPerWord - 1) / elemsPerWord;
                }
                strides[strides.Length - 1] = wordsPerElem;
                for (int i = strides.Length - 2; i >= 0; i--)
                {
                    if (info.UseArrayDimPow2Alignment)
                    {
                        dimWords = MathExt.CeilPow2(dimWords);
                    }
                    strides[i] = dimWords;
                    dimSize    = (ulong)(int)td.TypeParams[i];
                    dimWords  *= dimSize;
                }
                return(new ArrayMemoryLayout(td, info.WordSize, strides, subStride, (uint)elemsPerWord, (uint)wordsPerElem, elemLayout)
                {
                    Size = dimWords,
                    SizeInBits = dimWords * info.WordSize
                });
            }
            if (type.IsValueType && !type.IsPrimitive)
            {
                StructMemoryLayout ml     = new StructMemoryLayout(td);
                FieldInfo[]        fields = type.GetFields(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                ulong offset = 0;
                foreach (FieldInfo field in fields)
                {
                    TypeDescriptor fieldTd     = td.GetFieldType(field);
                    MemoryLayout   fieldLayout = Layout(fieldTd, info);
                    FieldLocation  fieldLoc    = new FieldLocation(field, fieldLayout, offset);
                    ml.AddLocation(fieldLoc);
                    offset += fieldLayout.Size;
                }
                ml.Size       = offset;
                ml.SizeInBits = offset * info.WordSize;
                return(ml);
            }

            throw new InvalidOperationException("Unable to create data layout for type " + type.Name);
        }