ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/xmltv_parser/trunk/libxmltv/Extensions.cs
(Generate patch)

Comparing trunk/libxmltv/Extensions.cs (file contents):
Revision 196 by william, Sat Mar 16 21:53:19 2013 UTC vs.
Revision 197 by william, Sat Mar 16 22:02:01 2013 UTC

--- trunk/libxmltv/Extensions.cs	2013/03/16 21:53:19	196
+++ trunk/libxmltv/Extensions.cs	2013/03/16 22:02:01	197
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Diagnostics;
 
 namespace libxmltv
 {
@@ -28,16 +29,50 @@ namespace libxmltv
 
     public static class extensions
     {
-        /// <summary>
-        /// Break a list of items into chunks of a specific size
-        /// </summary>
-        public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
+        public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source,
+            int chunkSize)
         {
-            while (source.Any())
+            // Validate parameters.
+            if (source == null) throw new ArgumentNullException("source");
+            if (chunkSize <= 0) throw new ArgumentOutOfRangeException("chunkSize",
+                "The chunkSize parameter must be a positive value.");
+
+            // Call the internal implementation.
+            return source.ChunkInternal(chunkSize);
+        }
+        private static IEnumerable<IEnumerable<T>> ChunkInternal<T>(this IEnumerable<T> source, int chunkSize)
+        {
+            // Validate parameters.
+            Debug.Assert(source != null);
+            Debug.Assert(chunkSize > 0);
+
+            // Get the enumerator.  Dispose of when done.
+            using (IEnumerator<T> enumerator = source.GetEnumerator())
+                do
+                {
+                    // Move to the next element.  If there's nothing left
+                    // then get out.
+                    if (!enumerator.MoveNext()) yield break;
+
+                    // Return the chunked sequence.
+                    yield return ChunkSequence(enumerator, chunkSize);
+                } while (true);
+        }
+        private static IEnumerable<T> ChunkSequence<T>(IEnumerator<T> enumerator, int chunkSize)
+        {
+            // Validate parameters.
+            Debug.Assert(enumerator != null);
+            Debug.Assert(chunkSize > 0);
+
+            // The count.
+            int count = 0;
+
+            // There is at least one item.  Yield and then continue.
+            do
             {
-                yield return source.Take(chunksize);
-                source = source.Skip(chunksize);
-            }
+                // Yield the item.
+                yield return enumerator.Current;
+            } while (++count < chunkSize && enumerator.MoveNext());
         }
     }
 }