View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.mavibot.btree.util;
21  
22  
23  import java.io.UnsupportedEncodingException;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  
29  /**
30   * Various string manipulation methods that are more efficient then chaining
31   * string operations: all is done in the same buffer without creating a bunch of
32   * string objects.
33   *
34   * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
35   */
36  public final class Strings
37  {
38      /** Hex chars */
39      private static final byte[] HEX_CHAR = new byte[]
40          { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
41  
42      /** A empty byte array */
43      public static final byte[] EMPTY_BYTES = new byte[0];
44  
45  
46      /**
47       * Helper function that dump an array of bytes in hex form
48       *
49       * @param buffer The bytes array to dump
50       * @return A string representation of the array of bytes
51       */
52      public static String dumpBytes( byte[] buffer )
53      {
54          if ( buffer == null )
55          {
56              return "";
57          }
58  
59          StringBuffer sb = new StringBuffer();
60  
61          for ( byte b : buffer )
62          {
63              sb.append( "0x" ).append( ( char ) ( HEX_CHAR[( b & 0x00F0 ) >> 4] ) ).append(
64                  ( char ) ( HEX_CHAR[b & 0x000F] ) ).append( " " );
65          }
66  
67          return sb.toString();
68      }
69  
70  
71      /**
72       * Helper function that dump a byte in hex form
73       *
74       * @param octet The byte to dump
75       * @return A string representation of the byte
76       */
77      public static String dumpByte( byte octet )
78      {
79          return new String( new byte[]
80              { '0', 'x', HEX_CHAR[( octet & 0x00F0 ) >> 4], HEX_CHAR[octet & 0x000F] } );
81      }
82  
83  
84      /**
85       * Helper function that returns a char from an hex
86       *
87       * @param hex The hex to dump
88       * @return A char representation of the hex
89       */
90      public static char dumpHex( byte hex )
91      {
92          return ( char ) HEX_CHAR[hex & 0x000F];
93      }
94  
95  
96      /**
97       * Helper function that dump an array of bytes in hex pair form,
98       * without '0x' and space chars
99       *
100      * @param buffer The bytes array to dump
101      * @return A string representation of the array of bytes
102      */
103     public static String dumpHexPairs( byte[] buffer )
104     {
105         if ( buffer == null )
106         {
107             return "";
108         }
109 
110         char[] str = new char[buffer.length << 1];
111 
112         int pos = 0;
113 
114         for ( byte b : buffer )
115         {
116             str[pos++] = ( char ) ( HEX_CHAR[( b & 0x00F0 ) >> 4] );
117             str[pos++] = ( char ) ( HEX_CHAR[b & 0x000F] );
118         }
119 
120         return new String( str );
121     }
122 
123 
124     /**
125      * Gets a hex string from byte array.
126      *
127      * @param res the byte array
128      * @return the hex string representing the binary values in the array
129      */
130     public static String toHexString( byte[] res )
131     {
132         StringBuffer buf = new StringBuffer( res.length << 1 );
133 
134         for ( byte b : res )
135         {
136             String digit = Integer.toHexString( 0xFF & b );
137 
138             if ( digit.length() == 1 )
139             {
140                 digit = '0' + digit;
141             }
142 
143             buf.append( digit );
144         }
145 
146         return buf.toString().toUpperCase();
147     }
148 
149 
150     /**
151      * Get byte array from hex string
152      *
153      * @param hexString the hex string to convert to a byte array
154      * @return the byte form of the hex string.
155      */
156     public static byte[] toByteArray( String hexString )
157     {
158         int arrLength = hexString.length() >> 1;
159         byte[] buf = new byte[arrLength];
160 
161         for ( int ii = 0; ii < arrLength; ii++ )
162         {
163             int index = ii << 1;
164 
165             String digit = hexString.substring( index, index + 2 );
166             buf[ii] = ( byte ) Integer.parseInt( digit, 16 );
167         }
168 
169         return buf;
170     }
171 
172     private static final byte[] UTF8 = new byte[]
173         { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
174             0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
175             0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
176             0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
177             0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
178             0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64,
179             0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
180             0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F };
181 
182 
183     /**
184      * Return an UTF-8 encoded String
185      *
186      * @param bytes The byte array to be transformed to a String
187      * @return A String.
188      */
189     public static String utf8ToString( byte[] bytes )
190     {
191         if ( bytes == null )
192         {
193             return "";
194         }
195 
196         char[] chars = new char[bytes.length];
197         int pos = 0;
198 
199         try
200         {
201             for ( byte b : bytes )
202             {
203                 chars[pos++] = ( char ) UTF8[b];
204             }
205         }
206         catch ( ArrayIndexOutOfBoundsException aioobe )
207         {
208             try
209             {
210                 return new String( bytes, "UTF-8" );
211             }
212             catch ( UnsupportedEncodingException uee )
213             {
214                 // if this happens something is really strange
215                 throw new RuntimeException( uee );
216             }
217         }
218 
219         return new String( chars );
220     }
221 
222 
223     /**
224      * Return an UTF-8 encoded String
225      *
226      * @param bytes The byte array to be transformed to a String
227      * @param length The length of the byte array to be converted
228      * @return A String.
229      */
230     public static String utf8ToString( byte[] bytes, int length )
231     {
232         if ( bytes == null )
233         {
234             return "";
235         }
236 
237         try
238         {
239             return new String( bytes, 0, length, "UTF-8" );
240         }
241         catch ( UnsupportedEncodingException uee )
242         {
243             // if this happens something is really strange
244             throw new RuntimeException( uee );
245         }
246     }
247 
248 
249     /**
250      * Return an UTF-8 encoded String
251      *
252      * @param bytes  The byte array to be transformed to a String
253      * @param start the starting position in the byte array
254      * @param length The length of the byte array to be converted
255      * @return A String.
256      */
257     public static String utf8ToString( byte[] bytes, int start, int length )
258     {
259         if ( bytes == null )
260         {
261             return "";
262         }
263 
264         try
265         {
266             return new String( bytes, start, length, "UTF-8" );
267         }
268         catch ( UnsupportedEncodingException uee )
269         {
270             // if this happens something is really strange
271             throw new RuntimeException( uee );
272         }
273     }
274 
275 
276     /**
277      * <p>
278      * Checks if a String is empty ("") or null.
279      * </p>
280      *
281      * <pre>
282      *  StringUtils.isEmpty(null)      = true
283      *  StringUtils.isEmpty(&quot;&quot;)        = true
284      *  StringUtils.isEmpty(&quot; &quot;)       = false
285      *  StringUtils.isEmpty(&quot;bob&quot;)     = false
286      *  StringUtils.isEmpty(&quot;  bob  &quot;) = false
287      * </pre>
288      *
289      * <p>
290      * NOTE: This method changed in Lang version 2.0. It no longer trims the
291      * String. That functionality is available in isBlank().
292      * </p>
293      *
294      * @param str the String to check, may be null
295      * @return <code>true</code> if the String is empty or null
296      */
297     public static boolean isEmpty( String str )
298     {
299         return ( str == null ) || ( str.length() == 0 );
300     }
301 
302 
303     /**
304      * Checks if a bytes array is empty or null.
305      *
306      * @param bytes The bytes array to check, may be null
307      * @return <code>true</code> if the bytes array is empty or null
308      */
309     public static boolean isEmpty( byte[] bytes )
310     {
311         return ( bytes == null ) || ( bytes.length == 0 );
312     }
313 
314 
315     /**
316      * Return UTF-8 encoded byte[] representation of a String
317      *
318      * @param string The string to be transformed to a byte array
319      * @return The transformed byte array
320      */
321     public static byte[] getBytesUtf8( String string )
322     {
323         if ( string == null )
324         {
325             return EMPTY_BYTES;
326         }
327 
328         try
329         {
330             return string.getBytes( "UTF-8" );
331         }
332         catch ( UnsupportedEncodingException uee )
333         {
334             // if this happens something is really strange
335             throw new RuntimeException( uee );
336         }
337     }
338 
339 
340     /**
341      * When the string to convert to bytes is pure ascii, this is a faster 
342      * method than the getBytesUtf8. Otherwise, it's slower.
343      * 
344      * @param string The string to convert to byte[]
345      * @return The bytes 
346      */
347     public static byte[] getBytesUtf8Ascii( String string )
348     {
349         if ( string == null )
350         {
351             return new byte[0];
352         }
353 
354         try
355         {
356             try
357             {
358                 char[] chars = string.toCharArray();
359                 byte[] bytes = new byte[chars.length];
360                 int pos = 0;
361 
362                 for ( char c : chars )
363                 {
364                     bytes[pos++] = UTF8[c];
365                 }
366 
367                 return bytes;
368             }
369             catch ( ArrayIndexOutOfBoundsException aioobe )
370             {
371                 return string.getBytes( "UTF-8" );
372             }
373         }
374         catch ( UnsupportedEncodingException uee )
375         {
376             // if this happens something is really strange
377             throw new RuntimeException( uee );
378         }
379     }
380 
381 
382     /**
383      * Utility method that return a String representation of a list
384      *
385      * @param list The list to transform to a string
386      * @return A csv string
387      */
388     public static String listToString( List<?> list )
389     {
390         if ( ( list == null ) || ( list.size() == 0 ) )
391         {
392             return "";
393         }
394 
395         StringBuilder sb = new StringBuilder();
396         boolean isFirst = true;
397 
398         for ( Object elem : list )
399         {
400             if ( isFirst )
401             {
402                 isFirst = false;
403             }
404             else
405             {
406                 sb.append( ", " );
407             }
408 
409             sb.append( elem );
410         }
411 
412         return sb.toString();
413     }
414 
415 
416     /**
417      * Utility method that return a String representation of a set
418      *
419      * @param set The set to transform to a string
420      * @return A csv string
421      */
422     public static String setToString( Set<?> set )
423     {
424         if ( ( set == null ) || ( set.size() == 0 ) )
425         {
426             return "";
427         }
428 
429         StringBuilder sb = new StringBuilder();
430         boolean isFirst = true;
431 
432         for ( Object elem : set )
433         {
434             if ( isFirst )
435             {
436                 isFirst = false;
437             }
438             else
439             {
440                 sb.append( ", " );
441             }
442 
443             sb.append( elem );
444         }
445 
446         return sb.toString();
447     }
448 
449 
450     /**
451      * Utility method that return a String representation of a list
452      *
453      * @param list The list to transform to a string
454      * @param tabs The tabs to add in ffront of the elements
455      * @return A csv string
456      */
457     public static String listToString( List<?> list, String tabs )
458     {
459         if ( ( list == null ) || ( list.size() == 0 ) )
460         {
461             return "";
462         }
463 
464         StringBuffer sb = new StringBuffer();
465 
466         for ( Object elem : list )
467         {
468             sb.append( tabs );
469             sb.append( elem );
470             sb.append( '\n' );
471         }
472 
473         return sb.toString();
474     }
475 
476 
477     /**
478      * Utility method that return a String representation of a map. The elements
479      * will be represented as "key = value"
480      *
481      * @param map The map to transform to a string
482      * @return A csv string
483      */
484     public static String mapToString( Map<?, ?> map )
485     {
486         if ( ( map == null ) || ( map.size() == 0 ) )
487         {
488             return "";
489         }
490 
491         StringBuffer sb = new StringBuffer();
492         boolean isFirst = true;
493 
494         for ( Map.Entry<?, ?> entry : map.entrySet() )
495         {
496             if ( isFirst )
497             {
498                 isFirst = false;
499             }
500             else
501             {
502                 sb.append( ", " );
503             }
504 
505             sb.append( entry.getKey() );
506             sb.append( " = '" ).append( entry.getValue() ).append( "'" );
507         }
508 
509         return sb.toString();
510     }
511 
512 
513     /**
514      * Utility method that return a String representation of a map. The elements
515      * will be represented as "key = value"
516      *
517      * @param map The map to transform to a string
518      * @param tabs The tabs to add in ffront of the elements
519      * @return A csv string
520      */
521     public static String mapToString( Map<?, ?> map, String tabs )
522     {
523         if ( ( map == null ) || ( map.size() == 0 ) )
524         {
525             return "";
526         }
527 
528         StringBuffer sb = new StringBuffer();
529 
530         for ( Map.Entry<?, ?> entry : map.entrySet() )
531         {
532             sb.append( tabs );
533             sb.append( entry.getKey() );
534 
535             sb.append( " = '" ).append( entry.getValue().toString() ).append( "'\n" );
536         }
537 
538         return sb.toString();
539     }
540 }