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 void WritePad(int alignment) { int needed = ProtocolInformation.PadNeeded((int)stream.Position, alignment); if (needed == 0) { return; } stream.Write(nullBytes, 0, needed); }
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 + "'"); }
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()); }
static int GetAlignmentFromPrimitiveType(Type type) { return(ProtocolInformation.GetAlignment(Signature.TypeCodeToDType(Type.GetTypeCode(type)))); }
// 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 + "'"); }