Collections/RingCollection.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 298 96263190189a
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections;
    13 using System.Collections.Generic;
    14 
    15 namespace OpenHardwareMonitor.Collections {
    16   public class RingCollection<T> : IEnumerable<T> {
    17 
    18     private T[] array;
    19 
    20     // first item of collection
    21     private int head;
    22 
    23     // index after the last item of the collection
    24     private int tail;
    25 
    26     // number of items in the collection
    27     private int size;
    28 
    29     public RingCollection() : this(0) { }
    30 
    31     public RingCollection(int capacity) {
    32       if (capacity < 0)
    33         throw new ArgumentOutOfRangeException("capacity");
    34       this.array = new T[capacity];
    35       this.head = 0; 
    36       this.tail = 0;
    37       this.size = 0;
    38     }
    39 
    40     public int Capacity {
    41       get {
    42         return array.Length;
    43       }
    44       set {
    45         T[] newArray = new T[value];
    46         if (size > 0) {
    47           if (head < tail) {
    48             Array.Copy(array, head, newArray, 0, size);
    49           } else {
    50             Array.Copy(array, head, newArray, 0, array.Length - head);
    51             Array.Copy(array, 0, newArray, array.Length - head, tail);
    52           }
    53         }
    54         this.array = newArray;
    55         this.head = 0;
    56         this.tail = size == value ? 0 : size;
    57       }
    58     }
    59 
    60     public void Clear() {
    61       
    62       // remove potential references 
    63       if (head < tail) {
    64         Array.Clear(array, head, size);
    65       } else {
    66         Array.Clear(array, 0, tail);
    67         Array.Clear(array, head, array.Length - head);
    68       }
    69 
    70       this.head = 0;
    71       this.tail = 0;
    72       this.size = 0;
    73     }
    74 
    75     public void Append(T item) {
    76       if (size == array.Length) {
    77         int newCapacity = array.Length * 3 / 2;
    78         if (newCapacity < array.Length + 8)
    79           newCapacity = array.Length + 8;
    80         Capacity = newCapacity;
    81       }
    82 
    83       array[tail] = item;
    84       tail = tail + 1 == array.Length ? 0 : tail + 1;
    85       size++;
    86     }
    87 
    88     public T Remove() {
    89       if (size == 0)
    90         throw new InvalidOperationException();
    91 
    92       T result = array[head];
    93       array[head] = default(T);
    94       head = head + 1 == array.Length ? 0 : head + 1;
    95       size--;
    96 
    97       return result;
    98     }
    99 
   100     public int Count {
   101       get {
   102         return size;
   103       }
   104     }
   105 
   106     public T this[int index] {
   107       get {
   108         if (index < 0 || index >= size)
   109           throw new IndexOutOfRangeException();
   110         int i = head + index;
   111         if (i >= array.Length)
   112           i -= array.Length;
   113         return array[i];
   114       }
   115       set {
   116         if (index < 0 || index >= size)
   117           throw new IndexOutOfRangeException();
   118         int i = head + index;
   119         if (i >= array.Length)
   120           i -= array.Length;
   121         array[i] = value;
   122       }
   123     }
   124 
   125     public T First {
   126       get {
   127         if (size == 0)
   128           throw new InvalidOperationException();
   129         return array[head];
   130       }
   131       set {
   132         if (size == 0)
   133           throw new InvalidOperationException();
   134         array[head] = value;
   135       }
   136     }
   137 
   138     public T Last {
   139       get {
   140         if (size == 0)
   141           throw new InvalidOperationException();
   142         return array[tail == 0 ? array.Length - 1 : tail - 1];
   143       }
   144       set {
   145         if (size == 0)
   146           throw new InvalidOperationException();
   147         array[tail == 0 ? array.Length - 1 : tail - 1] = value;
   148       }
   149     }
   150 
   151     IEnumerator<T> IEnumerable<T>.GetEnumerator() {
   152       return new RingCollection<T>.Enumerator(this);
   153     }
   154 
   155     IEnumerator IEnumerable.GetEnumerator() {
   156       return new RingCollection<T>.Enumerator(this);
   157     }
   158 
   159     private struct Enumerator : IEnumerator<T>, IEnumerator {
   160 
   161       private RingCollection<T> collection;
   162       private int index;
   163 
   164       public Enumerator(RingCollection<T> collection) {
   165         this.collection = collection;
   166         this.index = -1;
   167       }
   168 
   169       public void Dispose() {
   170         this.index = -2;
   171       }
   172 
   173       public void Reset() {
   174         this.index = -1;
   175       }
   176 
   177       public T Current {
   178         get {
   179           if (index < 0)
   180             throw new InvalidOperationException();
   181           return collection[index];
   182         }
   183       }
   184 
   185       object IEnumerator.Current {
   186         get {
   187           if (index < 0)
   188             throw new InvalidOperationException();
   189           return collection[index];
   190         }
   191       }
   192 
   193       public bool MoveNext() {
   194         if (index == -2)
   195           return false;
   196 
   197         index++;
   198 
   199         if (index == collection.size) {
   200           index = -2;
   201           return false;
   202         }
   203 
   204         return true;
   205       }
   206     }
   207   }
   208 }