예제 #1
0
        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();
        }
예제 #2
0
        // 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));
            }
        }
예제 #3
0
        private void WritePad(int alignment)
        {
            int needed = ProtocolInformation.PadNeeded((int)stream.Position, alignment);

            if (needed == 0)
            {
                return;
            }
            stream.Write(nullBytes, 0, needed);
        }
예제 #4
0
 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]);
         }
     }
 }
예제 #5
0
        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());
        }