public virtual IEnumerator GetEnumerator()
        {
            // this seems like a hack, also this enumerator is NOT thread safe!
            m_EnumReset = true;
            m_EnumPos   = null;

            return((IEnumerator)this);
        }
 private void MergeSort()
 {
     // if list has more than 1 item, then sort it, otherwise our work is done for us.
     if (m_NodeCount > 1)
     {
         m_Head = RecursiveMergeSort(m_Head, m_NodeCount, out m_Tail);
     }
 }
        protected virtual int CompareNodes(DOSLinkedListNode Node1, DOSLinkedListNode Node2)
        {
            // If Nodes carried ints, theoretical algorithm here would be
            //  return Node1.Value - Node2.Value
            // Hence results are:
            //    postive int --> Node1 >  Node2
            //    zero        --> Node1 == Node2
            //    negative    --> Node1 <  Node2

            // higher class should override and do the compare, so we just return negative so nothing gets moved.
            return(-1);
        }
        protected override int CompareNodes(DOSLinkedListNode Node1, DOSLinkedListNode Node2)
        {
            int      Result = 0;
            DirStats Item1;
            DirStats Item2;
            ulong    Total1, Total2 = 0;

            if ((Node1 == null) || (Node2 == null))
            {
                return(0);
            }

            Item1 = (DirStats)Node1.Data;
            Item2 = (DirStats)Node2.Data;

            switch (SortType)
            {
            case DirStatsList.EnumSortType.DirName:
                Result = Item1.DirName.CompareTo(Item2.DirName);
                break;

            case DirStatsList.EnumSortType.TotalFileSize:
            default:
                Total1 = (Item1.NestedFileSize + Item1.LocalFileSize);
                Total2 = (Item2.NestedFileSize + Item2.LocalFileSize);

                // These are ulongs, I could type cast to int and just do math, but I
                // I think my method is more determinant and avoids weird cases
                // where integers (even 64-bit) might wrap around.

                if (Total1 == Total2)
                {
                    Result = 0;
                }
                else
                {
                    if (Total1 > Total2)
                    {
                        Result = 1;
                    }
                    else
                    {
                        Result = -1;
                    }
                }
                break;
            }

            return(Result * m_ReverseSortModifier);
        }
        public void Clear()
        {
            DOSLinkedListNode m_Cur = m_Head;
            DOSLinkedListNode m_Tmp = null;

            while (m_Cur != null)
            {
                m_Tmp = m_Cur;
                m_Cur = m_Cur.Next;

                m_Tmp.Previous = null;
                m_Tmp.Next     = null;
            }

            m_Tmp = null;

            m_Head      = null;
            m_Tail      = null;
            m_NodeCount = 0;
        }
        private DOSLinkedListNode RecursiveMergeSort(DOSLinkedListNode List, int ListSize, out DOSLinkedListNode NewTail)
        {
            DOSLinkedListNode NewList = null;
            DOSLinkedListNode Left    = List;
            DOSLinkedListNode Right   = List;
            int i        = 0;
            int ListHalf = (ListSize + 1) / 2;

            // make the 2 lists
            while ((Right != null) && (i < ListHalf))
            {
                Right = Right.Next;
                i++;
            }

            if ((Right != null) && (Right.Previous != null))
            {
                // separate left from right.
                Right.Previous.Next = null;
                Right.Previous      = null;
            }

            // Tests - Left has an item, Left is not right (i.e. empty),
            //  Left has more than one item (i.e. Next is not null)
            if ((Left != null) && (Left != Right) && (Left.Next != null))
            {
                Left = RecursiveMergeSort(Left, ListHalf, out NewTail);
            }

            // Tests - Right has an item, Right is not left,
            //   Right has more than one item (i.e. Next is not null)
            if ((Right != null) && (Right != Left) && (Right.Next != null))
            {
                Right = RecursiveMergeSort(Right, ListHalf, out NewTail);
            }

            // merge lists
            NewList = Merge(Left, Right, out NewTail);

            return(NewList);
        }
        public bool MoveNext()
        {
            if (m_EnumReset == true)
            {
                if (m_EnumForwards == true)
                {
                    m_EnumPos = m_Head;
                }
                else
                {
                    m_EnumPos = m_Tail;
                }

                m_EnumReset = false;
            }
            else
            {
                if (m_EnumPos != null)
                {
                    if (m_EnumForwards == true)
                    {
                        m_EnumPos = m_EnumPos.Next;
                    }
                    else
                    {
                        m_EnumPos = m_EnumPos.Previous;
                    }
                }
            }

            if (m_EnumPos != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private void AddNode(object Data, bool AddLastIfTrue)
        {
            DOSLinkedListNode NewNode = new DOSLinkedListNode(Data);

            if (m_Head == null)
            {
                // empty list
                if (m_Tail != null)
                {
                    throw new CountException("Programming Error! Linked List in unstable state");
                }

                m_Head      = NewNode;
                m_Tail      = NewNode;
                m_NodeCount = 1;
            }
            else
            {
                if (AddLastIfTrue == true)
                {
                    // add last code
                    NewNode.Previous = m_Tail;
                    m_Tail.Next      = NewNode;
                    m_Tail           = NewNode;
                }
                else
                {
                    // add first code
                    NewNode.Next    = m_Head;
                    m_Head.Previous = NewNode;
                    m_Head          = NewNode;
                }

                m_NodeCount++;
            }
        }
 public void Reset()
 {
     m_EnumReset = true;
     m_EnumPos   = null;
 }
        private DOSLinkedListNode Merge(DOSLinkedListNode Left, DOSLinkedListNode Right, out DOSLinkedListNode NewTail)
        {
            DOSLinkedListNode NewList         = null;
            DOSLinkedListNode CurrentListNode = null;
            DOSLinkedListNode NodePick        = null;

            if (Left == Right)
            {
                Right = null;
            }

            while ((Left != null) || (Right != null))
            {
                if (Left == null)                 // Case 1 - Left is empty, take from right.
                {
                    NodePick = Right;
                    Right    = Right.Next;
                }
                else
                {
                    if (Right == null)                     // Case 2 - Right is empty, take from left.
                    {
                        NodePick = Left;
                        Left     = Left.Next;
                    }
                    else
                    {
                        if (CompareNodes(Left, Right) < 0)                          // Case 3 - Compare items to see which goes first.
                        {
                            // Left goes first
                            NodePick = Left;
                            Left     = Left.Next;
                        }
                        else
                        {
                            NodePick = Right;
                            Right    = Right.Next;
                        }
                    }
                }

                // add item to NewList
                if (NewList == null)
                {
                    NewList           = NodePick;
                    NodePick.Next     = null;
                    NodePick.Previous = null;
                }
                else
                {
                    CurrentListNode.Next = NodePick;
                    NodePick.Next        = null;
                    NodePick.Previous    = CurrentListNode;
                }

                CurrentListNode = NodePick;
            }

            NewTail = CurrentListNode;
            return(NewList);
        }