示例#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
 public void ReadPad(int alignment)
 {
     for (int endPos = ProtocolInformation.Padded(pos, alignment); pos != endPos; pos++)
     {
         if (data[pos] != 0)
         {
             throw new PaddingException(pos, data[pos]);
         }
     }
 }
示例#3
0
        public void WritePad(int alignment)
        {
            int needed = ProtocolInformation.PadNeeded((int)stream.Position, alignment);

            if (needed == 0)
            {
                return;
            }
            stream.Write(nullBytes, 0, needed);
        }
示例#4
0
        public IEnumerable <Signature> StepInto(Signature sig)
        {
            if (sig == Signature.VariantSig)
            {
                Signature valueSig = ReadSignature();
                yield return(valueSig);

                yield break;
            }

            // No need to handle dicts specially. IsArray does the job
            if (sig.IsArray)
            {
                Signature elemSig = sig.GetElementSignature();
                uint      ln      = ReadUInt32();
                ReadPad(elemSig.Alignment);
                int endPos = pos + (int)ln;
                while (pos < endPos)
                {
                    yield return(elemSig);
                }
                yield break;
            }

            if (sig.IsDictEntry)
            {
                pos = ProtocolInformation.Padded(pos, sig.Alignment);
                Signature sigKey, sigValue;
                sig.GetDictEntrySignatures(out sigKey, out sigValue);
                yield return(sigKey);

                yield return(sigValue);

                yield break;
            }

            if (sig.IsStruct)
            {
                pos = ProtocolInformation.Padded(pos, sig.Alignment);
                foreach (Signature fieldSig in sig.GetFieldSignatures())
                {
                    yield return(fieldSig);
                }
                yield break;
            }

            throw new Exception("Can't step into '" + sig + "'");
        }
示例#5
0
        public TArray[] ReadArray <TArray> ()
        {
            uint ln       = ReadUInt32();
            Type elemType = typeof(TArray);

            if (ln > ProtocolInformation.MaxArrayLength)
            {
                throw new Exception("Array length " + ln + " exceeds maximum allowed " + ProtocolInformation.MaxArrayLength + " bytes");
            }

            //advance to the alignment of the element
            ReadPad(ProtocolInformation.GetAlignment(Signature.TypeToDType(elemType)));

            if (elemType.IsPrimitive)
            {
                // Fast path for primitive types (except bool which isn't blittable and take another path)
                if (elemType != typeof(bool))
                {
                    return(MarshalArray <TArray> (ln));
                }
                else
                {
                    return((TArray[])(Array)MarshalBoolArray(ln));
                }
            }

            var list   = new List <TArray> ();
            int endPos = pos + (int)ln;

            while (pos < endPos)
            {
                list.Add((TArray)ReadValue(elemType));
            }

            if (pos != endPos)
            {
                throw new Exception("Read pos " + pos + " != ep " + endPos);
            }

            return(list.ToArray());
        }
示例#6
0
 static int GetAlignmentFromPrimitiveType(Type type)
 {
     return(ProtocolInformation.GetAlignment(Signature.TypeCodeToDType(Type.GetTypeCode(type))));
 }
示例#7
0
        // Note: This method doesn't support aggregate signatures
        public bool StepOver(Signature sig)
        {
            if (sig == Signature.VariantSig)
            {
                Signature valueSig = ReadSignature();
                return(StepOver(valueSig));
            }

            if (sig == Signature.StringSig)
            {
                uint valueLength = ReadUInt32();
                pos += (int)valueLength;
                pos++;
                return(true);
            }

            if (sig == Signature.ObjectPathSig)
            {
                uint valueLength = ReadUInt32();
                pos += (int)valueLength;
                pos++;
                return(true);
            }

            if (sig == Signature.SignatureSig)
            {
                byte valueLength = ReadByte();
                pos += valueLength;
                pos++;
                return(true);
            }

            // No need to handle dicts specially. IsArray does the job
            if (sig.IsArray)
            {
                Signature elemSig = sig.GetElementSignature();
                uint      ln      = ReadUInt32();
                pos  = ProtocolInformation.Padded(pos, elemSig.Alignment);
                pos += (int)ln;
                return(true);
            }

            int endPos = pos;

            if (sig.GetFixedSize(ref endPos))
            {
                pos = endPos;
                return(true);
            }

            if (sig.IsDictEntry)
            {
                pos = ProtocolInformation.Padded(pos, sig.Alignment);
                Signature sigKey, sigValue;
                sig.GetDictEntrySignatures(out sigKey, out sigValue);
                if (!StepOver(sigKey))
                {
                    return(false);
                }
                if (!StepOver(sigValue))
                {
                    return(false);
                }
                return(true);
            }

            if (sig.IsStruct)
            {
                pos = ProtocolInformation.Padded(pos, sig.Alignment);
                foreach (Signature fieldSig in sig.GetFieldSignatures())
                {
                    if (!StepOver(fieldSig))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            throw new Exception("Can't step over '" + sig + "'");
        }