-
+// System.Web.UI.WebControls.PagedDataSource.cs
+//
+// Author: Duncan Mak (duncan@novell.com)
+// Jackson Harper (jackson@ximian.com)
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-/**
- * Namespace: System.Web.UI.WebControls
- * Class: PagedDataSource
- *
- * Author: Gaurav Vaish
- * Maintainer: gvaish@iitk.ac.in
- * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>
- * Implementation: yes
- * Status: 100%
- *
- * (C) Gaurav Vaish (2002)
- */
-
-using System;
-using System.ComponentModel;
+
using System.Collections;
-using System.Web;
-using System.Web.UI;
+using System.ComponentModel;
+using System.Security.Permissions;
-namespace System.Web.UI.WebControls
-{
+namespace System.Web.UI.WebControls {
+
+ // CAS - no inheritance demand required because the class is sealed
+ [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class PagedDataSource : ICollection, IEnumerable, ITypedList
{
- private int pageSize;
- private bool allowPaging;
- private int currentPageIndex;
- private bool allowCustomPaging;
- private int virtualCount;
+ int page_size, current_page_index, virtual_count;
+ bool allow_paging, allow_custom_paging, allow_server_paging;
+ IEnumerable source;
-#if NET_2_0
- DataSourceSelectArguments arguments;
- DataSourceView view;
- bool serverPaging;
-#endif
-
- private IEnumerable dataSource;
-
- public PagedDataSource()
+ public PagedDataSource ()
{
- Initialize();
- }
-
- private void Initialize()
- {
- pageSize = 10;
- allowPaging = false;
- currentPageIndex = 0;
- allowCustomPaging = false;
- virtualCount = 0;
+ page_size = 10;
}
+ public bool AllowCustomPaging {
+ get { return allow_custom_paging; }
+ set {
+ allow_custom_paging = value;
#if NET_2_0
- public DataSourceSelectArguments DataSourceSelectArguments {
- get { return arguments; }
- set { arguments = value; }
- }
-
- public DataSourceView DataSourceView {
- get { return view; }
- set { view = value; }
- }
-
- public bool AllowServerPaging {
- get { return serverPaging; }
- set { serverPaging = value; }
- }
-
- public bool IsServerPagingEnabled {
- get { return allowPaging && serverPaging; }
- }
-
- public void SetItemCountFromPageIndex (int highestPageIndex)
- {
- arguments.StartRowIndex = CurrentPageIndex * PageSize;
- arguments.MaximumRows = (highestPageIndex - CurrentPageIndex) * PageSize + 1;
- IEnumerable data = view.ExecuteSelect (arguments);
-
- virtualCount = CurrentPageIndex * PageSize;
- if (data is ICollection) {
- virtualCount += ((ICollection)data).Count;
- } else {
- IEnumerator e = data.GetEnumerator ();
- while (e.MoveNext())
- virtualCount++;
- }
- }
-
+ // AllowCustomPaging and AllowServerPaging are mutually exclusive
+ if (allow_custom_paging)
+ allow_server_paging = false;
#endif
-
- public bool AllowCustomPaging
- {
- get
- {
- return allowCustomPaging;
- }
- set
- {
- allowCustomPaging = value;
}
}
- public bool AllowPaging
- {
- get
- {
- return allowPaging;
- }
- set
- {
- allowPaging = value;
- }
+ public bool AllowPaging {
+ get { return allow_paging; }
+ set { allow_paging = value; }
}
- public int Count
- {
- get
- {
- if(dataSource != null)
- {
- if(!IsPagingEnabled)
- {
- return DataSourceCount;
- }
- if(IsCustomPagingEnabled)
- {
- return pageSize;
- }
-
- if(IsLastPage)
- {
- int n = DataSourceCount;
- if (n == 0) return 0;
- else return (n - FirstIndexInPage);
- }
- return pageSize;
+ public int Count {
+ get {
+ if (source == null)
+ return 0;
+
+ if (IsPagingEnabled) {
+ if (IsCustomPagingEnabled || !IsLastPage)
+ return page_size;
+ return DataSourceCount - FirstIndexInPage;
}
- return 0;
- }
- }
- public int CurrentPageIndex
- {
- get
- {
- return currentPageIndex;
+ return DataSourceCount;
}
+ }
- set
- {
- currentPageIndex = value;
- }
+ public int CurrentPageIndex {
+ get { return current_page_index; }
+ set { current_page_index = value; }
}
- public IEnumerable DataSource
- {
- get
- {
- return dataSource;
- }
- set
- {
- dataSource = value;
- }
+ public IEnumerable DataSource {
+ get { return source; }
+ set { source = value; }
}
- public int DataSourceCount
- {
- get
- {
- if(dataSource != null)
- {
+ public int DataSourceCount {
+ get {
+ if (source == null)
+ return 0;
+
+ if (IsCustomPagingEnabled
#if NET_2_0
- if (serverPaging)
- {
- return virtualCount;
- }
+ || IsServerPagingEnabled
#endif
- if(IsCustomPagingEnabled)
- {
- return virtualCount;
- }
- if(dataSource is ICollection)
- {
- return ((ICollection)dataSource).Count;
- }
- throw new HttpException(HttpRuntime.FormatResourceString("PagedDataSource_Cannot_Get_Count"));
- }
- return 0;
- }
- }
+ )
+ return virtual_count;
- public int FirstIndexInPage
- {
- get
- {
- if(dataSource != null && IsPagingEnabled && !IsCustomPagingEnabled)
- {
- return (currentPageIndex * pageSize);
- }
- return 0;
- }
- }
+ if (source is ICollection)
+ return ((ICollection) source).Count;
- public bool IsCustomPagingEnabled
- {
- get
- {
- return (IsPagingEnabled && allowCustomPaging);
+ throw new HttpException ("The data source must implement ICollection");
}
}
- public bool IsFirstPage
- {
- get
- {
- return (!IsPagingEnabled || (CurrentPageIndex == 0));
+ public int FirstIndexInPage {
+ get {
+ if (!IsPagingEnabled || IsCustomPagingEnabled ||
+#if NET_2_0
+ IsServerPagingEnabled ||
+#endif
+ source == null)
+ return 0;
+
+ return current_page_index * page_size;
}
}
- public bool IsLastPage
- {
- get
- {
- return (!IsPagingEnabled || (CurrentPageIndex == (PageCount - 1)) || PageCount <= 1);
- }
+ public bool IsCustomPagingEnabled {
+ get { return IsPagingEnabled && allow_custom_paging; }
}
- public bool IsPagingEnabled
- {
- get
- {
- return (allowPaging && pageSize != 0);
- }
+#if NET_2_0
+ public bool IsServerPagingEnabled {
+ get { return IsPagingEnabled && allow_server_paging; }
}
+#endif
- public bool IsReadOnly
- {
- get
- {
- return false;
+ public bool IsFirstPage {
+ get {
+ if (!allow_paging)
+ return true;
+
+ return current_page_index == 0;
}
}
- public bool IsSynchronized
- {
- get
- {
- return false;
+ public bool IsLastPage {
+ get {
+ if (!allow_paging || page_size == 0)
+ return true;
+
+ return (current_page_index == (PageCount - 1));
}
}
- public int PageCount
- {
- get
- {
- if(dataSource != null) {
- if(!IsPagingEnabled)
- return 1;
-
- int total = DataSourceCount;
- return (total + pageSize - 1)/pageSize;
- }
- return 0;
- }
+ public bool IsPagingEnabled {
+ get { return (allow_paging && page_size != 0); }
}
- public int PageSize
- {
- get
- {
- return pageSize;
- }
- set
- {
- pageSize = value;
- }
+ public bool IsReadOnly {
+ get { return false; } // as documented
}
- public object SyncRoot
- {
- get
- {
- return this;
- }
+ public bool IsSynchronized {
+ get { return false; } // as documented
}
- public int VirtualCount
- {
- get
- {
- return virtualCount;
- }
- set
- {
- virtualCount = value;
+ public int PageCount {
+ get {
+ if (source == null)
+ return 0;
+
+ if (!IsPagingEnabled || DataSourceCount == 0 || page_size == 0)
+ return 1;
+
+ return (DataSourceCount + page_size - 1) / page_size;
}
}
- public void CopyTo(Array array, int index)
- {
- IEnumerator enumerator = this.GetEnumerator();
- if(enumerator == null) return;
+ public int PageSize {
+ get { return page_size; }
+ set { page_size = value; }
+ }
- while(enumerator.MoveNext())
- array.SetValue(enumerator.Current, index++);
+ public object SyncRoot {
+ get { return this; }
}
- public IEnumerator GetEnumerator()
- {
+ public int VirtualCount {
+ get { return virtual_count; }
+ set { virtual_count = value; }
+ }
#if NET_2_0
- int fInd = serverPaging ? 0 : FirstIndexInPage;
-#else
- int fInd = FirstIndexInPage;
-#endif
- int count = -1;
-
- if(dataSource is ICollection)
- {
- count = Count;
- }
-
- if(dataSource is IList)
- {
- return (new PrivateListEnumerator((IList)dataSource, fInd, count));
- }
- if(dataSource is Array)
- {
- return (new PrivateArrayEnumerator((object[])dataSource, fInd, count));
+ public bool AllowServerPaging {
+ get {
+ return allow_server_paging;
}
- if(dataSource is ICollection)
- {
- return (new PrivateICollectionEnumerator((ICollection)dataSource, fInd, count));
+ set {
+ allow_server_paging = value;
+ // AllowCustomPaging and AllowServerPaging are mutually exclusive
+ if (allow_server_paging)
+ allow_custom_paging = false;
}
- if(allowCustomPaging)
- {
- return (new PrivateIEnumeratorEnumerator(dataSource.GetEnumerator(), Count));
- }
- return dataSource.GetEnumerator();
}
+#endif
- class PrivateIEnumeratorEnumerator : IEnumerator
+ public void CopyTo (Array array, int index)
{
- private int index;
- private int max;
-
- private IEnumerator enumerator;
-
- public PrivateIEnumeratorEnumerator(IEnumerator enumerator, int count)
- {
- this.enumerator = enumerator;
- index = -1;
- max = count;
- }
+ foreach (object o in source)
+ array.SetValue (o, index++);
+ }
- public bool MoveNext()
- {
- enumerator.MoveNext();
- index++;
- return (index < max);
+ public IEnumerator GetEnumerator ()
+ {
+ // IList goes first, as it implements ICollection
+ IList list = source as IList;
+ int first = 0;
+ int count;
+ int limit;
+ if (list != null) {
+ first = FirstIndexInPage;
+ count = ((ICollection) source).Count;
+ limit = ((first + page_size) > count) ? (count - first) : page_size;
+ return GetListEnum (list, first, first + limit);
}
- public void Reset()
- {
- index = -1;
- enumerator.Reset();
+ ICollection col = source as ICollection;
+ if (col != null) {
+ first = FirstIndexInPage;
+ count = col.Count;
+ limit = ((first + page_size) > count) ? (count - first) : page_size;
+ return GetEnumeratorEnum (col.GetEnumerator (), first, first + page_size);
}
- public object Current
- {
- get
- {
- return enumerator.Current;
- }
- }
+ return source.GetEnumerator ();
}
- class PrivateICollectionEnumerator : IEnumerator
+ public PropertyDescriptorCollection GetItemProperties (PropertyDescriptor [] list_accessors)
{
- private int index;
- private int start;
- private int max;
-
- private ICollection collection;
- private IEnumerator collEnum;
-
- public PrivateICollectionEnumerator(ICollection collection, int start, int count)
- {
- this.collection = collection;
- this.start = start;
- index = -1;
- max = start + count;
- if(max > collection.Count)
- {
- max = collection.Count;
- }
- }
-
- public bool MoveNext()
- {
- if(collEnum == null)
- {
- int cIndex = 0;
- collEnum = collection.GetEnumerator();
- while(cIndex < start)
- {
- collEnum.MoveNext();
- cIndex++;
- }
- }
- collEnum.MoveNext();
- index++;
- return (start + index < max);
- }
-
- public void Reset()
- {
- index = -1;
- collEnum = null;
- }
+ ITypedList typed = source as ITypedList;
+ if (typed == null)
+ return null;
+ return typed.GetItemProperties (list_accessors);
+ }
- public object Current
- {
- get
- {
- return collEnum.Current;
- }
- }
+ public string GetListName (PropertyDescriptor [] list_accessors)
+ {
+ return String.Empty; // as documented
}
- class PrivateArrayEnumerator : IEnumerator
+#if TARGET_JVM
+ internal class ListEnum : IEnumerator
{
- private int index;
- private int start;
- private int max;
- private object[] values;
+ int start;
+ int end;
+ int ind;
+ IList list;
- public PrivateArrayEnumerator(object[] values, int start, int count)
+ internal ListEnum(IList list, int start, int end)
{
- this.values = values;
- this.start = start;
- index = -1;
- max = start + count;
- if(max > this.values.Length)
- {
- max = this.values.Length;
- }
+ this.list = list;
+ this.start = start;
+ this.end = end;
+ this.ind = start - 1;
}
public bool MoveNext()
{
- index++;
- return (index + start < max);
+ ind++;
+ return (ind < end);
}
- public void Reset()
- {
- index = -1;
- }
+ public void Reset() { ind = start - 1; }
+ public object Current { get { return list[ind]; }}
+ }
- public object Current
- {
- get
- {
- if(index >= 0)
- {
- return values[index + start];
- }
- throw new InvalidOperationException("Enumerator_MoveNext_Not_Called");
- }
- }
+ private IEnumerator GetListEnum (IList list, int start, int end)
+ {
+ if (!allow_paging)
+ end = list.Count;
+ return new ListEnum(list, start, end);
}
- class PrivateListEnumerator : IEnumerator
+ internal class EnumeratorEnum : IEnumerator
{
- private int index;
- private int start;
- private int max;
- private IList collection;
+ int start;
+ int end;
+ int ind;
+ IEnumerator en;
+ PagedDataSource parent;
- public PrivateListEnumerator(IList list, int start, int count)
+ internal EnumeratorEnum(PagedDataSource parent, IEnumerator en, int start, int end)
{
- collection = list;
+ this.parent = parent;
+ this.en = en;
this.start = start;
- index = -1;
- max = start + count;
- if(max > list.Count)
- {
- max = list.Count;
- }
+ this.end = end;
+ this.ind = start - 1;
+ for (int i = 0; i < start; i++)
+ en.MoveNext ();
}
public bool MoveNext()
{
- index++;
- return (index + start < max);
+ ind++;
+ return (!parent.allow_paging || ind < end) && en.MoveNext ();
}
public void Reset()
{
- index = -1;
+ throw new NotSupportedException();
}
- public object Current
- {
- get
- {
- if(index >= 0)
- {
- return collection[index + start];
- }
- throw new InvalidOperationException("Enumerator_MoveNext_Not_Called");
- }
- }
+ public object Current { get { return en.Current; }}
}
- public string GetListName(PropertyDescriptor[] listAccessors)
+ private IEnumerator GetEnumeratorEnum (IEnumerator e, int start, int end)
{
- return String.Empty;
+ return new EnumeratorEnum(this, e, start, end);
+ }
+#else
+ private IEnumerator GetListEnum (IList list, int start, int end)
+ {
+ if (!AllowPaging)
+ end = list.Count;
+ else if (start >= list.Count)
+ yield break;
+
+ for (int i = start; i < end; i++)
+ yield return list [i];
}
- public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
+ private IEnumerator GetEnumeratorEnum (IEnumerator e, int start, int end)
{
- if(dataSource != null)
- {
- if(dataSource is ITypedList)
- {
- return ((ITypedList)dataSource).GetItemProperties(listAccessors);
- }
- }
- return null;
+ for (int i = 0; i < start; i++)
+ e.MoveNext ();
+ for (int i = start; (!allow_paging || i < end) && e.MoveNext (); i++)
+ yield return e.Current;
}
+#endif
}
}
+