/// <summary>
        /// <para>
        /// Instantiates a sorter based on the sortCriteria string. The basic algorithm for
        /// sorting is to supply a comma-separated-value (CSV) listing of property names
        /// (easily retrieved from using <see cref="Tags"/>'s indexer with the
        /// <see cref="CommonPropertyNames"/>,
        /// <see cref="_DC"/>,
        /// <see cref="_UPNP"/>, or
        /// <see cref="_ATTRIB"/>
        /// enumerators.)
        /// with each property name having a + or - sign to indicate ascending or descending
        /// order of the sorting for that property name. Assuming "T" is an instance of a
        /// <see cref="Tags"/> object.
        /// Example below.
        /// </para>
        ///
        /// <para>
        /// <list type="table">
        /// <item>
        /// <term>"+" +T[CommonPropertyNames.title]+ ",-" +T[CommonPropertyNames.creator]</term>
        /// <description>Sorts with ascending titles first, then descending creators</description>
        /// </item>
        /// </list>
        /// </para>
        ///
        /// </summary>
        /// <param name="forceDistinction">if true, then any comparison that evaluates to equal will force an arbitrary ordering of the two objects in question</param>
        /// <param name="sortCriteria">a string with the property names in a CSV list, where
        /// each property name has a + or - sign to indicate ascending or descending order</param>
        public MediaSorter(bool forceDistinction, string sortCriteria)
        {
            this.forceDistinction = forceDistinction;

            if (sortCriteria != null)
            {
                if (sortCriteria != "")
                {
                    DText parser = new DText();
                    parser.ATTRMARK = ",";
                    parser[0]       = sortCriteria;

                    int size = parser.DCOUNT();
                    this.sortKeys = new ArrayList(size);

                    // iterate through properties for sorting
                    //
                    for (int i = 1; i <= size; i++)
                    {
                        string prop    = parser[i].Trim();
                        char   asc_dsc = prop[0];

                        string property = prop.Substring(1);

                        bool ascending = true;
                        if (asc_dsc == '-')
                        {
                            ascending = false;
                        }
                        else if (asc_dsc == '+')
                        {
                            ascending = true;
                        }
                        else
                        {
                            throw new UPnPCustomException(709, "Invalid sort flag.");
                        }

                        MetadataValueComparer mvc = new MetadataValueComparer(property, ascending);

                        this.sortKeys.Add(mvc);
                    }
                }
            }

            if (this.sortKeys == null)
            {
                this.sortKeys = new ArrayList(0);
            }
        }
        /// <summary>
        /// Evaluates a subexpression of a whole expression.
        /// </summary>
        /// <param name="media">the media object with the metadata</param>
        /// <param name="prop">the property/attribute metadata to examine</param>
        /// <param name="op">the operator to use for examination</param>
        /// <param name="val">the value to compare against in string form</param>
        /// <returns></returns>
        /// <exception cref="OpenSource.UPnP.AV.CdsMetadata.Error_MalformedSearchCriteria">
        /// Thrown when the expression provided at constructor time could not
        /// be used to evaluate the media because of syntax errors in
        /// the expression.
        /// </exception>
        private bool Evaluate(IUPnPMedia media, string prop, OperatorTokens op, string val)
        {
            bool result = false;

            TagExtractor te = (TagExtractor)this.m_PE[prop];

            IList values = te.Extract(media);


            if (op == OperatorTokens.Exists)
            {
                bool testVal = (string.Compare(val, "true", true) == 0);

                result = (
                    ((values.Count > 0) && (testVal)) ||
                    ((values.Count == 0) && (testVal == false))
                    );
            }
            else
            {
                foreach (object testVal in values)
                {
                    int opCode = (int)op;
                    if ((opCode >= (int)OperatorTokens.Equal) && (opCode <= (int)OperatorTokens.GreaterThanEqualTo))
                    {
                        // Compare using a relational operator
                        //
                        try
                        {
                            int relResult = MetadataValueComparer.CompareTagValues(testVal, val, this.IgnoreCase);

                            if (relResult == 0)
                            {
                                result = true;
                                break;
                            }
                        }
                        catch                         //(Exception e)
                        {
                            string opString = Enum.GetName(typeof(OperatorTokens), opCode);
                            throw new Error_MalformedSearchCriteria("(" + val + ") " + opString + " " + testVal.ToString() + ") could not occur.");
                        }
                    }
                    else if (op == OperatorTokens.Contains)
                    {
                        string tv  = testVal.ToString();
                        int    pos = tv.IndexOf(val);
                        result = (pos >= 0);
                    }
                    else if (op == OperatorTokens.DoesNotContain)
                    {
                        string tv  = testVal.ToString();
                        int    pos = tv.IndexOf(val);
                        result = (pos < 0);
                    }
                    else if (op == OperatorTokens.DerivedFrom)
                    {
                        string tv = testVal.ToString();

                        result = tv.StartsWith(val);
                    }
                }
            }

            return(result);
        }
Пример #3
0
		/// <summary>
		/// <para>
		/// Instantiates a sorter based on the sortCriteria string. The basic algorithm for
		/// sorting is to supply a comma-separated-value (CSV) listing of property names
		/// (easily retrieved from using <see cref="Tags"/>'s indexer with the
		/// <see cref="CommonPropertyNames"/>, 
		/// <see cref="_DC"/>, 
		/// <see cref="_UPNP"/>, or
		/// <see cref="_ATTRIB"/>
		/// enumerators.) 
		/// with each property name having a + or - sign to indicate ascending or descending
		/// order of the sorting for that property name. Assuming "T" is an instance of a
		/// <see cref="Tags"/> object.
		/// Example below.
		/// </para>
		/// 
		/// <para>
		/// <list type="table">
		/// <item>
		/// <term>"+" +T[CommonPropertyNames.title]+ ",-" +T[CommonPropertyNames.creator]</term>
		/// <description>Sorts with ascending titles first, then descending creators</description>
		/// </item>
		/// </list>
		/// </para>
		/// 
		/// </summary>
		/// <param name="forceDistinction">if true, then any comparison that evaluates to equal will force an arbitrary ordering of the two objects in question</param>
		/// <param name="sortCriteria">a string with the property names in a CSV list, where
		/// each property name has a + or - sign to indicate ascending or descending order</param>
		public MediaSorter (bool forceDistinction, string sortCriteria)
		{
			this.forceDistinction = forceDistinction;

			if (sortCriteria != null)
			{
				if (sortCriteria != "")
				{
					DText parser = new DText();
					parser.ATTRMARK = ",";
					parser[0] = sortCriteria;

					int size = parser.DCOUNT();
					this.sortKeys = new ArrayList(size);
					
					// iterate through properties for sorting
					//
					for (int i=1; i <= size; i++)
					{
						string prop = parser[i].Trim();
						char asc_dsc = prop[0];

						string property = prop.Substring(1);

						bool ascending = true;
						if (asc_dsc == '-')
						{
							ascending = false;
						}
						else if (asc_dsc == '+')
						{
							ascending = true;
						}
						else
						{
							throw new UPnPCustomException(709, "Invalid sort flag.");
						}

						MetadataValueComparer mvc = new MetadataValueComparer(property, ascending);

						this.sortKeys.Add(mvc);
					}
				}
			}

			if (this.sortKeys == null)
			{
				this.sortKeys = new ArrayList(0);
			}
		}