1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Diagnostics; 6 7 namespace System.Data 8 { 9 /// <summary> 10 /// Represents an custom error that can be associated with a <see cref='System.Data.DataRow'/>. 11 /// </summary> 12 internal sealed class DataError 13 { 14 private string _rowError = string.Empty; 15 16 // column-level errors 17 private int _count; 18 private ColumnError[] _errorList; 19 internal const int initialCapacity = 1; 20 DataError()21 internal DataError() { } 22 DataError(string rowError)23 internal DataError(string rowError) 24 { 25 SetText(rowError); 26 } 27 28 internal string Text 29 { 30 get { return _rowError; } 31 set { SetText(value); } 32 } 33 34 internal bool HasErrors => _rowError.Length != 0 || _count != 0; 35 36 // this method resets the error to the new value. SetColumnError(DataColumn column, string error)37 internal void SetColumnError(DataColumn column, string error) 38 { 39 Debug.Assert(column != null, "Invalid (null) argument"); 40 Debug.Assert(column.Table != null, "Invalid (loose) column"); 41 if (error == null || error.Length == 0) 42 { 43 // remove error from the collection 44 Clear(column); 45 } 46 else 47 { 48 if (_errorList == null) 49 { 50 _errorList = new ColumnError[initialCapacity]; 51 } 52 int i = IndexOf(column); 53 _errorList[i]._column = column; 54 _errorList[i]._error = error; 55 column._errors++; 56 if (i == _count) 57 { 58 _count++; 59 } 60 } 61 } 62 GetColumnError(DataColumn column)63 internal string GetColumnError(DataColumn column) 64 { 65 for (int i = 0; i < _count; i++) 66 { 67 if (_errorList[i]._column == column) 68 { 69 return _errorList[i]._error; 70 } 71 } 72 73 return string.Empty; 74 } 75 Clear(DataColumn column)76 internal void Clear(DataColumn column) 77 { 78 if (_count == 0) 79 { 80 return; 81 } 82 83 for (int i = 0; i < _count; i++) 84 { 85 if (_errorList[i]._column == column) 86 { 87 Array.Copy(_errorList, i + 1, _errorList, i, _count - i - 1); 88 _count--; 89 column._errors--; 90 Debug.Assert(column._errors >= 0, "missing error counts"); 91 } 92 } 93 } 94 Clear()95 internal void Clear() 96 { 97 for (int i = 0; i < _count; i++) 98 { 99 _errorList[i]._column._errors--; 100 Debug.Assert(_errorList[i]._column._errors >= 0, "missing error counts"); 101 } 102 _count = 0; 103 _rowError = string.Empty; 104 } 105 GetColumnsInError()106 internal DataColumn[] GetColumnsInError() 107 { 108 var cols = new DataColumn[_count]; 109 110 for (int i = 0; i < _count; i++) 111 { 112 cols[i] = _errorList[i]._column; 113 } 114 115 return cols; 116 } 117 118 /// <summary> 119 /// Sets the error message for the <see cref='System.Data.DataError'/>. 120 /// </summary> SetText(string errorText)121 private void SetText(string errorText) 122 { 123 if (null == errorText) 124 { 125 errorText = string.Empty; 126 } 127 _rowError = errorText; 128 } 129 IndexOf(DataColumn column)130 internal int IndexOf(DataColumn column) 131 { 132 // try to find the column 133 for (int i = 0; i < _count; i++) 134 { 135 if (_errorList[i]._column == column) 136 { 137 return i; 138 } 139 } 140 141 if (_count >= _errorList.Length) 142 { 143 int newCapacity = Math.Min(_count * 2, column.Table.Columns.Count); 144 var biggerList = new ColumnError[newCapacity]; 145 Array.Copy(_errorList, 0, biggerList, 0, _count); 146 _errorList = biggerList; 147 } 148 return _count; 149 } 150 151 internal struct ColumnError 152 { 153 internal DataColumn _column; 154 internal string _error; 155 }; 156 } 157 } 158