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(); }
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]); } } }
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 + "'"); }
// 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 + "'"); }