1 //------------------------------------------------------------------------------
2 // <copyright file="DataRecordInternal.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 namespace System.Data.Common {
12 using System.Collections;
13 using System.ComponentModel;
15 using System.Data.ProviderBase;
16 using System.Diagnostics;
18 using System.Threading;
20 internal sealed class DataRecordInternal : DbDataRecord, ICustomTypeDescriptor {
21 private SchemaInfo[] _schemaInfo;
22 private object[] _values;
23 private PropertyDescriptorCollection _propertyDescriptors;
24 private FieldNameLookup _fieldNameLookup; // MDAC 69015
26 // copy all runtime data information
27 internal DataRecordInternal(SchemaInfo[] schemaInfo, object[] values, PropertyDescriptorCollection descriptors, FieldNameLookup fieldNameLookup) {
28 Debug.Assert(null != schemaInfo, "invalid attempt to instantiate DataRecordInternal with null schema information");
29 Debug.Assert(null != values, "invalid attempt to instantiate DataRecordInternal with null value[]");
30 _schemaInfo = schemaInfo;
32 _propertyDescriptors = descriptors;
33 _fieldNameLookup = fieldNameLookup;
36 // copy all runtime data information
37 internal DataRecordInternal(object[] values, PropertyDescriptorCollection descriptors, FieldNameLookup fieldNameLookup) {
38 Debug.Assert(null != values, "invalid attempt to instantiate DataRecordInternal with null value[]");
40 _propertyDescriptors = descriptors;
41 _fieldNameLookup = fieldNameLookup;
44 internal void SetSchemaInfo(SchemaInfo[] schemaInfo) {
45 Debug.Assert(null == _schemaInfo, "invalid attempt to override DataRecordInternal schema information");
46 _schemaInfo = schemaInfo;
49 public override int FieldCount {
51 return _schemaInfo.Length;
55 public override int GetValues(object[] values) {
57 throw ADP.ArgumentNull("values");
60 int copyLen = (values.Length < _schemaInfo.Length) ? values.Length : _schemaInfo.Length;
61 for (int i = 0; i < copyLen; i++) {
62 values[i] = _values[i];
67 public override string GetName(int i) {
68 return _schemaInfo[i].name;
72 public override object GetValue(int i) {
76 public override string GetDataTypeName(int i) {
77 return _schemaInfo[i].typeName;
80 public override Type GetFieldType(int i) {
81 return _schemaInfo[i].type;
84 public override int GetOrdinal(string name) { // MDAC 69015
85 return _fieldNameLookup.GetOrdinal(name); // MDAC 71470
88 public override object this[int i] {
94 public override object this[string name] {
96 return GetValue(GetOrdinal(name));
100 public override bool GetBoolean(int i) {
101 return((bool) _values[i]);
104 public override byte GetByte(int i) {
105 return((byte) _values[i]);
108 public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) {
112 byte[] data = (byte[])_values[i];
114 cbytes = data.Length;
116 // since arrays can't handle 64 bit values and this interface doesn't
117 // allow chunked access to data, a dataIndex outside the rang of Int32
119 if (dataIndex > Int32.MaxValue) {
120 throw ADP.InvalidSourceBufferIndex(cbytes, dataIndex, "dataIndex");
123 ndataIndex = (int)dataIndex;
125 // if no buffer is passed in, return the number of characters we have
130 if (ndataIndex < cbytes) {
131 // help the user out in the case where there's less data than requested
132 if ((ndataIndex + length) > cbytes)
133 cbytes = cbytes - ndataIndex;
138 // until arrays are 64 bit, we have to do these casts
139 Array.Copy(data, ndataIndex, buffer, bufferIndex, (int)cbytes);
141 catch (Exception e) {
143 if (ADP.IsCatchableExceptionType(e)) {
144 cbytes = data.Length;
147 throw ADP.InvalidDataLength(length);
149 // if bad buffer index, throw
150 if (bufferIndex < 0 || bufferIndex >= buffer.Length)
151 throw ADP.InvalidDestinationBufferIndex(length, bufferIndex, "bufferIndex");
153 // if bad data index, throw
154 if (dataIndex < 0 || dataIndex >= cbytes)
155 throw ADP.InvalidSourceBufferIndex(length, dataIndex, "dataIndex");
157 // if there is not enough room in the buffer for data
158 if (cbytes + bufferIndex > buffer.Length)
159 throw ADP.InvalidBufferSizeOrIndex(cbytes, bufferIndex);
168 public override char GetChar(int i) {
171 s = (string)_values[i];
172 char[] c = s.ToCharArray();
176 public override long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) {
181 // if the object doesn't contain a char[] then the user will get an exception
182 s = (string)_values[i];
184 char[] data = s.ToCharArray();
186 cchars = data.Length;
188 // since arrays can't handle 64 bit values and this interface doesn't
189 // allow chunked access to data, a dataIndex outside the rang of Int32
191 if (dataIndex > Int32.MaxValue) {
192 throw ADP.InvalidSourceBufferIndex(cchars, dataIndex, "dataIndex");
195 ndataIndex = (int)dataIndex;
198 // if no buffer is passed in, return the number of characters we have
203 if (ndataIndex < cchars) {
204 // help the user out in the case where there's less data than requested
205 if ((ndataIndex + length) > cchars)
206 cchars = cchars - ndataIndex;
211 Array.Copy(data, ndataIndex, buffer, bufferIndex, cchars);
213 catch (Exception e) {
215 if (ADP.IsCatchableExceptionType(e)) {
216 cchars = data.Length;
219 throw ADP.InvalidDataLength(length);
221 // if bad buffer index, throw
222 if (bufferIndex < 0 || bufferIndex >= buffer.Length)
223 throw ADP.InvalidDestinationBufferIndex(buffer.Length, bufferIndex, "bufferIndex");
225 // if bad data index, throw
226 if (ndataIndex < 0 || ndataIndex >= cchars)
227 throw ADP.InvalidSourceBufferIndex(cchars, dataIndex, "dataIndex");
229 // if there is not enough room in the buffer for data
230 if (cchars + bufferIndex > buffer.Length)
231 throw ADP.InvalidBufferSizeOrIndex(cchars, bufferIndex);
240 public override Guid GetGuid(int i) {
241 return ((Guid)_values[i]);
245 public override Int16 GetInt16(int i) {
246 return((Int16) _values[i]);
249 public override Int32 GetInt32(int i) {
250 return((Int32) _values[i]);
253 public override Int64 GetInt64(int i) {
254 return((Int64) _values[i]);
257 public override float GetFloat(int i) {
258 return((float) _values[i]);
261 public override double GetDouble(int i) {
262 return((double) _values[i]);
265 public override string GetString(int i) {
266 return((string) _values[i]);
269 public override Decimal GetDecimal(int i) {
270 return((Decimal) _values[i]);
273 public override DateTime GetDateTime(int i) {
274 return((DateTime) _values[i]);
277 public override bool IsDBNull(int i) {
278 object o = _values[i];
279 return (null == o || Convert.IsDBNull(o));
283 // ICustomTypeDescriptor
286 AttributeCollection ICustomTypeDescriptor.GetAttributes() {
287 return new AttributeCollection((Attribute[])null);
291 string ICustomTypeDescriptor.GetClassName() {
295 string ICustomTypeDescriptor.GetComponentName() {
299 TypeConverter ICustomTypeDescriptor.GetConverter() {
303 EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() {
308 PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() {
312 object ICustomTypeDescriptor.GetEditor(Type editorBaseType) {
316 EventDescriptorCollection ICustomTypeDescriptor.GetEvents() {
317 return new EventDescriptorCollection(null);
320 EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) {
321 return new EventDescriptorCollection(null);
324 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() {
325 return((ICustomTypeDescriptor)this).GetProperties(null);
328 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) {
329 if(_propertyDescriptors == null) {
330 _propertyDescriptors = new PropertyDescriptorCollection(null);
332 return _propertyDescriptors;
335 object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) {
340 // this doesn't change per record, only alloc once
341 internal struct SchemaInfo {
343 public string typeName;