2 // CodePointIndexer.cs : indexing table optimizer
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Globalization;
32 namespace Mono.Globalization.Unicode
34 internal class CodePointIndexer
36 public static Array CompressArray (
37 Array source, Type type, CodePointIndexer indexer)
40 for (int i = 0; i < indexer.ranges.Length; i++)
41 totalCount += indexer.ranges [i].Count;
43 Array ret = Array.CreateInstance (type, totalCount);
44 for (int i = 0; i < indexer.ranges.Length; i++)
47 indexer.ranges [i].Start,
49 indexer.ranges [i].IndexStart,
50 indexer.ranges [i].Count);
54 // This class is used to compactize indexes to limited areas so that
55 // we can save extraneous 0,0,0,0,0... in the tables.
56 internal class TableRange
58 public TableRange (int start, int end, int indexStart)
63 IndexStart = indexStart;
64 IndexEnd = IndexStart + Count;
67 public readonly int Start;
68 public readonly int End;
69 public readonly int Count;
70 public readonly int IndexStart;
71 public readonly int IndexEnd;
74 readonly TableRange [] ranges;
76 public readonly int TotalCount;
81 public CodePointIndexer (int [] starts, int [] ends, int defaultIndex, int defaultCP)
83 this.defaultIndex = defaultIndex;
84 this.defaultCP = defaultCP;
85 ranges = new TableRange [starts.Length];
86 for (int i = 0; i < ranges.Length; i++)
87 ranges [i] = new TableRange (starts [i],
88 ends [i], i == 0 ? 0 :
89 ranges [i - 1].IndexStart +
90 ranges [i - 1].Count);
91 for (int i = 0; i < ranges.Length; i++)
92 TotalCount += ranges [i].Count;
94 // for (int i = 0; i < ranges.Length; i++)
95 // Console.Error.WriteLine ("RANGES [{0}] : {1:x} to {2:x} index {3:x} to {4:x}. total {5:x}", i, ranges [i].Start, ranges [i].End, ranges [i].IndexStart, ranges [i].IndexEnd, ranges [i].Count);
96 // Console.Error.WriteLine ("Total items: {0:X} ({1})", TotalCount, TotalCount);
99 public int ToIndex (int cp)
101 for (int t = 0; t < ranges.Length; t++) {
102 if (cp < ranges [t].Start)
104 else if (cp < ranges [t].End)
105 return cp - ranges [t].Start + ranges [t].IndexStart;
108 // throw new SystemException (String.Format ("Should not happen: no map definition for cp {0:x}({1})", cp, (char) cp));
111 public int ToCodePoint (int i)
113 for (int t = 0; t < ranges.Length; t++) {
115 if (t > 0 && i < ranges [t - 1].IndexEnd)
116 return defaultCP; // unexpected out of range
117 if (ranges [t].IndexStart <= i &&
118 i < ranges [t].IndexEnd)
119 return i - ranges [t].IndexStart
122 if (i < ranges [t].IndexStart)
124 if (i < ranges [t].IndexEnd)
125 return i - ranges [t].IndexStart
129 // throw new SystemException (String.Format ("Should not happen: no map definition for index {0:x}({1})", i, i));