public void WriteDictionaryObject <T>(T val) { var type = typeof(T); FieldInfo[] fis = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); long origPos = stream.Position; // Pre-write array length field, we overwrite it at the end with the correct value WriteUInt32((uint)0); WritePad(8); long startPos = stream.Position; foreach (var fi in fis) { object fieldVal = fi.GetValue(val); if (fieldVal == null) { continue; } Type fieldType; string fieldName; PropertyTypeInspector.InspectField(fi, out fieldName, out fieldType); Signature sig = Signature.GetSig(fieldType, isCompileTimeType: true); WritePad(8); WriteString(fieldName); WriteSignature(sig); Write(fieldType, fieldVal, isCompileTimeType: true); } long endPos = stream.Position; uint ln = (uint)(endPos - startPos); stream.Position = origPos; if (ln > ProtocolInformation.MaxArrayLength) { throw new ProtocolException("Dict length " + ln + " exceeds maximum allowed " + ProtocolInformation.MaxArrayLength + " bytes"); } WriteUInt32(ln); stream.Position = endPos; }
public T ReadDictionaryObject <T>() { var type = typeof(T); FieldInfo[] fis = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); object val = Activator.CreateInstance(type); uint ln = ReadUInt32(); if (ln > ProtocolInformation.MaxArrayLength) { throw new ProtocolException("Dict length " + ln + " exceeds maximum allowed " + ProtocolInformation.MaxArrayLength + " bytes"); } ReadPad(8); int endPos = _pos + (int)ln; while (_pos < endPos) { ReadPad(8); var key = ReadString(); var sig = ReadSignature(); if (!sig.IsSingleCompleteType) { throw new InvalidOperationException(string.Format("ReadVariant need a single complete type signature, {0} was given", sig.ToString())); } // if the key contains a '-' which is an invalid identifier character, // we try and replace it with '_' and see if we find a match. // The name may be prefixed with '_'. var field = fis.Where(f => ((f.Name.Length == key.Length) || (f.Name.Length == key.Length + 1 && f.Name[0] == '_')) && (f.Name.EndsWith(key, StringComparison.Ordinal) || (key.Contains("-") && f.Name.Replace('_', '-').EndsWith(key, StringComparison.Ordinal)))).SingleOrDefault(); if (field == null) { var value = Read(sig.ToType()); } else { Type fieldType; string propertyName; PropertyTypeInspector.InspectField(field, out propertyName, out fieldType); if (sig != Signature.GetSig(fieldType, isCompileTimeType: true)) { throw new ArgumentException($"Dictionary '{type.FullName}' field '{field.Name}' with type '{fieldType.FullName}' cannot be read from D-Bus type '{sig}'"); } var readValue = Read(fieldType); field.SetValue(val, readValue); } } if (_pos != endPos) { throw new ProtocolException("Read pos " + _pos + " != ep " + endPos); } return((T)val); }