コード例 #1
0
        /** Reads a list of dataobjects from this nodes child of given name, returns null if not found.  Can be referenced, or full. */
        protected List <T> ReadNamedDataObjectList <T>(XElement node, string name, FieldReferenceType referenceType, DataLibrary <T> library = null) where T : NamedDataObject
        {
            node = node.Element(name);

            if (node == null)
            {
                return(null);
            }

            var    list        = new List <T>();
            string subNodeName = GetClassAttributesForType(typeof(T)).NodeName;

            library = library ?? NamedDataObject.GetLibraryForType <T>();

            if (library == null && referenceType != FieldReferenceType.Full)
            {
                throw new Exception("Can not load type " + typeof(T) + " as no default library is defined, and it is stored referenced.");
            }

            foreach (var subNode in node.Elements(subNodeName))
            {
                T item = null;

                switch (referenceType)
                {
                case FieldReferenceType.Full:
                    item = (T)Activator.CreateInstance(typeof(T));
                    item.ReadNode(subNode);
                    break;

                case FieldReferenceType.ID:
                    var fieldId = int.Parse(subNode.Value);
                    item = (T)library._byID(fieldId);
                    break;

                case FieldReferenceType.Name:
                    var fieldName = subNode.Value;
                    item = (T)library._byName(fieldName);
                    break;
                }

                list.Add(item);
            }

            return(list);
        }
コード例 #2
0
        /**
         * Writes a value to the writer.
         * Object can be primative, string, or DataObject, or enum
         * Or an array or list of either primative, string or DataObject.
         *
         * If name is null or empty value will be written to node directly.
         *
         * If byReference is true any NamedDataObjects will be referenced by name instead of writing them out in full.
         */
        protected void WriteValue(XElement node, string name, object value, FieldReferenceType referenceType = FieldReferenceType.Full)
        {
            if (value == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(name))
            {
                WriteDirect(node, value, referenceType);
                return;
            }

            var subNode = new XElement(name);

            WriteDirect(subNode, value, referenceType);
            node.Add(subNode);
        }
コード例 #3
0
ファイル: Util.cs プロジェクト: bsimser/CoM
 /** New display extended field attributes.  Use null string for default fieldname */
 public FieldAttrAttribute(string displayName, FieldReferenceType referenceType = FieldReferenceType.Full, bool ignore = false)
 {
     DisplayName   = displayName;
     Ignore        = ignore;
     ReferenceType = referenceType;
 }
コード例 #4
0
        /**
         * Writes a value direct to a node.
         */
        protected void WriteDirect(XElement node, object value, FieldReferenceType referenceType = FieldReferenceType.Full)
        {
            if (value == null)
            {
                return;
            }

            // Todo: use stringbuilder for performance.

            var valueType = value.GetType();

            // -----------------------------------------
            // single items

            if (valueType.IsPrimitive || (value is string))
            {
                node.Value = value.ToString();
                return;
            }

            if (value is DateTime)
            {
                node.Value = ((DateTime)value).ToString("u");
                return;
            }

            // use custom dataobject serialization
            if (value is DataObject)
            {
                if (value is NamedDataObject)
                {
                    switch (referenceType)
                    {
                    case FieldReferenceType.Name:
                        node.Value = (value as NamedDataObject).Name;
                        return;

                    case FieldReferenceType.ID:
                        node.Value = (value as NamedDataObject).ID.ToString();
                        return;
                    }
                }
                (value as DataObject).WriteNode(node);
                return;
            }

            if (valueType.IsEnum)
            {
                node.Value = (value as Enum).ToString();
                return;
            }

            // check for ReadWriteable interface
            if (value is iSerializable)
            {
                (value as iSerializable).WriteNode(node);
                return;
            }

            // -----------------------------------------
            // arrays and lists

            // simple arrays
            if (valueType.IsArray && valueType.HasElementType && (valueType.GetElementType().IsPrimitive || valueType.GetElementType() == typeof(string)))
            {
                var array = (Array)value;
                var sb    = new StringBuilder();

                foreach (var element in array)
                {
                    sb.Append(element + ",");
                }

                if (sb.Length >= 1)
                {
                    sb.Remove(sb.Length - 1, 1);
                }

                node.Value = sb.ToString();
                return;
            }

            // array or list of data objects
            if (value is IList)
            {
                var list = (IList)(value);

                if (list.Count == 0)
                {
                    return;
                }

                Type entryType = null;
                if (valueType.GetGenericArguments().Length >= 1)
                {
                    entryType = valueType.GetGenericArguments()[0];
                }

                // If we know the generic type use this, otherwise just check each entry.
                // Knowing the generic type allows nulls to be written with the correct type.
                if (entryType != null)
                {
                    var classAttr = DataObject.GetClassAttributesForType(entryType);
                    var nodeName  = classAttr.NodeName;
                    foreach (object entry in list)
                    {
                        WriteValue(node, nodeName, entry, referenceType);
                    }
                }
                else
                {
                    foreach (object entry in list)
                    {
                        var classAttr = DataObject.GetClassAttributesForType(entry.GetType());
                        var nodeName  = classAttr.NodeName;
                        WriteValue(node, nodeName, entry, referenceType);
                    }
                }

                return;
            }

            // -----------------------------------------
            // some random types

            if (value is BitArray)
            {
                string stringValue = "";
                foreach (bool bit in (value as BitArray))
                {
                    stringValue += bit ? "1" : "0";
                }
                node.Value = stringValue;
                return;
            }

            if (value is Dictionary <string, string> )
            {
                foreach (KeyValuePair <string, string> entry in (value as Dictionary <String, String>))
                {
                    node.Add(new XElement("entry", entry.Key + ": " + entry.Value));
                }
                return;
            }

            if (value is Dictionary <string, int> )
            {
                foreach (KeyValuePair <string, int> entry in (value as Dictionary <String, int>))
                {
                    node.Add(new XElement("entry", entry.Key + ": " + entry.Value));
                }
                return;
            }

            // just convert to a string as a fall back
            Trace.LogWarning("Unknown datatype [" + valueType + "] while trying to serialize a [" + this.GetType() + "] object.");
            node.Value = value.ToString();
        }
コード例 #5
0
        /**
         * Loads a given object from node.
         * If the node contains a reference (i.e. an id or name but not the full object) then specify the reference type,
         * and library to search.
         *
         * Supported types.
         *
         * Primatives and strings
         * Data objects (referenced and full)
         * Arrays of primatives or strings
         *
         * Not implement yet: Lists of primatives, Lists or arrays of dataObjects.
         *
         */
        protected object ReadObject(XElement node, string name, Type type, FieldReferenceType referenceType = FieldReferenceType.Full, IDataLibrary library = null)
        {
            XElement sourceNode = (node.Element(name));

            if (sourceNode == null)
            {
                return(null);
            }

            // Primatives

            if (type.IsEnum)
            {
                return(ReadEnum(node, type, name));
            }

            if (type == typeof(Color))
            {
                return(ReadColor(node, name));
            }

            if (type == typeof(bool))
            {
                return(ReadBool(node, name));
            }
            if (type.IsIntType())
            {
                return(ReadInt(node, name));
            }
            if (type == typeof(float))
            {
                return(ReadFloat(node, name));
            }
            if (type == typeof(string))
            {
                return(ReadValue(node, name));
            }
            if (type == typeof(DateTime))
            {
                return(ReadDateTime(node, name));
            }

            // Data object.

            if (type.IsSubclassOf(typeof(DataObject)))
            {
                switch (referenceType)
                {
                case FieldReferenceType.ID:
                case FieldReferenceType.Name:

                    if (!type.IsSubclassOf(typeof(NamedDataObject)))
                    {
                        throw new Exception("Type must be subclass of NamedDataObject");
                    }

                    if (referenceType == FieldReferenceType.ID)
                    {
                        return(library._byID(ReadInt(node, name)));
                    }
                    else
                    {
                        return(library._byName(ReadValue(node, name)));
                    }

                case FieldReferenceType.Full:

                    var result = Activator.CreateInstance(type);
                    (result as DataObject).ReadNode(sourceNode);
                    return(result);
                }
            }

            // Serializable
            if (typeof(iSerializable).IsAssignableFrom(type))
            {
                var result = Activator.CreateInstance(type);
                (result as iSerializable).ReadNode(sourceNode);
                return(result);
            }

            // Arrays.

            if (type.IsArray)
            {
                switch (Type.GetTypeCode(type.GetElementType()))
                {
                case TypeCode.Boolean:
                    return(ReadArray <bool>(node, name));

                case TypeCode.Byte:
                    return(ReadArray <byte>(node, name));

                case TypeCode.Char:
                    return(ReadArray <char>(node, name));

                case TypeCode.DateTime:
                    return(ReadArray <DateTime>(node, name));

                case TypeCode.Double:
                    return(ReadArray <double>(node, name));

                case TypeCode.Single:
                    return(ReadArray <Single>(node, name));

                case TypeCode.Int16:
                    return(ReadArray <Int16>(node, name));

                case TypeCode.Int32:
                    return(ReadArray <Int32>(node, name));

                case TypeCode.Int64:
                    return(ReadArray <Int64>(node, name));

                case TypeCode.UInt16:
                    return(ReadArray <UInt16>(node, name));

                case TypeCode.UInt32:
                    return(ReadArray <UInt32>(node, name));

                case TypeCode.UInt64:
                    return(ReadArrayULong(node, name));
                }
            }

            // Try other types.

            if (type == typeof(BitArray))
            {
                return(ReadBitArray(node, name));
            }

            if (type.IsGenericList())
            {
                throw new Exception("Sorry, auto loading for generic lists are not yet supported for [" + type + "].");
            }

            throw new Exception("Can not read object of type " + type + " as it is not a known type.");
        }