コード例 #1
0
        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;
        }
コード例 #2
0
ファイル: MessageReader.cs プロジェクト: thosil/Tmds.DBus
        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);
        }