pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / analysis / tokenattributes / CharTermAttributeImpl.java
1 package org.apache.lucene.analysis.tokenattributes;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.Serializable;
21 import java.nio.CharBuffer;
22
23 import org.apache.lucene.util.ArrayUtil;
24 import org.apache.lucene.util.AttributeImpl;
25 import org.apache.lucene.util.AttributeReflector;
26 import org.apache.lucene.util.RamUsageEstimator;
27
28 /**
29  * The term text of a Token.
30  */
31 public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttribute, TermAttribute, Cloneable, Serializable {
32   private static int MIN_BUFFER_SIZE = 10;
33   
34   private char[] termBuffer = new char[ArrayUtil.oversize(MIN_BUFFER_SIZE, RamUsageEstimator.NUM_BYTES_CHAR)];
35   private int termLength = 0;
36   
37   @Deprecated
38   public String term() {
39     // don't delegate to toString() here!
40     return new String(termBuffer, 0, termLength);
41   }
42
43   public final void copyBuffer(char[] buffer, int offset, int length) {
44     growTermBuffer(length);
45     System.arraycopy(buffer, offset, termBuffer, 0, length);
46     termLength = length;
47   }
48
49   @Deprecated
50   public void setTermBuffer(char[] buffer, int offset, int length) {
51     copyBuffer(buffer, offset, length);
52   }
53
54   @Deprecated
55   public void setTermBuffer(String buffer) {
56     int length = buffer.length();
57     growTermBuffer(length);
58     buffer.getChars(0, length, termBuffer, 0);
59     termLength = length;
60   }
61
62   @Deprecated
63   public void setTermBuffer(String buffer, int offset, int length) {
64     assert offset <= buffer.length();
65     assert offset + length <= buffer.length();
66     growTermBuffer(length);
67     buffer.getChars(offset, offset + length, termBuffer, 0);
68     termLength = length;
69   }
70
71   public final char[] buffer() {
72     return termBuffer;
73   }
74
75   @Deprecated
76   public char[] termBuffer() {
77     return termBuffer;
78   }
79   
80   public final char[] resizeBuffer(int newSize) {
81     if(termBuffer.length < newSize){
82       // Not big enough; create a new array with slight
83       // over allocation and preserve content
84       final char[] newCharBuffer = new char[ArrayUtil.oversize(newSize, RamUsageEstimator.NUM_BYTES_CHAR)];
85       System.arraycopy(termBuffer, 0, newCharBuffer, 0, termBuffer.length);
86       termBuffer = newCharBuffer;
87     }
88     return termBuffer;   
89   }
90
91   @Deprecated
92   public char[] resizeTermBuffer(int newSize) {
93     return resizeBuffer(newSize);
94   }
95   
96   private void growTermBuffer(int newSize) {
97     if(termBuffer.length < newSize){
98       // Not big enough; create a new array with slight
99       // over allocation:
100       termBuffer = new char[ArrayUtil.oversize(newSize, RamUsageEstimator.NUM_BYTES_CHAR)];
101     }
102   }
103   
104   @Deprecated
105   public int termLength() {
106     return termLength;
107   }
108
109   public final CharTermAttribute setLength(int length) {
110     if (length > termBuffer.length)
111       throw new IllegalArgumentException("length " + length + " exceeds the size of the termBuffer (" + termBuffer.length + ")");
112     termLength = length;
113     return this;
114   }
115   
116   public final CharTermAttribute setEmpty() {
117     termLength = 0;
118     return this;
119   }
120   
121   @Deprecated
122   public void setTermLength(int length) {
123     setLength(length);
124   }
125   
126   // *** CharSequence interface ***
127   public final int length() {
128     return termLength;
129   }
130   
131   public final char charAt(int index) {
132     if (index >= termLength)
133       throw new IndexOutOfBoundsException();
134     return termBuffer[index];
135   }
136   
137   public final CharSequence subSequence(final int start, final int end) {
138     if (start > termLength || end > termLength)
139       throw new IndexOutOfBoundsException();
140     return new String(termBuffer, start, end - start);
141   }
142   
143   // *** Appendable interface ***
144
145   public final CharTermAttribute append(CharSequence csq) {
146     if (csq == null) // needed for Appendable compliance
147       return appendNull();
148     return append(csq, 0, csq.length());
149   }
150   
151   public final CharTermAttribute append(CharSequence csq, int start, int end) {
152     if (csq == null) // needed for Appendable compliance
153       csq = "null";
154     final int len = end - start, csqlen = csq.length();
155     if (len < 0 || start > csqlen || end > csqlen)
156       throw new IndexOutOfBoundsException();
157     if (len == 0)
158       return this;
159     resizeBuffer(termLength + len);
160     if (len > 4) { // only use instanceof check series for longer CSQs, else simply iterate
161       if (csq instanceof String) {
162         ((String) csq).getChars(start, end, termBuffer, termLength);
163       } else if (csq instanceof StringBuilder) {
164         ((StringBuilder) csq).getChars(start, end, termBuffer, termLength);
165       } else if (csq instanceof CharTermAttribute) {
166         System.arraycopy(((CharTermAttribute) csq).buffer(), start, termBuffer, termLength, len);
167       } else if (csq instanceof CharBuffer && ((CharBuffer) csq).hasArray()) {
168         final CharBuffer cb = (CharBuffer) csq;
169         System.arraycopy(cb.array(), cb.arrayOffset() + cb.position() + start, termBuffer, termLength, len);
170       } else if (csq instanceof StringBuffer) {
171         ((StringBuffer) csq).getChars(start, end, termBuffer, termLength);
172       } else {
173         while (start < end)
174           termBuffer[termLength++] = csq.charAt(start++);
175         // no fall-through here, as termLength is updated!
176         return this;
177       }
178       termLength += len;
179       return this;
180     } else {
181       while (start < end)
182         termBuffer[termLength++] = csq.charAt(start++);
183       return this;
184     }
185   }
186   
187   public final CharTermAttribute append(char c) {
188     resizeBuffer(termLength + 1)[termLength++] = c;
189     return this;
190   }
191   
192   // *** For performance some convenience methods in addition to CSQ's ***
193   
194   public final CharTermAttribute append(String s) {
195     if (s == null) // needed for Appendable compliance
196       return appendNull();
197     final int len = s.length();
198     s.getChars(0, len, resizeBuffer(termLength + len), termLength);
199     termLength += len;
200     return this;
201   }
202   
203   public final CharTermAttribute append(StringBuilder s) {
204     if (s == null) // needed for Appendable compliance
205       return appendNull();
206     final int len = s.length();
207     s.getChars(0, len, resizeBuffer(termLength + len), termLength);
208     termLength += len;
209     return this;
210   }
211   
212   public final CharTermAttribute append(CharTermAttribute ta) {
213     if (ta == null) // needed for Appendable compliance
214       return appendNull();
215     final int len = ta.length();
216     System.arraycopy(ta.buffer(), 0, resizeBuffer(termLength + len), termLength, len);
217     termLength += len;
218     return this;
219   }
220
221   private CharTermAttribute appendNull() {
222     resizeBuffer(termLength + 4);
223     termBuffer[termLength++] = 'n';
224     termBuffer[termLength++] = 'u';
225     termBuffer[termLength++] = 'l';
226     termBuffer[termLength++] = 'l';
227     return this;
228   }
229   
230   // *** AttributeImpl ***
231
232   @Override
233   public int hashCode() {
234     int code = termLength;
235     code = code * 31 + ArrayUtil.hashCode(termBuffer, 0, termLength);
236     return code;
237   }
238
239   @Override
240   public void clear() {
241     termLength = 0;    
242   }
243
244   @Override
245   public Object clone() {
246     CharTermAttributeImpl t = (CharTermAttributeImpl)super.clone();
247     // Do a deep clone
248     t.termBuffer = new char[this.termLength];
249     System.arraycopy(this.termBuffer, 0, t.termBuffer, 0, this.termLength);
250     return t;
251   }
252   
253   @Override
254   public boolean equals(Object other) {
255     if (other == this) {
256       return true;
257     }
258     
259     if (other instanceof CharTermAttributeImpl) {
260       final CharTermAttributeImpl o = ((CharTermAttributeImpl) other);
261       if (termLength != o.termLength)
262         return false;
263       for(int i=0;i<termLength;i++) {
264         if (termBuffer[i] != o.termBuffer[i]) {
265           return false;
266         }
267       }
268       return true;
269     }
270     
271     return false;
272   }
273
274   /** 
275    * Returns solely the term text as specified by the
276    * {@link CharSequence} interface.
277    * <p>This method changed the behavior with Lucene 3.1,
278    * before it returned a String representation of the whole
279    * term with all attributes.
280    * This affects especially the
281    * {@link org.apache.lucene.analysis.Token} subclass.
282    */
283   @Override
284   public String toString() {
285     // CharSequence requires that only the contents are returned, but this is orginal code: "term=" + new String(termBuffer, 0, termLength)
286     return new String(termBuffer, 0, termLength);
287   }
288   
289   @Override
290   public void reflectWith(AttributeReflector reflector) {
291     reflector.reflect(CharTermAttribute.class, "term", toString());
292   }
293   
294   @Override
295   public void copyTo(AttributeImpl target) {
296     if (target instanceof CharTermAttribute) {
297       CharTermAttribute t = (CharTermAttribute) target;
298       t.copyBuffer(termBuffer, 0, termLength);
299     } else {
300       TermAttribute t = (TermAttribute) target;
301       t.setTermBuffer(termBuffer, 0, termLength);
302     }
303   }
304
305 }