public bool GetFixedSize(ref int size) { if (size < 0) { return(false); } if (_data.Length == 0) { return(true); } // Sensible? size = ProtocolInformation.Padded(size, Alignment); if (_data.Length == 1) { int valueSize = GetSize(this[0]); if (valueSize == -1) { return(false); } size += valueSize; return(true); } if (IsStructlike) { foreach (Signature sig in GetParts()) { if (!sig.GetFixedSize(ref size)) { return(false); } } return(true); } if (IsArray || IsDict) { return(false); } if (IsStruct) { foreach (Signature sig in GetFieldSignatures()) { if (!sig.GetFixedSize(ref size)) { return(false); } } return(true); } // Any other cases? throw new Exception(); }
// 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)); } }
private void WritePad(int alignment) { int needed = ProtocolInformation.PadNeeded((int)stream.Position, alignment); if (needed == 0) { return; } stream.Write(nullBytes, 0, needed); }
public void ReadPad(int alignment) { for (int endPos = ProtocolInformation.Padded(_pos, alignment); _pos != endPos; _pos++) { if (_data.Array[_data.Offset + _pos] != 0) { throw new ProtocolException("Read non-zero byte at position " + _pos + " while expecting padding. Value given: " + _data.Array[_data.Offset + _pos]); } } }
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()); }