Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
ISOLatin1AccentFilter.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using Lucene.Net.Analysis.Tokenattributes;
20 
21 namespace Lucene.Net.Analysis
22 {
23 
36  [Obsolete("If you build a new index, use ASCIIFoldingFilter which covers a superset of Latin 1. This class is included for use with existing indexes and will be removed in a future release (possible Lucene 4.0).")]
38  {
39  public ISOLatin1AccentFilter(TokenStream input):base(input)
40  {
41  termAtt = AddAttribute<ITermAttribute>();
42  }
43 
44  private char[] output = new char[256];
45  private int outputPos;
46  private readonly ITermAttribute termAtt;
47 
48  public override bool IncrementToken()
49  {
50  if (input.IncrementToken())
51  {
52  char[] buffer = termAtt.TermBuffer();
53  int length = termAtt.TermLength();
54  // If no characters actually require rewriting then we
55  // just return token as-is:
56  for (int i = 0; i < length; i++)
57  {
58  char c = buffer[i];
59  if (c >= '\u00c0' && c <= '\uFB06')
60  {
61  RemoveAccents(buffer, length);
62  termAtt.SetTermBuffer(output, 0, outputPos);
63  break;
64  }
65  }
66  return true;
67  }
68  return false;
69  }
70 
72  public void RemoveAccents(char[] input, int length)
73  {
74 
75  // Worst-case length required:
76  int maxSizeNeeded = 2 * length;
77 
78  int size = output.Length;
79  while (size < maxSizeNeeded)
80  size *= 2;
81 
82  if (size != output.Length)
83  output = new char[size];
84 
85  outputPos = 0;
86 
87  int pos = 0;
88 
89  for (int i = 0; i < length; i++, pos++)
90  {
91  char c = input[pos];
92 
93  // Quick test: if it's not in range then just keep
94  // current character
95  if (c < '\u00c0' || c > '\uFB06')
96  output[outputPos++] = c;
97  else
98  {
99  switch (c)
100  {
101 
102  case '\u00C0':
103  // À
104  case '\u00C1':
105  // �?
106  case '\u00C2':
107  // Â
108  case '\u00C3':
109  // Ã
110  case '\u00C4':
111  // Ä
112  case '\u00C5': // Ã…
113  output[outputPos++] = 'A';
114  break;
115 
116  case '\u00C6': // Æ
117  output[outputPos++] = 'A';
118  output[outputPos++] = 'E';
119  break;
120 
121  case '\u00C7': // Ç
122  output[outputPos++] = 'C';
123  break;
124 
125  case '\u00C8':
126  // È
127  case '\u00C9':
128  // É
129  case '\u00CA':
130  // Ê
131  case '\u00CB': // Ë
132  output[outputPos++] = 'E';
133  break;
134 
135  case '\u00CC':
136  // ÃŒ
137  case '\u00CD':
138  // �?
139  case '\u00CE':
140  // ÃŽ
141  case '\u00CF': // �?
142  output[outputPos++] = 'I';
143  break;
144 
145  case '\u0132': // IJ
146  output[outputPos++] = 'I';
147  output[outputPos++] = 'J';
148  break;
149 
150  case '\u00D0': // �?
151  output[outputPos++] = 'D';
152  break;
153 
154  case '\u00D1': // Ñ
155  output[outputPos++] = 'N';
156  break;
157 
158  case '\u00D2':
159  // Ã’
160  case '\u00D3':
161  // Ó
162  case '\u00D4':
163  // Ô
164  case '\u00D5':
165  // Õ
166  case '\u00D6':
167  // Ö
168  case '\u00D8': // Ø
169  output[outputPos++] = 'O';
170  break;
171 
172  case '\u0152': // Å’
173  output[outputPos++] = 'O';
174  output[outputPos++] = 'E';
175  break;
176 
177  case '\u00DE': // Þ
178  output[outputPos++] = 'T';
179  output[outputPos++] = 'H';
180  break;
181 
182  case '\u00D9':
183  // Ù
184  case '\u00DA':
185  // Ú
186  case '\u00DB':
187  // Û
188  case '\u00DC': // Ãœ
189  output[outputPos++] = 'U';
190  break;
191 
192  case '\u00DD':
193  // �?
194  case '\u0178': // Ÿ
195  output[outputPos++] = 'Y';
196  break;
197 
198  case '\u00E0':
199  // à
200  case '\u00E1':
201  // á
202  case '\u00E2':
203  // â
204  case '\u00E3':
205  // ã
206  case '\u00E4':
207  // ä
208  case '\u00E5': // Ã¥
209  output[outputPos++] = 'a';
210  break;
211 
212  case '\u00E6': // æ
213  output[outputPos++] = 'a';
214  output[outputPos++] = 'e';
215  break;
216 
217  case '\u00E7': // ç
218  output[outputPos++] = 'c';
219  break;
220 
221  case '\u00E8':
222  // è
223  case '\u00E9':
224  // é
225  case '\u00EA':
226  // ê
227  case '\u00EB': // ë
228  output[outputPos++] = 'e';
229  break;
230 
231  case '\u00EC':
232  // ì
233  case '\u00ED':
234  // í
235  case '\u00EE':
236  // î
237  case '\u00EF': // ï
238  output[outputPos++] = 'i';
239  break;
240 
241  case '\u0133': // ij
242  output[outputPos++] = 'i';
243  output[outputPos++] = 'j';
244  break;
245 
246  case '\u00F0': // ð
247  output[outputPos++] = 'd';
248  break;
249 
250  case '\u00F1': // ñ
251  output[outputPos++] = 'n';
252  break;
253 
254  case '\u00F2':
255  // ò
256  case '\u00F3':
257  // ó
258  case '\u00F4':
259  // ô
260  case '\u00F5':
261  // õ
262  case '\u00F6':
263  // ö
264  case '\u00F8': // ø
265  output[outputPos++] = 'o';
266  break;
267 
268  case '\u0153': // Å“
269  output[outputPos++] = 'o';
270  output[outputPos++] = 'e';
271  break;
272 
273  case '\u00DF': // ß
274  output[outputPos++] = 's';
275  output[outputPos++] = 's';
276  break;
277 
278  case '\u00FE': // þ
279  output[outputPos++] = 't';
280  output[outputPos++] = 'h';
281  break;
282 
283  case '\u00F9':
284  // ù
285  case '\u00FA':
286  // ú
287  case '\u00FB':
288  // û
289  case '\u00FC': // ü
290  output[outputPos++] = 'u';
291  break;
292 
293  case '\u00FD':
294  // ý
295  case '\u00FF': // ÿ
296  output[outputPos++] = 'y';
297  break;
298 
299  case '\uFB00': // ff
300  output[outputPos++] = 'f';
301  output[outputPos++] = 'f';
302  break;
303 
304  case '\uFB01': // �?
305  output[outputPos++] = 'f';
306  output[outputPos++] = 'i';
307  break;
308 
309  case '\uFB02': // fl
310  output[outputPos++] = 'f';
311  output[outputPos++] = 'l';
312  break;
313  // following 2 are commented as they can break the maxSizeNeeded (and doing *3 could be expensive)
314  // case '\uFB03': // ffi
315  // output[outputPos++] = 'f';
316  // output[outputPos++] = 'f';
317  // output[outputPos++] = 'i';
318  // break;
319  // case '\uFB04': // ffl
320  // output[outputPos++] = 'f';
321  // output[outputPos++] = 'f';
322  // output[outputPos++] = 'l';
323  // break;
324 
325  case '\uFB05': // ſt
326  output[outputPos++] = 'f';
327  output[outputPos++] = 't';
328  break;
329 
330  case '\uFB06': // st
331  output[outputPos++] = 's';
332  output[outputPos++] = 't';
333  break;
334 
335  default:
336  output[outputPos++] = c;
337  break;
338 
339  }
340  }
341  }
342  }
343  }
344 }