1 package org.apache.maven.surefire.util.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.UnsupportedEncodingException;
23 import java.nio.ByteBuffer;
24 import java.nio.CharBuffer;
25 import java.nio.charset.CharacterCodingException;
26 import java.nio.charset.Charset;
27 import java.util.StringTokenizer;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public final class StringUtils
59 {
60 public static final String NL = System.getProperty( "line.separator" );
61
62 private static final byte[] HEX_CHARS = {
63 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
64
65 private static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
66
67
68 public static final String FORK_STREAM_CHARSET_NAME = "ISO-8859-1";
69
70 private StringUtils()
71 {
72 throw new IllegalStateException( "no instantiable constructor" );
73 }
74
75 public static String[] split( String text, String separator )
76 {
77 int max = -1;
78 StringTokenizer tok;
79 if ( separator == null )
80 {
81
82
83 tok = new StringTokenizer( text );
84 }
85 else
86 {
87 tok = new StringTokenizer( text, separator );
88 }
89
90 int listSize = tok.countTokens();
91 if ( max > 0 && listSize > max )
92 {
93 listSize = max;
94 }
95
96 String[] list = new String[listSize];
97 int i = 0;
98 int lastTokenBegin;
99 int lastTokenEnd = 0;
100 while ( tok.hasMoreTokens() )
101 {
102 if ( max > 0 && i == listSize - 1 )
103 {
104
105
106
107 String endToken = tok.nextToken();
108 lastTokenBegin = text.indexOf( endToken, lastTokenEnd );
109 list[i] = text.substring( lastTokenBegin );
110 break;
111 }
112 else
113 {
114 list[i] = tok.nextToken();
115 lastTokenBegin = text.indexOf( list[i], lastTokenEnd );
116 lastTokenEnd = lastTokenBegin + list[i].length();
117 }
118 i++;
119 }
120 return list;
121 }
122
123
124
125
126
127
128
129
130
131 public static boolean isBlank( String str )
132 {
133 return str == null || str.trim().length() == 0;
134 }
135
136
137
138
139
140
141
142
143
144
145 public static boolean isNotBlank( String str )
146 {
147 return !isBlank( str );
148 }
149
150
151
152
153
154
155
156
157
158
159 @SuppressWarnings( "checkstyle:magicnumber" )
160 public static void escapeToPrintable( StringBuilder target, CharSequence str )
161 {
162 if ( target == null )
163 {
164 throw new IllegalArgumentException( "The target buffer must not be null" );
165 }
166 if ( str == null )
167 {
168 return;
169 }
170
171 for ( int i = 0; i < str.length(); i++ )
172 {
173 char c = str.charAt( i );
174
175
176 if ( c < 32 || c > 126 || c == '\\' || c == ',' )
177 {
178 target.append( '\\' );
179 target.append( (char) HEX_CHARS[( 0xF000 & c ) >> 12] );
180 target.append( (char) HEX_CHARS[( 0x0F00 & c ) >> 8] );
181 target.append( (char) HEX_CHARS[( 0x00F0 & c ) >> 4] );
182 target.append( (char) HEX_CHARS[( 0x000F & c )] );
183 }
184 else
185 {
186 target.append( c );
187 }
188 }
189 }
190
191
192
193
194
195
196
197 public static void unescapeString( StringBuilder target, CharSequence str )
198 {
199 if ( target == null )
200 {
201 throw new IllegalArgumentException( "The target buffer must not be null" );
202 }
203 if ( str == null )
204 {
205 return;
206 }
207
208 for ( int i = 0; i < str.length(); i++ )
209 {
210 char ch = str.charAt( i );
211
212 if ( ch == '\\' )
213 {
214 target.append( (char) (
215 digit( str.charAt( ++i ) ) << 12
216 | digit( str.charAt( ++i ) ) << 8
217 | digit( str.charAt( ++i ) ) << 4
218 | digit( str.charAt( ++i ) )
219 ) );
220 }
221 else
222 {
223 target.append( ch );
224 }
225 }
226 }
227
228 private static int digit( char ch )
229 {
230 if ( ch >= 'a' )
231 {
232 return 10 + ch - 'a';
233 }
234 else if ( ch >= 'A' )
235 {
236 return 10 + ch - 'A';
237 }
238 else
239 {
240 return ch - '0';
241 }
242 }
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 @SuppressWarnings( "checkstyle:magicnumber" )
261 public static int escapeBytesToPrintable( byte[] out, int outoff, byte[] input, int off, int len )
262 {
263 if ( out == null )
264 {
265 throw new IllegalArgumentException( "The output array must not be null" );
266 }
267 if ( input == null || input.length == 0 )
268 {
269 return 0;
270 }
271 int outputPos = outoff;
272 int end = off + len;
273 for ( int i = off; i < end; i++ )
274 {
275 byte b = input[i];
276
277
278 if ( b < 32 || b > 126 || b == '\\' || b == ',' )
279 {
280 int upper = ( 0xF0 & b ) >> 4;
281 int lower = ( 0x0F & b );
282 out[outputPos++] = '\\';
283 out[outputPos++] = HEX_CHARS[upper];
284 out[outputPos++] = HEX_CHARS[lower];
285 }
286 else
287 {
288 out[outputPos++] = b;
289 }
290 }
291
292 return outputPos - outoff;
293 }
294
295
296
297
298
299
300
301
302 public static ByteBuffer unescapeBytes( String str, String charsetName )
303 {
304 int outPos = 0;
305
306 if ( str == null )
307 {
308 return ByteBuffer.wrap( new byte[0] );
309 }
310
311 byte[] out = new byte[str.length()];
312 for ( int i = 0; i < str.length(); i++ )
313 {
314 char ch = str.charAt( i );
315
316 if ( ch == '\\' )
317 {
318 int upper = digit( str.charAt( ++i ) );
319 int lower = digit( str.charAt( ++i ) );
320 out[outPos++] = (byte) ( upper << 4 | lower );
321 }
322 else
323 {
324 out[outPos++] = (byte) ch;
325 }
326 }
327
328 Charset sourceCharset = Charset.forName( charsetName );
329 if ( !DEFAULT_CHARSET.equals( sourceCharset ) )
330 {
331 CharBuffer decodedFromSourceCharset;
332 try
333 {
334 decodedFromSourceCharset = sourceCharset.newDecoder().decode( ByteBuffer.wrap( out, 0, outPos ) );
335 ByteBuffer defaultEncoded = DEFAULT_CHARSET.encode( decodedFromSourceCharset );
336
337 return defaultEncoded;
338 }
339 catch ( CharacterCodingException e )
340 {
341
342 }
343 }
344
345 return ByteBuffer.wrap( out, 0, outPos );
346 }
347
348 public static byte[] encodeStringForForkCommunication( String string )
349 {
350 try
351 {
352 return string.getBytes( FORK_STREAM_CHARSET_NAME );
353 }
354 catch ( UnsupportedEncodingException e )
355 {
356 throw new RuntimeException( "The JVM must support Charset " + FORK_STREAM_CHARSET_NAME, e );
357 }
358 }
359
360
361
362
363
364
365
366 public static boolean startsWith( StringBuffer buffer, String pattern )
367 {
368 if ( buffer.length() < pattern.length() )
369 {
370 return false;
371 }
372 else
373 {
374 for ( int i = 0, len = pattern.length(); i < len; i++ )
375 {
376 if ( buffer.charAt( i ) != pattern.charAt( i ) )
377 {
378 return false;
379 }
380 }
381 return true;
382 }
383 }
384 }