// 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.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 = Protocol.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 = Protocol.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 = Protocol.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 + "'"); //return false; }
//this requires a seekable stream for now public unsafe void WriteArray <T> (T[] val) { Type elemType = typeof(T); if (elemType == typeof(byte)) { if (val.Length > Protocol.MaxArrayLength) { throw new Exception("Array length " + val.Length + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } Write((uint)val.Length); stream.Write((byte[])(object)val, 0, val.Length); return; } if (elemType.IsEnum) { elemType = Enum.GetUnderlyingType(elemType); } Signature sigElem = Signature.GetSig(elemType); int fixedSize = 0; if (endianness == Connection.NativeEndianness && elemType.IsValueType && !sigElem.IsStruct && sigElem.GetFixedSize(ref fixedSize)) { int byteLength = fixedSize * val.Length; if (byteLength > Protocol.MaxArrayLength) { throw new Exception("Array length " + byteLength + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } Write((uint)byteLength); WritePad(sigElem.Alignment); GCHandle valHandle = GCHandle.Alloc(val, GCHandleType.Pinned); IntPtr p = valHandle.AddrOfPinnedObject(); byte[] data = new byte[byteLength]; byte * bp = (byte *)p; for (int i = 0; i != byteLength; i++) { data[i] = bp[i]; } stream.Write(data, 0, data.Length); valHandle.Free(); return; } long origPos = stream.Position; Write((uint)0); //advance to the alignment of the element WritePad(sigElem.Alignment); long startPos = stream.Position; TypeWriter <T> tWriter = TypeImplementer.GetTypeWriter <T> (); foreach (T elem in val) { tWriter(this, elem); } long endPos = stream.Position; uint ln = (uint)(endPos - startPos); stream.Position = origPos; if (ln > Protocol.MaxArrayLength) { throw new Exception("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } Write(ln); stream.Position = endPos; }
// 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.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 = Protocol.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 = Protocol.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 = Protocol.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 + "'"); //return false; }