Update Reference Sources to .NET Framework 4.6
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Common / FieldNameLookup.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="FieldNameLookup.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="false" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
8
9
10 namespace System.Data 
11 {
12     using System;
13     using System.Collections;
14     using System.ComponentModel;
15     using System.Data;
16     using System.Data.Common;
17     using System.Diagnostics;
18     using System.Globalization;
19     using System.Text;
20     
21     internal sealed class FieldNameLookup { // V1.2.3300, MDAC 69015, 71470
22
23         // hashtable stores the index into the _fieldNames, match via case-sensitive
24         private Hashtable _fieldNameLookup;
25
26         // original names for linear searches when exact matches fail
27         private string[] _fieldNames;
28
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;
33
34         public FieldNameLookup(System.Collections.ObjectModel.ReadOnlyCollection<string> columnNames, int defaultLocaleID) {
35
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");
41             }
42             _fieldNames = fieldNames;
43             _defaultLocaleID = defaultLocaleID;
44             GenerateLookup();
45         }
46
47         public FieldNameLookup(IDataRecord reader, int defaultLocaleID) { // V1.2.3300
48
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");
54             }
55             _fieldNames = fieldNames;
56             _defaultLocaleID = defaultLocaleID;
57         }
58
59         public int GetOrdinal(string fieldName) { // V1.2.3300
60             if (null == fieldName) {
61                 throw EntityUtil.ArgumentNull("fieldName");
62             }
63             int index = IndexOf(fieldName);
64             if (-1 == index) {
65                 throw EntityUtil.IndexOutOfRange(fieldName);
66             }
67             return index;
68         }
69
70         public int IndexOf(string fieldName) { // V1.2.3300
71             if (null == _fieldNameLookup) {
72                 GenerateLookup();
73             }
74             int index;
75             object value = _fieldNameLookup[fieldName];
76             if (null != value) {
77                 // via case sensitive search, first match with lowest ordinal matches
78                 index = (int) value;
79             }
80             else {
81                 // via case insensitive search, first match with lowest ordinal matches
82                 index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase);
83                 if (-1 == index) {
84                     // do the slow search now (kana, width insensitive comparison)
85                     index = LinearIndexOf(fieldName, EntityUtil.StringCompareOptions);
86                 }
87             }
88             return index;
89         }
90
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);
96                 }
97                 if (null == compareInfo) {
98                     compareInfo = CultureInfo.InvariantCulture.CompareInfo;
99                 }
100                 _compareInfo = compareInfo;
101             }
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
106                     return i;
107                 }
108             }
109             return -1;
110         }
111
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);
116
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];
120                 hash[fieldName] = i;
121             }
122             _fieldNameLookup = hash;
123         }
124     }
125 }