// If a struct is only composed of primitive type fields (i.e. blittable types) // then this method return true. Result is cached in isPrimitiveStruct dictionary. internal static bool IsEligibleStruct(Type structType, FieldInfo[] fields) { lock (s_isPrimitiveStruct) { bool result; if (s_isPrimitiveStruct.TryGetValue(structType, out result)) { return(result); } var typeInfo = structType.GetTypeInfo(); if (!typeInfo.IsLayoutSequential) { return(false); } if (!(s_isPrimitiveStruct[structType] = fields.All((f) => f.FieldType.GetTypeInfo().IsPrimitive&& f.FieldType != typeof(bool)))) { return(false); } int alignement = ProtocolInformation.GetAlignment(fields[0].FieldType); return(s_isPrimitiveStruct[structType] = !fields.Any((f) => ProtocolInformation.GetAlignment(f.FieldType) != alignement)); } }
public T[] ReadArray <T> () { uint ln = ReadUInt32(); Type elemType = typeof(T); if (ln > ProtocolInformation.MaxArrayLength) { throw new ProtocolException("Array length " + ln + " exceeds maximum allowed " + ProtocolInformation.MaxArrayLength + " bytes"); } //advance to the alignment of the element ReadPad(ProtocolInformation.GetAlignment(elemType)); if (elemType.GetTypeInfo().IsPrimitive) { // Fast path for primitive types (except bool which isn't blittable and take another path) if (elemType != typeof(bool)) { return(MarshalArray <T> (ln)); } else { return((T[])(Array)MarshalBoolArray(ln)); } } var list = new List <T> (); int endPos = _pos + (int)ln; var elementReader = ReadMethodFactory.CreateReadMethodDelegate <T>(); while (_pos < endPos) { list.Add(elementReader(this)); } if (_pos != endPos) { throw new ProtocolException("Read pos " + _pos + " != ep " + endPos); } return(list.ToArray()); }