// Header format is: yyyyuua{yv} public byte[] GetHeaderData() { WvDbusWriter w = new WvDbusWriter(); w.Write((byte)endian); w.Write((byte)type); w.Write((byte)flags); w.Write((byte)Dbus.Protocol.Version); w.Write(Body != null ? (uint)Body.Length : 0); w.Write((uint)serial); // This two-step process is a little convoluted because of the // way the WriteArray function needs to work. That, in turn, // is convoluted because the alignment of an array is complicated: // there's different padding for zero-element arrays than for // nonzero-element arrays, and WriteArray does that for us, // which means it needs to know in advance how many elements // are in our array. var l = new List<Dbus.Field>(); if (sender.ne()) l.Add(Dbus.Field.Sender); if (dest.ne()) l.Add(Dbus.Field.Destination); if (rserial.HasValue) l.Add(Dbus.Field.ReplySerial); if (signature.ne()) l.Add(Dbus.Field.Signature); if (path.ne()) l.Add(Dbus.Field.Path); if (ifc.ne()) l.Add(Dbus.Field.Interface); if (method.ne()) l.Add(Dbus.Field.Member); if (err.ne()) l.Add(Dbus.Field.ErrorName); w.WriteArray(8, l, (w2, i) => { switch (i) { case Dbus.Field.Sender: wws(w2, i, "s", sender); break; case Dbus.Field.Destination: wws(w2, i, "s", dest); break; case Dbus.Field.ReplySerial: wv.assert(rserial.Value != 0); wwu(w2, i, "u", rserial.Value); break; case Dbus.Field.Signature: wwsig(w2, i, "g", signature); break; case Dbus.Field.Path: wws(w2, i, "o", path); break; case Dbus.Field.Interface: wws(w2, i, "s", ifc); break; case Dbus.Field.Member: wws(w2, i, "s", method); break; case Dbus.Field.ErrorName: wws(w2, i, "s", err); break; default: break; // unknown field code, ignore } }); w.WritePad(8); // the header is *always* a multiple of 8 return w.ToArray(); }