View Javadoc

1   // ========================================================================
2   // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.util;
15  
16  import java.io.UnsupportedEncodingException;
17  
18  import org.eclipse.jetty.util.log.Log;
19  
20  // ====================================================================
21  /** Fast String Utilities.
22   *
23   * These string utilities provide both conveniance methods and
24   * performance improvements over most standard library versions. The
25   * main aim of the optimizations is to avoid object creation unless
26   * absolutely required.
27   *
28   * 
29   */
30  public class StringUtil
31  {
32      public static final String ALL_INTERFACES="0.0.0.0";
33      public static final String CRLF="\015\012";
34      public static final String __LINE_SEPARATOR=
35          System.getProperty("line.separator","\n");
36         
37      public static final String __ISO_8859_1;
38      static
39      {
40          String iso=System.getProperty("ISO_8859_1");
41          if (iso==null)
42          {
43              try{
44                  new String(new byte[]{(byte)20},"ISO-8859-1");
45                  iso="ISO-8859-1";
46              }
47              catch(java.io.UnsupportedEncodingException e)
48              {
49                  iso="ISO8859_1";
50              }        
51          }
52          __ISO_8859_1=iso;
53      }
54      
55      
56      public final static String __UTF8="UTF-8";
57      public final static String __UTF8Alt="UTF8";
58      public final static String __UTF16="UTF-16";
59      
60      
61      private static char[] lowercases = {
62            '\000','\001','\002','\003','\004','\005','\006','\007',
63            '\010','\011','\012','\013','\014','\015','\016','\017',
64            '\020','\021','\022','\023','\024','\025','\026','\027',
65            '\030','\031','\032','\033','\034','\035','\036','\037',
66            '\040','\041','\042','\043','\044','\045','\046','\047',
67            '\050','\051','\052','\053','\054','\055','\056','\057',
68            '\060','\061','\062','\063','\064','\065','\066','\067',
69            '\070','\071','\072','\073','\074','\075','\076','\077',
70            '\100','\141','\142','\143','\144','\145','\146','\147',
71            '\150','\151','\152','\153','\154','\155','\156','\157',
72            '\160','\161','\162','\163','\164','\165','\166','\167',
73            '\170','\171','\172','\133','\134','\135','\136','\137',
74            '\140','\141','\142','\143','\144','\145','\146','\147',
75            '\150','\151','\152','\153','\154','\155','\156','\157',
76            '\160','\161','\162','\163','\164','\165','\166','\167',
77            '\170','\171','\172','\173','\174','\175','\176','\177' };
78  
79      /* ------------------------------------------------------------ */
80      /**
81       * fast lower case conversion. Only works on ascii (not unicode)
82       * @param s the string to convert
83       * @return a lower case version of s
84       */
85      public static String asciiToLowerCase(String s)
86      {
87          char[] c = null;
88          int i=s.length();
89  
90          // look for first conversion
91          while (i-->0)
92          {
93              char c1=s.charAt(i);
94              if (c1<=127)
95              {
96                  char c2=lowercases[c1];
97                  if (c1!=c2)
98                  {
99                      c=s.toCharArray();
100                     c[i]=c2;
101                     break;
102                 }
103             }
104         }
105 
106         while (i-->0)
107         {
108             if(c[i]<=127)
109                 c[i] = lowercases[c[i]];
110         }
111         
112         return c==null?s:new String(c);
113     }
114 
115 
116     /* ------------------------------------------------------------ */
117     public static boolean startsWithIgnoreCase(String s,String w)
118     {
119         if (w==null)
120             return true;
121         
122         if (s==null || s.length()<w.length())
123             return false;
124         
125         for (int i=0;i<w.length();i++)
126         {
127             char c1=s.charAt(i);
128             char c2=w.charAt(i);
129             if (c1!=c2)
130             {
131                 if (c1<=127)
132                     c1=lowercases[c1];
133                 if (c2<=127)
134                     c2=lowercases[c2];
135                 if (c1!=c2)
136                     return false;
137             }
138         }
139         return true;
140     }
141     
142     /* ------------------------------------------------------------ */
143     public static boolean endsWithIgnoreCase(String s,String w)
144     {
145         if (w==null)
146             return true;
147 
148         if (s==null)
149             return false;
150             
151         int sl=s.length();
152         int wl=w.length();
153         
154         if (sl<wl)
155             return false;
156         
157         for (int i=wl;i-->0;)
158         {
159             char c1=s.charAt(--sl);
160             char c2=w.charAt(i);
161             if (c1!=c2)
162             {
163                 if (c1<=127)
164                     c1=lowercases[c1];
165                 if (c2<=127)
166                     c2=lowercases[c2];
167                 if (c1!=c2)
168                     return false;
169             }
170         }
171         return true;
172     }
173     
174     /* ------------------------------------------------------------ */
175     /**
176      * returns the next index of a character from the chars string
177      */
178     public static int indexFrom(String s,String chars)
179     {
180         for (int i=0;i<s.length();i++)
181            if (chars.indexOf(s.charAt(i))>=0)
182               return i;
183         return -1;
184     }
185     
186     /* ------------------------------------------------------------ */
187     /**
188      * replace substrings within string.
189      */
190     public static String replace(String s, String sub, String with)
191     {
192         int c=0;
193         int i=s.indexOf(sub,c);
194         if (i == -1)
195             return s;
196     
197         StringBuilder buf = new StringBuilder(s.length()+with.length());
198 
199         do
200         {
201             buf.append(s.substring(c,i));
202             buf.append(with);
203             c=i+sub.length();
204         } while ((i=s.indexOf(sub,c))!=-1);
205 
206         if (c<s.length())
207             buf.append(s.substring(c,s.length()));
208 
209         return buf.toString();
210         
211     }
212 
213 
214     /* ------------------------------------------------------------ */
215     /** Remove single or double quotes.
216      */
217     public static String unquote(String s)
218     {
219         return QuotedStringTokenizer.unquote(s);
220     }
221 
222 
223     /* ------------------------------------------------------------ */
224     /** Append substring to StringBuilder 
225      * @param buf StringBuilder to append to
226      * @param s String to append from
227      * @param offset The offset of the substring
228      * @param length The length of the substring
229      */
230     public static void append(StringBuilder buf,
231                               String s,
232                               int offset,
233                               int length)
234     {
235         synchronized(buf)
236         {
237             int end=offset+length;
238             for (int i=offset; i<end;i++)
239             {
240                 if (i>=s.length())
241                     break;
242                 buf.append(s.charAt(i));
243             }
244         }
245     }
246 
247     
248     /* ------------------------------------------------------------ */
249     /**
250      * append hex digit
251      * 
252      */
253     public static void append(StringBuilder buf,byte b,int base)
254     {
255         int bi=0xff&b;
256         int c='0'+(bi/base)%base;
257         if (c>'9')
258             c= 'a'+(c-'0'-10);
259         buf.append((char)c);
260         c='0'+bi%base;
261         if (c>'9')
262             c= 'a'+(c-'0'-10);
263         buf.append((char)c);
264     }
265 
266     /* ------------------------------------------------------------ */
267     public static void append2digits(StringBuffer buf,int i)
268     {
269         if (i<100)
270         {
271             buf.append((char)(i/10+'0'));
272             buf.append((char)(i%10+'0'));
273         }
274     }
275     
276     /* ------------------------------------------------------------ */
277     public static void append2digits(StringBuilder buf,int i)
278     {
279         if (i<100)
280         {
281             buf.append((char)(i/10+'0'));
282             buf.append((char)(i%10+'0'));
283         }
284     }
285     
286     /* ------------------------------------------------------------ */
287     /** Return a non null string.
288      * @param s String
289      * @return The string passed in or empty string if it is null. 
290      */
291     public static String nonNull(String s)
292     {
293         if (s==null)
294             return "";
295         return s;
296     }
297     
298     /* ------------------------------------------------------------ */
299     public static boolean equals(String s,char[] buf, int offset, int length)
300     {
301         if (s.length()!=length)
302             return false;
303         for (int i=0;i<length;i++)
304             if (buf[offset+i]!=s.charAt(i))
305                 return false;
306         return true;
307     }
308 
309     /* ------------------------------------------------------------ */
310     public static String toUTF8String(byte[] b,int offset,int length)
311     {
312         try
313         {
314             return new String(b,offset,length,__UTF8);
315         }
316         catch (UnsupportedEncodingException e)
317         {
318             throw new IllegalArgumentException(e);
319         }
320     }
321 
322     /* ------------------------------------------------------------ */
323     public static String toString(byte[] b,int offset,int length,String charset)
324     {
325         try
326         {
327             return new String(b,offset,length,charset);
328         }
329         catch (UnsupportedEncodingException e)
330         {
331             throw new IllegalArgumentException(e);
332         }
333     }
334 
335 
336     /* ------------------------------------------------------------ */
337     public static boolean isUTF8(String charset)
338     {
339         return charset==__UTF8||__UTF8.equalsIgnoreCase(charset)||__UTF8Alt.equalsIgnoreCase(charset);
340     }
341 
342 
343     /* ------------------------------------------------------------ */
344     public static String printable(String name)
345     {
346         if (name==null)
347             return null;
348         StringBuilder buf = new StringBuilder(name.length());
349         for (int i=0;i<name.length();i++)
350         {
351             char c=name.charAt(i);
352             if (!Character.isISOControl(c))
353                 buf.append(c);
354         }
355         return buf.toString();
356     }
357     
358     public static byte[] getBytes(String s)
359     {
360         try
361         {
362             return s.getBytes(__ISO_8859_1);
363         }
364         catch(Exception e)
365         {
366             Log.warn(e);
367             return s.getBytes();
368         }
369     }
370     
371     public static byte[] getBytes(String s,String charset)
372     {
373         try
374         {
375             return s.getBytes(charset);
376         }
377         catch(Exception e)
378         {
379             Log.warn(e);
380             return s.getBytes();
381         }
382     }
383 }