// 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(); }
// Utility API so you can say Get("foo"). public VxSchema Get(params string[] keys) { WvDbusMsg call = methodcall("GetSchema", "as"); WvDbusWriter writer = new WvDbusWriter(); if (keys == null) keys = new string[0]; writer.WriteArray(4, keys, (w2, k) => { w2.Write(k); }); call.Body = writer.ToArray(); WvDbusMsg reply = bus.send_and_wait(call); reply.check("a(sssy)"); VxSchema schema = new VxSchema(reply.iter().pop()); return schema; }
static void WriteColInfo(WvDbusWriter writer, VxColumnInfo[] colinfo) { // a(issnny) writer.WriteArray(8, colinfo, (w2, i) => { w2.Write(i.size); w2.Write(i.colname); w2.Write(i.coltype.ToString()); w2.Write(i.precision); w2.Write(i.scale); w2.Write(i.nullable); }); }
// A method exported over DBus but not exposed in ISchemaBackend public VxSchemaErrors DropSchema(params string[] keys) { WvDbusMsg call = methodcall("DropSchema", "as"); WvDbusWriter writer = new WvDbusWriter(); writer.WriteArray(4, keys, (w2, k) => { w2.Write(k); }); call.Body = writer.ToArray(); WvDbusMsg reply = bus.send_and_wait(call); if (reply.signature == VxSchemaErrors.GetDbusSignature()) return new VxSchemaErrors(reply.iter().pop()); else reply.check(VxSchemaErrors.GetDbusSignature()); return null; }
// a(issnny)vaay public static WvDbusWriter PrepareRecordsetWriter(VxColumnInfo[] colinfo, object[][] data, byte[][] nulldata) { WvDbusWriter writer = new WvDbusWriter(); // a(issnny) WriteColInfo(writer, colinfo); // v if (colinfo.Length <= 0) { // Some clients can't parse a() (empty struct) properly, so // we'll have an empty array of (i) instead. writer.WriteSig("a(i)"); } else writer.WriteSig(VxColumnInfoToArraySignature(colinfo)); // a(whatever) writer.WriteArray(8, data, (w2, r) => { for (int i = 0; i < colinfo.Length; i++) WriteV(w2, colinfo[i].VxColumnType, r[i]); }); // aay writer.WriteArray(4, nulldata, (w2, r) => { w2.Write(r); }); return writer; }