1 //------------------------------------------------------------------------------
2 // <copyright file="FieldNameLookup.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">[....]</owner>
6 // <owner current="false" primary="false">[....]</owner>
7 //------------------------------------------------------------------------------
13 using System.Collections;
14 using System.ComponentModel;
16 using System.Data.Common;
17 using System.Diagnostics;
18 using System.Globalization;
21 internal sealed class FieldNameLookup { // V1.2.3300, MDAC 69015, 71470
23 // hashtable stores the index into the _fieldNames, match via case-sensitive
24 private Hashtable _fieldNameLookup;
26 // original names for linear searches when exact matches fail
27 private string[] _fieldNames;
29 // if _defaultLocaleID is -1 then _compareInfo is initialized with InvariantCulture CompareInfo
30 // otherwise it is specified by the server? for the correct compare info
31 private CompareInfo _compareInfo;
32 private int _defaultLocaleID;
34 public FieldNameLookup(System.Collections.ObjectModel.ReadOnlyCollection<string> columnNames, int defaultLocaleID) {
36 int length = columnNames.Count;
37 string[] fieldNames = new string[length];
38 for (int i = 0; i < length; ++i) {
39 fieldNames[i] = columnNames[i];
40 Debug.Assert(null != fieldNames[i], "MDAC 66681");
42 _fieldNames = fieldNames;
43 _defaultLocaleID = defaultLocaleID;
47 public FieldNameLookup(IDataRecord reader, int defaultLocaleID) { // V1.2.3300
49 int length = reader.FieldCount;
50 string[] fieldNames = new string[length];
51 for (int i = 0; i < length; ++i) {
52 fieldNames[i] = reader.GetName(i);
53 Debug.Assert(null != fieldNames[i], "MDAC 66681");
55 _fieldNames = fieldNames;
56 _defaultLocaleID = defaultLocaleID;
59 public int GetOrdinal(string fieldName) { // V1.2.3300
60 if (null == fieldName) {
61 throw EntityUtil.ArgumentNull("fieldName");
63 int index = IndexOf(fieldName);
65 throw EntityUtil.IndexOutOfRange(fieldName);
70 public int IndexOf(string fieldName) { // V1.2.3300
71 if (null == _fieldNameLookup) {
75 object value = _fieldNameLookup[fieldName];
77 // via case sensitive search, first match with lowest ordinal matches
81 // via case insensitive search, first match with lowest ordinal matches
82 index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase);
84 // do the slow search now (kana, width insensitive comparison)
85 index = LinearIndexOf(fieldName, EntityUtil.StringCompareOptions);
91 private int LinearIndexOf(string fieldName, CompareOptions compareOptions) {
92 CompareInfo compareInfo = _compareInfo;
93 if (null == compareInfo) {
94 if (-1 != _defaultLocaleID) {
95 compareInfo = CompareInfo.GetCompareInfo(_defaultLocaleID);
97 if (null == compareInfo) {
98 compareInfo = CultureInfo.InvariantCulture.CompareInfo;
100 _compareInfo = compareInfo;
102 int length = _fieldNames.Length;
103 for (int i = 0; i < length; ++i) {
104 if (0 == compareInfo.Compare(fieldName, _fieldNames[i], compareOptions)) {
105 _fieldNameLookup[fieldName] = i; // add an exact match for the future
112 // RTM common code for generating Hashtable from array of column names
113 private void GenerateLookup() {
114 int length = _fieldNames.Length;
115 Hashtable hash = new Hashtable(length);
117 // via case sensitive search, first match with lowest ordinal matches
118 for (int i = length-1; 0 <= i; --i) {
119 string fieldName = _fieldNames[i];
122 _fieldNameLookup = hash;