EMMA Coverage Report (generated Tue Jul 25 08:38:09 UTC 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [StringUtils.java]

nameclass, %method, %block, %line, %
StringUtils.java100% (1/1)88%  (28/32)69%  (1479/2141)70%  (343.4/488)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StringUtils100% (1/1)88%  (28/32)69%  (1479/2141)70%  (343.4/488)
StringUtils (): void 0%   (0/1)0%   (0/3)0%   (0/1)
getBytes (String, SingleByteCharsetConverter, String, String, int, int, boole... 0%   (0/1)0%   (0/97)0%   (0/18)
getBytes (char [], SingleByteCharsetConverter, String, String, boolean): byte [] 0%   (0/1)0%   (0/70)0%   (0/13)
getBytes (char [], String, String, boolean, Connection): byte [] 0%   (0/1)0%   (0/36)0%   (0/7)
wildCompare (String, String): int 100% (1/1)5%   (10/209)5%   (3/55)
getBytes (char [], SingleByteCharsetConverter, String, String, int, int, bool... 100% (1/1)33%  (33/99)51%  (9.7/19)
getBytes (String, String, String, boolean, Connection): byte [] 100% (1/1)56%  (20/36)71%  (5/7)
getBytes (String, SingleByteCharsetConverter, String, String, boolean): byte [] 100% (1/1)60%  (37/62)67%  (8/12)
consistentToString (BigDecimal): String 100% (1/1)72%  (13/18)50%  (4/8)
getLong (byte []): long 100% (1/1)78%  (125/160)79%  (28.6/36)
startsWithIgnoreCaseAndWs (String, String): boolean 100% (1/1)81%  (25/31)88%  (7/8)
split (String, String, boolean): List 100% (1/1)81%  (35/43)83%  (10/12)
startsWithIgnoreCaseAndNonAlphaNumeric (String, String): boolean 100% (1/1)82%  (27/33)89%  (8/9)
getInt (byte []): int 100% (1/1)84%  (123/147)85%  (30.6/36)
firstNonWsCharUc (String): char 100% (1/1)85%  (22/26)75%  (6/8)
getShort (byte []): short 100% (1/1)85%  (132/156)85%  (30.6/36)
indexOfIgnoreCaseRespectMarker (int, String, String, String, String, boolean)... 100% (1/1)87%  (69/79)93%  (16.7/18)
split (String, String, String, String, boolean): List 100% (1/1)88%  (61/69)89%  (17/19)
indexOfIgnoreCaseRespectQuotes (int, String, String, char, boolean): int 100% (1/1)89%  (59/66)93%  (14/15)
endsWith (byte [], String): boolean 100% (1/1)93%  (27/29)83%  (5/6)
indexOfIgnoreCase (int, String, String): int 100% (1/1)94%  (98/104)86%  (23.3/27)
escapeEasternUnicodeByteStream (byte [], String, int, int): byte [] 100% (1/1)97%  (111/115)97%  (34/35)
<static initializer> 100% (1/1)98%  (61/62)99%  (12.9/13)
dumpAsHex (byte [], int): String 100% (1/1)100% (208/208)100% (34/34)
fixDecimalExponent (String): String 100% (1/1)100% (68/68)100% (13/13)
indexOfIgnoreCase (String, String): int 100% (1/1)100% (5/5)100% (1/1)
startsWith (byte [], String): boolean 100% (1/1)100% (19/19)100% (4/4)
startsWithIgnoreCase (String, String): boolean 100% (1/1)100% (5/5)100% (1/1)
startsWithIgnoreCase (String, int, String): boolean 100% (1/1)100% (9/9)100% (1/1)
stripEnclosure (byte [], String, String): byte [] 100% (1/1)100% (46/46)100% (9/9)
toAsciiString (byte []): String 100% (1/1)100% (6/6)100% (1/1)
toAsciiString (byte [], int, int): String 100% (1/1)100% (25/25)100% (6/6)

1/*
2 Copyright (C) 2002-2004 MySQL AB
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of version 2 of the GNU General Public License as 
6 published by the Free Software Foundation.
7 
8 There are special exceptions to the terms and conditions of the GPL 
9 as it is applied to this software. View the full text of the 
10 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
11 software distribution.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22 
23 
24 */
25package com.mysql.jdbc;
26 
27import java.io.ByteArrayOutputStream;
28import java.io.UnsupportedEncodingException;
29import java.lang.reflect.InvocationTargetException;
30import java.lang.reflect.Method;
31import java.math.BigDecimal;
32 
33import java.sql.SQLException;
34 
35import java.util.ArrayList;
36import java.util.List;
37import java.util.StringTokenizer;
38 
39/**
40 * Various utility methods for converting to/from byte arrays in the platform
41 * encoding
42 * 
43 * @author Mark Matthews
44 */
45public class StringUtils {
46        
47        private static final int BYTE_RANGE = (1 + Byte.MAX_VALUE) - Byte.MIN_VALUE;
48 
49        private static byte[] allBytes = new byte[BYTE_RANGE];
50 
51        private static char[] byteToChars = new char[BYTE_RANGE];
52 
53        private static Method toPlainStringMethod;
54 
55        static final int WILD_COMPARE_MATCH_NO_WILD = 0;
56 
57        static final int WILD_COMPARE_MATCH_WITH_WILD = 1;
58 
59        static final int WILD_COMPARE_NO_MATCH = -1;
60 
61        static {
62                for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
63                        allBytes[i - Byte.MIN_VALUE] = (byte) i;
64                }
65 
66                String allBytesString = new String(allBytes, 0, Byte.MAX_VALUE
67                                - Byte.MIN_VALUE);
68 
69                int allBytesStringLen = allBytesString.length();
70 
71                for (int i = 0; (i < (Byte.MAX_VALUE - Byte.MIN_VALUE))
72                                && (i < allBytesStringLen); i++) {
73                        byteToChars[i] = allBytesString.charAt(i);
74                }
75 
76                try {
77                        toPlainStringMethod = BigDecimal.class.getMethod("toPlainString",
78                                        new Class[0]);
79                } catch (NoSuchMethodException nsme) {
80                        // that's okay, we fallback to .toString()
81                }
82        }
83 
84        /**
85         * Takes care of the fact that Sun changed the output of
86         * BigDecimal.toString() between JDK-1.4 and JDK 5
87         * 
88         * @param decimal
89         *            the big decimal to stringify
90         * 
91         * @return a string representation of 'decimal'
92         */
93        public static String consistentToString(BigDecimal decimal) {
94                if (decimal == null) {
95                        return null;
96                }
97 
98                if (toPlainStringMethod != null) {
99                        try {
100                                return (String) toPlainStringMethod.invoke(decimal, null);
101                        } catch (InvocationTargetException invokeEx) {
102                                // that's okay, we fall-through to decimal.toString()
103                        } catch (IllegalAccessException accessEx) {
104                                // that's okay, we fall-through to decimal.toString()
105                        }
106                }
107 
108                return decimal.toString();
109        }
110 
111        /**
112         * Dumps the given bytes to STDOUT as a hex dump (up to length bytes).
113         * 
114         * @param byteBuffer
115         *            the data to print as hex
116         * @param length
117         *            the number of bytes to print
118         * 
119         * @return ...
120         */
121        public static final String dumpAsHex(byte[] byteBuffer, int length) {
122                StringBuffer outputBuf = new StringBuffer(length * 4);
123 
124                int p = 0;
125                int rows = length / 8;
126 
127                for (int i = 0; (i < rows) && (p < length); i++) {
128                        int ptemp = p;
129 
130                        for (int j = 0; j < 8; j++) {
131                                String hexVal = Integer.toHexString(byteBuffer[ptemp] & 0xff);
132 
133                                if (hexVal.length() == 1) {
134                                        hexVal = "0" + hexVal; //$NON-NLS-1$
135                                }
136 
137                                outputBuf.append(hexVal + " "); //$NON-NLS-1$
138                                ptemp++;
139                        }
140 
141                        outputBuf.append("    "); //$NON-NLS-1$
142 
143                        for (int j = 0; j < 8; j++) {
144                                if ((byteBuffer[p] > 32) && (byteBuffer[p] < 127)) {
145                                        outputBuf.append((char) byteBuffer[p] + " "); //$NON-NLS-1$
146                                } else {
147                                        outputBuf.append(". "); //$NON-NLS-1$
148                                }
149 
150                                p++;
151                        }
152 
153                        outputBuf.append("\n"); //$NON-NLS-1$
154                }
155 
156                int n = 0;
157 
158                for (int i = p; i < length; i++) {
159                        String hexVal = Integer.toHexString(byteBuffer[i] & 0xff);
160 
161                        if (hexVal.length() == 1) {
162                                hexVal = "0" + hexVal; //$NON-NLS-1$
163                        }
164 
165                        outputBuf.append(hexVal + " "); //$NON-NLS-1$
166                        n++;
167                }
168 
169                for (int i = n; i < 8; i++) {
170                        outputBuf.append("   "); //$NON-NLS-1$
171                }
172 
173                outputBuf.append("    "); //$NON-NLS-1$
174 
175                for (int i = p; i < length; i++) {
176                        if ((byteBuffer[i] > 32) && (byteBuffer[i] < 127)) {
177                                outputBuf.append((char) byteBuffer[i] + " "); //$NON-NLS-1$
178                        } else {
179                                outputBuf.append(". "); //$NON-NLS-1$
180                        }
181                }
182 
183                outputBuf.append("\n"); //$NON-NLS-1$
184 
185                return outputBuf.toString();
186        }
187 
188        private static boolean endsWith(byte[] dataFrom, String suffix) {
189                for (int i = 1; i <= suffix.length(); i++) {
190                        int dfOffset = dataFrom.length - i;
191                        int suffixOffset = suffix.length() - i;
192                        if (dataFrom[dfOffset] != suffix.charAt(suffixOffset)) {
193                                return false;
194                        }
195                }
196                return true;
197        }
198 
199        /**
200         * Unfortunately, SJIS has 0x5c as a high byte in some of its double-byte
201         * characters, so we need to escape it.
202         * 
203         * @param origBytes
204         *            the original bytes in SJIS format
205         * @param origString
206         *            the string that had .getBytes() called on it
207         * @param offset
208         *            where to start converting from
209         * @param length
210         *            how many characters to convert.
211         * 
212         * @return byte[] with 0x5c escaped
213         */
214        public static byte[] escapeEasternUnicodeByteStream(byte[] origBytes,
215                        String origString, int offset, int length) {
216                if ((origBytes == null) || (origBytes.length == 0)) {
217                        return origBytes;
218                }
219 
220                int bytesLen = origBytes.length;
221                int bufIndex = 0;
222                int strIndex = 0;
223 
224                ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(bytesLen);
225 
226                while (true) {
227                        if (origString.charAt(strIndex) == '\\') {
228                                // write it out as-is
229                                bytesOut.write(origBytes[bufIndex++]);
230 
231                                // bytesOut.write(origBytes[bufIndex++]);
232                        } else {
233                                // Grab the first byte
234                                int loByte = origBytes[bufIndex];
235 
236                                if (loByte < 0) {
237                                        loByte += 256; // adjust for signedness/wrap-around
238                                }
239 
240                                // We always write the first byte
241                                bytesOut.write(loByte);
242 
243                                //
244                                // The codepage characters in question exist between
245                                // 0x81-0x9F and 0xE0-0xFC...
246                                //
247                                // See:
248                                //
249                                // http://www.microsoft.com/GLOBALDEV/Reference/dbcs/932.htm
250                                //
251                                // Problematic characters in GBK
252                                //
253                                // U+905C : CJK UNIFIED IDEOGRAPH
254                                //
255                                // Problematic characters in Big5
256                                //
257                                // B9F0 = U+5C62 : CJK UNIFIED IDEOGRAPH
258                                //
259                                if (loByte >= 0x80) {
260                                        if (bufIndex < (bytesLen - 1)) {
261                                                int hiByte = origBytes[bufIndex + 1];
262 
263                                                if (hiByte < 0) {
264                                                        hiByte += 256; // adjust for signedness/wrap-around
265                                                }
266 
267                                                // write the high byte here, and increment the index
268                                                // for the high byte
269                                                bytesOut.write(hiByte);
270                                                bufIndex++;
271 
272                                                // escape 0x5c if necessary
273                                                if (hiByte == 0x5C) {
274                                                        bytesOut.write(hiByte);
275                                                }
276                                        }
277                                } else if (loByte == 0x5c) {
278                                        if (bufIndex < (bytesLen - 1)) {
279                                                int hiByte = origBytes[bufIndex + 1];
280 
281                                                if (hiByte < 0) {
282                                                        hiByte += 256; // adjust for signedness/wrap-around
283                                                }
284 
285                                                if (hiByte == 0x62) {
286                                                        // we need to escape the 0x5c
287                                                        bytesOut.write(0x5c);
288                                                        bytesOut.write(0x62);
289                                                        bufIndex++;
290                                                }
291                                        }
292                                }
293 
294                                bufIndex++;
295                        }
296 
297                        if (bufIndex >= bytesLen) {
298                                // we're done
299                                break;
300                        }
301 
302                        strIndex++;
303                }
304 
305                return bytesOut.toByteArray();
306        }
307 
308        /**
309         * Returns the first non whitespace char, converted to upper case
310         * 
311         * @param searchIn
312         *            the string to search in
313         * 
314         * @return the first non-whitespace character, upper cased.
315         */
316        public static char firstNonWsCharUc(String searchIn) {
317                if (searchIn == null) {
318                        return 0;
319                }
320 
321                int length = searchIn.length();
322 
323                for (int i = 0; i < length; i++) {
324                        char c = searchIn.charAt(i);
325 
326                        if (!Character.isWhitespace(c)) {
327                                return Character.toUpperCase(c);
328                        }
329                }
330 
331                return 0;
332        }
333 
334        /**
335         * Adds '+' to decimal numbers that are positive (MySQL doesn't understand
336         * them otherwise
337         * 
338         * @param dString
339         *            The value as a string
340         * 
341         * @return String the string with a '+' added (if needed)
342         */
343        public static final String fixDecimalExponent(String dString) {
344                int ePos = dString.indexOf("E"); //$NON-NLS-1$
345 
346                if (ePos == -1) {
347                        ePos = dString.indexOf("e"); //$NON-NLS-1$
348                }
349 
350                if (ePos != -1) {
351                        if (dString.length() > (ePos + 1)) {
352                                char maybeMinusChar = dString.charAt(ePos + 1);
353 
354                                if (maybeMinusChar != '-' && maybeMinusChar != '+') {
355                                        StringBuffer buf = new StringBuffer(dString.length() + 1);
356                                        buf.append(dString.substring(0, ePos + 1));
357                                        buf.append('+');
358                                        buf.append(dString.substring(ePos + 1, dString.length()));
359                                        dString = buf.toString();
360                                }
361                        }
362                }
363 
364                return dString;
365        }
366 
367        public static final byte[] getBytes(char[] c,
368                        SingleByteCharsetConverter converter, String encoding,
369                        String serverEncoding, boolean parserKnowsUnicode)
370                        throws SQLException {
371                try {
372                        byte[] b = null;
373 
374                        if (converter != null) {
375                                b = converter.toBytes(c);
376                        } else if (encoding == null) {
377                                b = new String(c).getBytes();
378                        } else {
379                                String s = new String(c);
380 
381                                b = s.getBytes(encoding);
382 
383                                if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
384                                                || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
385                                || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
386 
387                                        if (!encoding.equalsIgnoreCase(serverEncoding)) {
388                                                b = escapeEasternUnicodeByteStream(b, s, 0, s.length());
389                                        }
390                                }
391                        }
392 
393                        return b;
394                } catch (UnsupportedEncodingException uee) {
395                        throw SQLError.createSQLException(Messages.getString("StringUtils.5") //$NON-NLS-1$
396                                        + encoding + Messages.getString("StringUtils.6"),
397                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
398                }
399        }
400 
401        public static final byte[] getBytes(char[] c,
402                        SingleByteCharsetConverter converter, String encoding,
403                        String serverEncoding, int offset, int length,
404                        boolean parserKnowsUnicode) throws SQLException {
405                try {
406                        byte[] b = null;
407 
408                        if (converter != null) {
409                                b = converter.toBytes(c, offset, length);
410                        } else if (encoding == null) {
411                                byte[] temp = new String(c, offset, length).getBytes();
412 
413                                length = temp.length;
414                                
415                                b = new byte[length];
416                                System.arraycopy(temp, 0, b, 0, length);
417                        } else {
418                                String s = new String(c, offset, length);
419 
420                                byte[] temp = s.getBytes(encoding);
421 
422                                length = temp.length;
423                                
424                                b = new byte[length];
425                                System.arraycopy(temp, 0, b, 0, length);
426 
427                                if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
428                                                || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
429                                || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
430 
431                                        if (!encoding.equalsIgnoreCase(serverEncoding)) {
432                                                b = escapeEasternUnicodeByteStream(b, s, offset, length);
433                                        }
434                                }
435                        }
436 
437                        return b;
438                } catch (UnsupportedEncodingException uee) {
439                        throw SQLError.createSQLException(Messages.getString("StringUtils.10") //$NON-NLS-1$
440                                        + encoding + Messages.getString("StringUtils.11"),
441                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
442                }
443        }
444 
445        public static final byte[] getBytes(char[] c, String encoding,
446                        String serverEncoding, boolean parserKnowsUnicode, Connection conn)
447                        throws SQLException {
448                try {
449                        
450                        SingleByteCharsetConverter converter = null;
451                        
452                        if (conn != null) {
453                                converter = conn.getCharsetConverter(encoding);
454                        } else {
455                                converter = SingleByteCharsetConverter.getInstance(encoding, null);
456                        }
457 
458                        return getBytes(c, converter, encoding, serverEncoding,
459                                        parserKnowsUnicode);
460                } catch (UnsupportedEncodingException uee) {
461                        throw SQLError.createSQLException(Messages.getString("StringUtils.0") //$NON-NLS-1$
462                                        + encoding + Messages.getString("StringUtils.1"),
463                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
464                }
465        }
466 
467        /**
468         * Returns the byte[] representation of the given string (re)using the given
469         * charset converter, and the given encoding.
470         * 
471         * @param s
472         *            the string to convert
473         * @param converter
474         *            the converter to reuse
475         * @param encoding
476         *            the character encoding to use
477         * @param serverEncoding
478         *            DOCUMENT ME!
479         * @param parserKnowsUnicode
480         *            DOCUMENT ME!
481         * 
482         * @return byte[] representation of the string
483         * 
484         * @throws SQLException
485         *             if an encoding unsupported by the JVM is supplied.
486         */
487        public static final byte[] getBytes(String s,
488                        SingleByteCharsetConverter converter, String encoding,
489                        String serverEncoding, boolean parserKnowsUnicode)
490                        throws SQLException {
491                try {
492                        byte[] b = null;
493 
494                        if (converter != null) {
495                                b = converter.toBytes(s);
496                        } else if (encoding == null) {
497                                b = s.getBytes();
498                        } else {
499                                b = s.getBytes(encoding);
500 
501                                if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
502                                                || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
503                                || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
504 
505                                        if (!encoding.equalsIgnoreCase(serverEncoding)) {
506                                                b = escapeEasternUnicodeByteStream(b, s, 0, s.length());
507                                        }
508                                }
509                        }
510 
511                        return b;
512                } catch (UnsupportedEncodingException uee) {
513                        throw SQLError.createSQLException(Messages.getString("StringUtils.5") //$NON-NLS-1$
514                                        + encoding + Messages.getString("StringUtils.6"),
515                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
516                }
517        }
518 
519        /**
520         * DOCUMENT ME!
521         * 
522         * @param s
523         *            DOCUMENT ME!
524         * @param converter
525         *            DOCUMENT ME!
526         * @param encoding
527         *            DOCUMENT ME!
528         * @param serverEncoding
529         *            DOCUMENT ME!
530         * @param offset
531         *            DOCUMENT ME!
532         * @param length
533         *            DOCUMENT ME!
534         * @param parserKnowsUnicode
535         *            DOCUMENT ME!
536         * 
537         * @return DOCUMENT ME!
538         * 
539         * @throws SQLException
540         *             DOCUMENT ME!
541         */
542        public static final byte[] getBytes(String s,
543                        SingleByteCharsetConverter converter, String encoding,
544                        String serverEncoding, int offset, int length,
545                        boolean parserKnowsUnicode) throws SQLException {
546                try {
547                        byte[] b = null;
548 
549                        if (converter != null) {
550                                b = converter.toBytes(s, offset, length);
551                        } else if (encoding == null) {
552                                byte[] temp = s.substring(offset, offset + length).getBytes();
553 
554                                length = temp.length;
555                                
556                                b = new byte[length];
557                                System.arraycopy(temp, 0, b, 0, length);
558                        } else {
559 
560                                byte[] temp = s.substring(offset, offset + length)
561                                        .getBytes(encoding);
562 
563                                length = temp.length;
564                                
565                                b = new byte[length];
566                                System.arraycopy(temp, 0, b, 0, length);
567 
568                                if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
569                                                || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
570                                || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
571 
572                                        if (!encoding.equalsIgnoreCase(serverEncoding)) {
573                                                b = escapeEasternUnicodeByteStream(b, s, offset, length);
574                                        }
575                                }
576                        }
577 
578                        return b;
579                } catch (UnsupportedEncodingException uee) {
580                        throw SQLError.createSQLException(Messages.getString("StringUtils.10") //$NON-NLS-1$
581                                        + encoding + Messages.getString("StringUtils.11"),
582                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
583                }
584        }
585 
586        /**
587         * Returns the byte[] representation of the given string using given
588         * encoding.
589         * 
590         * @param s
591         *            the string to convert
592         * @param encoding
593         *            the character encoding to use
594         * @param parserKnowsUnicode
595         *            DOCUMENT ME!
596         * 
597         * @return byte[] representation of the string
598         * 
599         * @throws SQLException
600         *             if an encoding unsupported by the JVM is supplied.
601         */
602        public static final byte[] getBytes(String s, String encoding,
603                        String serverEncoding, boolean parserKnowsUnicode, Connection conn)
604                        throws SQLException {
605                try {
606                        SingleByteCharsetConverter converter = null;
607                        
608                        if (conn != null) {
609                                converter = conn.getCharsetConverter(encoding);
610                        } else {
611                                converter = SingleByteCharsetConverter.getInstance(encoding, null);
612                        }
613 
614                        return getBytes(s, converter, encoding, serverEncoding,
615                                        parserKnowsUnicode);
616                } catch (UnsupportedEncodingException uee) {
617                        throw SQLError.createSQLException(Messages.getString("StringUtils.0") //$NON-NLS-1$
618                                        + encoding + Messages.getString("StringUtils.1"),
619                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
620                }
621        }
622 
623        public static int getInt(byte[] buf) throws NumberFormatException {
624                int base = 10;
625 
626                int s = 0;
627 
628                /* Skip white space. */
629                while (Character.isWhitespace((char) buf[s]) && (s < buf.length)) {
630                        ++s;
631                }
632 
633                if (s == buf.length) {
634                        throw new NumberFormatException(new String(buf));
635                }
636 
637                /* Check for a sign. */
638                boolean negative = false;
639 
640                if ((char) buf[s] == '-') {
641                        negative = true;
642                        ++s;
643                } else if ((char) buf[s] == '+') {
644                        ++s;
645                }
646 
647                /* Save the pointer so we can check later if anything happened. */
648                int save = s;
649 
650                int cutoff = Integer.MAX_VALUE / base;
651                int cutlim = (Integer.MAX_VALUE % base);
652 
653                if (negative) {
654                        cutlim++;
655                }
656 
657                boolean overflow = false;
658 
659                int i = 0;
660 
661                for (; s < buf.length; s++) {
662                        char c = (char) buf[s];
663 
664                        if (Character.isDigit(c)) {
665                                c -= '0';
666                        } else if (Character.isLetter(c)) {
667                                c = (char) (Character.toUpperCase(c) - 'A' + 10);
668                        } else {
669                                break;
670                        }
671 
672                        if (c >= base) {
673                                break;
674                        }
675 
676                        /* Check for overflow. */
677                        if ((i > cutoff) || ((i == cutoff) && (c > cutlim))) {
678                                overflow = true;
679                        } else {
680                                i *= base;
681                                i += c;
682                        }
683                }
684 
685                if (s == save) {
686                        throw new NumberFormatException(new String(buf));
687                }
688 
689                if (overflow) {
690                        throw new NumberFormatException(new String(buf));
691                }
692 
693                /* Return the result of the appropriate sign. */
694                return (negative ? (-i) : i);
695        }
696 
697        public static long getLong(byte[] buf) throws NumberFormatException {
698                int base = 10;
699 
700                int s = 0;
701 
702                /* Skip white space. */
703                while (Character.isWhitespace((char) buf[s]) && (s < buf.length)) {
704                        ++s;
705                }
706 
707                if (s == buf.length) {
708                        throw new NumberFormatException(new String(buf));
709                }
710 
711                /* Check for a sign. */
712                boolean negative = false;
713 
714                if ((char) buf[s] == '-') {
715                        negative = true;
716                        ++s;
717                } else if ((char) buf[s] == '+') {
718                        ++s;
719                }
720 
721                /* Save the pointer so we can check later if anything happened. */
722                int save = s;
723 
724                long cutoff = Long.MAX_VALUE / base;
725                long cutlim = (int) (Long.MAX_VALUE % base);
726 
727                if (negative) {
728                        cutlim++;
729                }
730 
731                boolean overflow = false;
732                long i = 0;
733 
734                for (; s < buf.length; s++) {
735                        char c = (char) buf[s];
736 
737                        if (Character.isDigit(c)) {
738                                c -= '0';
739                        } else if (Character.isLetter(c)) {
740                                c = (char) (Character.toUpperCase(c) - 'A' + 10);
741                        } else {
742                                break;
743                        }
744 
745                        if (c >= base) {
746                                break;
747                        }
748 
749                        /* Check for overflow. */
750                        if ((i > cutoff) || ((i == cutoff) && (c > cutlim))) {
751                                overflow = true;
752                        } else {
753                                i *= base;
754                                i += c;
755                        }
756                }
757 
758                if (s == save) {
759                        throw new NumberFormatException(new String(buf));
760                }
761 
762                if (overflow) {
763                        throw new NumberFormatException(new String(buf));
764                }
765 
766                /* Return the result of the appropriate sign. */
767                return (negative ? (-i) : i);
768        }
769 
770        public static short getShort(byte[] buf) throws NumberFormatException {
771                short base = 10;
772 
773                int s = 0;
774 
775                /* Skip white space. */
776                while (Character.isWhitespace((char) buf[s]) && (s < buf.length)) {
777                        ++s;
778                }
779 
780                if (s == buf.length) {
781                        throw new NumberFormatException(new String(buf));
782                }
783 
784                /* Check for a sign. */
785                boolean negative = false;
786 
787                if ((char) buf[s] == '-') {
788                        negative = true;
789                        ++s;
790                } else if ((char) buf[s] == '+') {
791                        ++s;
792                }
793 
794                /* Save the pointer so we can check later if anything happened. */
795                int save = s;
796 
797                short cutoff = (short) (Short.MAX_VALUE / base);
798                short cutlim = (short) (Short.MAX_VALUE % base);
799 
800                if (negative) {
801                        cutlim++;
802                }
803 
804                boolean overflow = false;
805                short i = 0;
806 
807                for (; s < buf.length; s++) {
808                        char c = (char) buf[s];
809 
810                        if (Character.isDigit(c)) {
811                                c -= '0';
812                        } else if (Character.isLetter(c)) {
813                                c = (char) (Character.toUpperCase(c) - 'A' + 10);
814                        } else {
815                                break;
816                        }
817 
818                        if (c >= base) {
819                                break;
820                        }
821 
822                        /* Check for overflow. */
823                        if ((i > cutoff) || ((i == cutoff) && (c > cutlim))) {
824                                overflow = true;
825                        } else {
826                                i *= base;
827                                i += c;
828                        }
829                }
830 
831                if (s == save) {
832                        throw new NumberFormatException(new String(buf));
833                }
834 
835                if (overflow) {
836                        throw new NumberFormatException(new String(buf));
837                }
838 
839                /* Return the result of the appropriate sign. */
840                return (negative ? (short) -i : (short) i);
841        }
842 
843        public final static int indexOfIgnoreCase(int startingPosition,
844                        String searchIn, String searchFor) {
845                if ((searchIn == null) || (searchFor == null)
846                                || startingPosition > searchIn.length()) {
847                        return -1;
848                }
849 
850                int patternLength = searchFor.length();
851                int stringLength = searchIn.length();
852                int stopSearchingAt = stringLength - patternLength;
853 
854                int i = startingPosition;
855 
856                if (patternLength == 0) {
857                        return -1;
858                }
859 
860                // Brute force string pattern matching
861                // Some locales don't follow upper-case rule, so need to check both
862                char firstCharOfPatternUc = Character.toUpperCase(searchFor.charAt(0));
863                char firstCharOfPatternLc = Character.toLowerCase(searchFor.charAt(0));
864 
865                lookForFirstChar: while (true) {
866                        while ((i < stopSearchingAt)
867                                        && (Character.toUpperCase(searchIn.charAt(i)) != firstCharOfPatternUc)
868                                        && Character.toLowerCase(searchIn.charAt(i)) != firstCharOfPatternLc) {
869                                i++;
870                        }
871 
872                        if (i > stopSearchingAt) {
873                                return -1;
874                        }
875 
876                        int j = i + 1;
877                        int end = (j + patternLength) - 1;
878 
879                        int k = 1; // start at second char of pattern
880 
881                        while (j < end) {
882                                int searchInPos = j++;
883                                int searchForPos = k++;
884 
885                                if (Character.toUpperCase(searchIn.charAt(searchInPos)) != Character
886                                                .toUpperCase(searchFor.charAt(searchForPos))) {
887                                        i++;
888 
889                                        // start over
890                                        continue lookForFirstChar;
891                                }
892 
893                                // Georgian and Turkish locales don't have same convention, so
894                                // need to check lowercase
895                                // too!
896                                if (Character.toLowerCase(searchIn.charAt(searchInPos)) != Character
897                                                .toLowerCase(searchFor.charAt(searchForPos))) {
898                                        i++;
899 
900                                        // start over
901                                        continue lookForFirstChar;
902                                }
903                        }
904 
905                        return i; // found entire pattern
906                }
907        }
908 
909        /**
910         * DOCUMENT ME!
911         * 
912         * @param searchIn
913         *            DOCUMENT ME!
914         * @param searchFor
915         *            DOCUMENT ME!
916         * 
917         * @return DOCUMENT ME!
918         */
919        public final static int indexOfIgnoreCase(String searchIn, String searchFor) {
920                return indexOfIgnoreCase(0, searchIn, searchFor);
921        }
922 
923        public static int indexOfIgnoreCaseRespectMarker(int startAt, String src,
924                        String target, String marker, String markerCloses,
925                        boolean allowBackslashEscapes) {
926                char contextMarker = Character.MIN_VALUE;
927                boolean escaped = false;
928                int markerTypeFound = 0;
929                int srcLength = src.length();
930                int ind = 0;
931 
932                for (int i = startAt; i < srcLength; i++) {
933                        char c = src.charAt(i);
934 
935                        if (allowBackslashEscapes && c == '\\') {
936                                escaped = !escaped;
937                        } else if (c == markerCloses.charAt(markerTypeFound) && !escaped) {
938                                contextMarker = Character.MIN_VALUE;
939                        } else if ((ind = marker.indexOf(c)) != -1 && !escaped
940                                        && contextMarker == Character.MIN_VALUE) {
941                                markerTypeFound = ind;
942                                contextMarker = c;
943                        } else if (c == target.charAt(0) && !escaped
944                                        && contextMarker == Character.MIN_VALUE) {
945                                if (indexOfIgnoreCase(i, src, target) != -1)
946                                        return i;
947                        }
948                }
949 
950                return -1;
951 
952        }
953 
954        public static int indexOfIgnoreCaseRespectQuotes(int startAt, String src,
955                        String target, char quoteChar, boolean allowBackslashEscapes) {
956                char contextMarker = Character.MIN_VALUE;
957                boolean escaped = false;
958 
959                int srcLength = src.length();
960 
961                for (int i = startAt; i < srcLength; i++) {
962                        char c = src.charAt(i);
963 
964                        if (allowBackslashEscapes && c == '\\') {
965                                escaped = !escaped;
966                        } else if (c == contextMarker && !escaped) {
967                                contextMarker = Character.MIN_VALUE;
968                        } else if (c == quoteChar && !escaped
969                                        && contextMarker == Character.MIN_VALUE) {
970                                contextMarker = c;
971                        } else if (c == target.charAt(0) && !escaped
972                                        && contextMarker == Character.MIN_VALUE) {
973                                if (startsWithIgnoreCase(src, i, target))
974                                        return i;
975                        }
976                }
977 
978                return -1;
979 
980        }
981 
982        /**
983         * Splits stringToSplit into a list, using the given delimitter
984         * 
985         * @param stringToSplit
986         *            the string to split
987         * @param delimitter
988         *            the string to split on
989         * @param trim
990         *            should the split strings be whitespace trimmed?
991         * 
992         * @return the list of strings, split by delimitter
993         * 
994         * @throws IllegalArgumentException
995         *             DOCUMENT ME!
996         */
997        public static final List split(String stringToSplit, String delimitter,
998                        boolean trim) {
999                if (stringToSplit == null) {
1000                        return new ArrayList();
1001                }
1002 
1003                if (delimitter == null) {
1004                        throw new IllegalArgumentException();
1005                }
1006 
1007                StringTokenizer tokenizer = new StringTokenizer(stringToSplit,
1008                                delimitter, false);
1009 
1010                List splitTokens = new ArrayList(tokenizer.countTokens());
1011 
1012                while (tokenizer.hasMoreTokens()) {
1013                        String token = tokenizer.nextToken();
1014 
1015                        if (trim) {
1016                                token = token.trim();
1017                        }
1018 
1019                        splitTokens.add(token);
1020                }
1021 
1022                return splitTokens;
1023        }
1024 
1025        /**
1026         * Splits stringToSplit into a list, using the given delimitter
1027         * 
1028         * @param stringToSplit
1029         *            the string to split
1030         * @param delimitter
1031         *            the string to split on
1032         * @param trim
1033         *            should the split strings be whitespace trimmed?
1034         * 
1035         * @return the list of strings, split by delimiter
1036         * 
1037         * @throws IllegalArgumentException
1038         *             DOCUMENT ME!
1039         */
1040        public static final List split(String stringToSplit, String delimiter,
1041                        String markers, String markerCloses, boolean trim) {
1042                if (stringToSplit == null) {
1043                        return new ArrayList();
1044                }
1045 
1046                if (delimiter == null) {
1047                        throw new IllegalArgumentException();
1048                }
1049 
1050                int delimPos = 0;
1051                int currentPos = 0;
1052 
1053                List splitTokens = new ArrayList();
1054 
1055                while ((delimPos = indexOfIgnoreCaseRespectMarker(currentPos,
1056                                stringToSplit, delimiter, markers, markerCloses, false)) != -1) {
1057                        String token = stringToSplit.substring(currentPos, delimPos);
1058 
1059                        if (trim) {
1060                                token = token.trim();
1061                        }
1062 
1063                        splitTokens.add(token);
1064                        currentPos = delimPos + 1;
1065                }
1066 
1067                if (currentPos < stringToSplit.length()) {
1068                        String token = stringToSplit.substring(currentPos);
1069 
1070                        if (trim) {
1071                                token = token.trim();
1072                        }
1073 
1074                        splitTokens.add(token);
1075                }
1076 
1077                return splitTokens;
1078        }
1079 
1080        private static boolean startsWith(byte[] dataFrom, String chars) {
1081                for (int i = 0; i < chars.length(); i++) {
1082                        if (dataFrom[i] != chars.charAt(i)) {
1083                                return false;
1084                        }
1085                }
1086                return true;
1087        }
1088 
1089        /**
1090         * Determines whether or not the string 'searchIn' contains the string
1091         * 'searchFor', dis-regarding case starting at 'startAt' Shorthand for a
1092         * String.regionMatch(...)
1093         * 
1094         * @param searchIn
1095         *            the string to search in
1096         * @param startAt
1097         *            the position to start at
1098         * @param searchFor
1099         *            the string to search for
1100         * 
1101         * @return whether searchIn starts with searchFor, ignoring case
1102         */
1103        public static boolean startsWithIgnoreCase(String searchIn, int startAt,
1104                        String searchFor) {
1105                return searchIn.regionMatches(true, startAt, searchFor, 0, searchFor
1106                                .length());
1107        }
1108 
1109        /**
1110         * Determines whether or not the string 'searchIn' contains the string
1111         * 'searchFor', dis-regarding case. Shorthand for a String.regionMatch(...)
1112         * 
1113         * @param searchIn
1114         *            the string to search in
1115         * @param searchFor
1116         *            the string to search for
1117         * 
1118         * @return whether searchIn starts with searchFor, ignoring case
1119         */
1120        public static boolean startsWithIgnoreCase(String searchIn, String searchFor) {
1121                return startsWithIgnoreCase(searchIn, 0, searchFor);
1122        }
1123 
1124        /**
1125         * Determines whether or not the sting 'searchIn' contains the string
1126         * 'searchFor', disregarding case,leading whitespace and non-alphanumeric
1127         * characters.
1128         * 
1129         * @param searchIn
1130         *            the string to search in
1131         * @param searchFor
1132         *            the string to search for
1133         * 
1134         * @return true if the string starts with 'searchFor' ignoring whitespace
1135         */
1136        public static boolean startsWithIgnoreCaseAndNonAlphaNumeric(
1137                        String searchIn, String searchFor) {
1138                if (searchIn == null) {
1139                        return searchFor == null;
1140                }
1141 
1142                int beginPos = 0;
1143 
1144                int inLength = searchIn.length();
1145 
1146                for (beginPos = 0; beginPos < inLength; beginPos++) {
1147                        char c = searchIn.charAt(beginPos);
1148 
1149                        if (Character.isLetterOrDigit(c)) {
1150                                break;
1151                        }
1152                }
1153 
1154                return startsWithIgnoreCase(searchIn, beginPos, searchFor);
1155        }
1156 
1157        /**
1158         * Determines whether or not the sting 'searchIn' contains the string
1159         * 'searchFor', disregarding case and leading whitespace
1160         * 
1161         * @param searchIn
1162         *            the string to search in
1163         * @param searchFor
1164         *            the string to search for
1165         * 
1166         * @return true if the string starts with 'searchFor' ignoring whitespace
1167         */
1168        public static boolean startsWithIgnoreCaseAndWs(String searchIn,
1169                        String searchFor) {
1170                if (searchIn == null) {
1171                        return searchFor == null;
1172                }
1173 
1174                int beginPos = 0;
1175 
1176                int inLength = searchIn.length();
1177 
1178                for (beginPos = 0; beginPos < inLength; beginPos++) {
1179                        if (!Character.isWhitespace(searchIn.charAt(beginPos))) {
1180                                break;
1181                        }
1182                }
1183 
1184                return startsWithIgnoreCase(searchIn, beginPos, searchFor);
1185        }
1186 
1187        /**
1188         * @param bytesToStrip
1189         * @param prefix
1190         * @param suffix
1191         * @return
1192         */
1193        public static byte[] stripEnclosure(byte[] source, String prefix,
1194                        String suffix) {
1195                if (source.length >= prefix.length() + suffix.length()
1196                                && startsWith(source, prefix) && endsWith(source, suffix)) {
1197 
1198                        int totalToStrip = prefix.length() + suffix.length();
1199                        int enclosedLength = source.length - totalToStrip;
1200                        byte[] enclosed = new byte[enclosedLength];
1201 
1202                        int startPos = prefix.length();
1203                        int numToCopy = enclosed.length;
1204                        System.arraycopy(source, startPos, enclosed, 0, numToCopy);
1205 
1206                        return enclosed;
1207                }
1208                return source;
1209        }
1210 
1211        /**
1212         * Returns the bytes as an ASCII String.
1213         * 
1214         * @param buffer
1215         *            the bytes representing the string
1216         * 
1217         * @return The ASCII String.
1218         */
1219        public static final String toAsciiString(byte[] buffer) {
1220                return toAsciiString(buffer, 0, buffer.length);
1221        }
1222 
1223        /**
1224         * Returns the bytes as an ASCII String.
1225         * 
1226         * @param buffer
1227         *            the bytes to convert
1228         * @param startPos
1229         *            the position to start converting
1230         * @param length
1231         *            the length of the string to convert
1232         * 
1233         * @return the ASCII string
1234         */
1235        public static final String toAsciiString(byte[] buffer, int startPos,
1236                        int length) {
1237                char[] charArray = new char[length];
1238                int readpoint = startPos;
1239 
1240                for (int i = 0; i < length; i++) {
1241                        charArray[i] = (char) buffer[readpoint];
1242                        readpoint++;
1243                }
1244 
1245                return new String(charArray);
1246        }
1247 
1248        /**
1249         * Compares searchIn against searchForWildcard with wildcards (heavily
1250         * borrowed from strings/ctype-simple.c in the server sources)
1251         * 
1252         * @param searchIn
1253         *            the string to search in
1254         * @param searchForWildcard
1255         *            the string to search for, using the 'standard' SQL wildcard
1256         *            chars of '%' and '_'
1257         * 
1258         * @return WILD_COMPARE_MATCH_NO_WILD if matched, WILD_COMPARE_NO_MATCH if
1259         *         not matched with wildcard, WILD_COMPARE_MATCH_WITH_WILD if
1260         *         matched with wildcard
1261         */
1262        public static int wildCompare(String searchIn, String searchForWildcard) {
1263                if ((searchIn == null) || (searchForWildcard == null)) {
1264                        return WILD_COMPARE_NO_MATCH;
1265                }
1266 
1267                if (searchForWildcard.equals("%")) { //$NON-NLS-1$
1268 
1269                        return WILD_COMPARE_MATCH_WITH_WILD;
1270                }
1271 
1272                int result = WILD_COMPARE_NO_MATCH; /* Not found, using wildcards */
1273 
1274                char wildcardMany = '%';
1275                char wildcardOne = '_';
1276                char wildcardEscape = '\\';
1277 
1278                int searchForPos = 0;
1279                int searchForEnd = searchForWildcard.length();
1280 
1281                int searchInPos = 0;
1282                int searchInEnd = searchIn.length();
1283 
1284                while (searchForPos != searchForEnd) {
1285                        char wildstrChar = searchForWildcard.charAt(searchForPos);
1286 
1287                        while ((searchForWildcard.charAt(searchForPos) != wildcardMany)
1288                                        && (wildstrChar != wildcardOne)) {
1289                                if ((searchForWildcard.charAt(searchForPos) == wildcardEscape)
1290                                                && ((searchForPos + 1) != searchForEnd)) {
1291                                        searchForPos++;
1292                                }
1293 
1294                                if ((searchInPos == searchInEnd)
1295                                                || (Character.toUpperCase(searchForWildcard
1296                                                                .charAt(searchForPos++)) != Character
1297                                                                .toUpperCase(searchIn.charAt(searchInPos++)))) {
1298                                        return WILD_COMPARE_MATCH_WITH_WILD; /* No match */
1299                                }
1300 
1301                                if (searchForPos == searchForEnd) {
1302                                        return ((searchInPos != searchInEnd) ? WILD_COMPARE_MATCH_WITH_WILD
1303                                                        : WILD_COMPARE_MATCH_NO_WILD); /*
1304                                                                                                                         * Match if both are
1305                                                                                                                         * at end
1306                                                                                                                         */
1307                                }
1308 
1309                                result = WILD_COMPARE_MATCH_WITH_WILD; /* Found an anchor char */
1310                        }
1311 
1312                        if (searchForWildcard.charAt(searchForPos) == wildcardOne) {
1313                                do {
1314                                        if (searchInPos == searchInEnd) { /*
1315                                                                                                                 * Skip one char if
1316                                                                                                                 * possible
1317                                                                                                                 */
1318 
1319                                                return (result);
1320                                        }
1321 
1322                                        searchInPos++;
1323                                } while ((++searchForPos < searchForEnd)
1324                                                && (searchForWildcard.charAt(searchForPos) == wildcardOne));
1325 
1326                                if (searchForPos == searchForEnd) {
1327                                        break;
1328                                }
1329                        }
1330 
1331                        if (searchForWildcard.charAt(searchForPos) == wildcardMany) { /*
1332                                                                                                                                                         * Found
1333                                                                                                                                                         * w_many
1334                                                                                                                                                         */
1335 
1336                                char cmp;
1337 
1338                                searchForPos++;
1339 
1340                                /* Remove any '%' and '_' from the wild search string */
1341                                for (; searchForPos != searchForEnd; searchForPos++) {
1342                                        if (searchForWildcard.charAt(searchForPos) == wildcardMany) {
1343                                                continue;
1344                                        }
1345 
1346                                        if (searchForWildcard.charAt(searchForPos) == wildcardOne) {
1347                                                if (searchInPos == searchInEnd) {
1348                                                        return (WILD_COMPARE_NO_MATCH);
1349                                                }
1350 
1351                                                searchInPos++;
1352 
1353                                                continue;
1354                                        }
1355 
1356                                        break; /* Not a wild character */
1357                                }
1358 
1359                                if (searchForPos == searchForEnd) {
1360                                        return WILD_COMPARE_MATCH_NO_WILD; /* Ok if w_many is last */
1361                                }
1362 
1363                                if (searchInPos == searchInEnd) {
1364                                        return WILD_COMPARE_NO_MATCH;
1365                                }
1366 
1367                                if (((cmp = searchForWildcard.charAt(searchForPos)) == wildcardEscape)
1368                                                && ((searchForPos + 1) != searchForEnd)) {
1369                                        cmp = searchForWildcard.charAt(++searchForPos);
1370                                }
1371 
1372                                searchForPos++;
1373 
1374                                do {
1375                                        while ((searchInPos != searchInEnd)
1376                                                        && (Character.toUpperCase(searchIn
1377                                                                        .charAt(searchInPos)) != Character
1378                                                                        .toUpperCase(cmp)))
1379                                                searchInPos++;
1380 
1381                                        if (searchInPos++ == searchInEnd) {
1382                                                return WILD_COMPARE_NO_MATCH;
1383                                        }
1384 
1385                                        {
1386                                                int tmp = wildCompare(searchIn, searchForWildcard);
1387 
1388                                                if (tmp <= 0) {
1389                                                        return (tmp);
1390                                                }
1391                                        }
1392                                } while ((searchInPos != searchInEnd)
1393                                                && (searchForWildcard.charAt(0) != wildcardMany));
1394 
1395                                return WILD_COMPARE_NO_MATCH;
1396                        }
1397                }
1398 
1399                return ((searchInPos != searchInEnd) ? WILD_COMPARE_MATCH_WITH_WILD
1400                                : WILD_COMPARE_MATCH_NO_WILD);
1401        }
1402}

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov