001    /*
002     * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/src/java/org/apache/commons/ssl/Util.java $
003     * $Revision: 132 $
004     * $Date: 2008-01-11 21:20:26 -0800 (Fri, 11 Jan 2008) $
005     *
006     * ====================================================================
007     * Licensed to the Apache Software Foundation (ASF) under one
008     * or more contributor license agreements.  See the NOTICE file
009     * distributed with this work for additional information
010     * regarding copyright ownership.  The ASF licenses this file
011     * to you under the Apache License, Version 2.0 (the
012     * "License"); you may not use this file except in compliance
013     * with the License.  You may obtain a copy of the License at
014     *
015     *   http://www.apache.org/licenses/LICENSE-2.0
016     *
017     * Unless required by applicable law or agreed to in writing,
018     * software distributed under the License is distributed on an
019     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020     * KIND, either express or implied.  See the License for the
021     * specific language governing permissions and limitations
022     * under the License.
023     * ====================================================================
024     *
025     * This software consists of voluntary contributions made by many
026     * individuals on behalf of the Apache Software Foundation.  For more
027     * information on the Apache Software Foundation, please see
028     * <http://www.apache.org/>.
029     *
030     */
031    
032    package org.apache.commons.ssl;
033    
034    import org.apache.commons.ssl.util.ByteArrayReadLine;
035    
036    import java.io.ByteArrayInputStream;
037    import java.io.IOException;
038    import java.io.InputStream;
039    import java.io.OutputStream;
040    import java.net.UnknownHostException;
041    import java.util.LinkedList;
042    import java.util.Map;
043    import java.util.StringTokenizer;
044    import java.util.TreeMap;
045    
046    /**
047     * @author Credit Union Central of British Columbia
048     * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
049     * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
050     * @since 28-Feb-2006
051     */
052    public class Util {
053        public final static int SIZE_KEY = 0;
054        public final static int LAST_READ_KEY = 1;
055    
056        public static boolean isYes(String yesString) {
057            if (yesString == null) {
058                return false;
059            }
060            String s = yesString.trim().toUpperCase();
061            return "1".equals(s) || "YES".equals(s) || "TRUE".equals(s) ||
062                   "ENABLE".equals(s) || "ENABLED".equals(s) || "Y".equals(s) ||
063                   "ON".equals(s);
064        }
065    
066        public static String trim(final String s) {
067            if (s == null || "".equals(s)) {
068                return s;
069            }
070            int i = 0;
071            int j = s.length() - 1;
072            while (isWhiteSpace(s.charAt(i))) {
073                i++;
074            }
075            while (isWhiteSpace(s.charAt(j))) {
076                j--;
077            }
078            return j >= i ? s.substring(i, j + 1) : "";
079        }
080    
081        public static boolean isWhiteSpace(final char c) {
082            switch (c) {
083                case 0:
084                case ' ':
085                case '\t':
086                case '\n':
087                case '\r':
088                case '\f':
089                    return true;
090                default:
091                    return false;
092            }
093        }
094    
095        public static void pipeStream(InputStream in, OutputStream out)
096            throws IOException {
097            pipeStream(in, out, true);
098        }
099    
100        public static void pipeStream(InputStream in, OutputStream out,
101                                      boolean autoClose)
102            throws IOException {
103            byte[] buf = new byte[8192];
104            IOException ioe = null;
105            try {
106                int bytesRead = in.read(buf);
107                while (bytesRead >= 0) {
108                    if (bytesRead > 0) {
109                        out.write(buf, 0, bytesRead);
110                    }
111                    bytesRead = in.read(buf);
112                }
113            }
114            finally {
115                // Probably it's best to let consumer call "close", but I'm usually
116                // the consumer, and I want to be lazy.  [Julius, November 20th, 2006]
117                try { in.close(); } catch (IOException e) { ioe = e; }
118                if (autoClose) {
119                    try { out.close(); } catch (IOException e) { ioe = e; }
120                }
121            }
122            if (ioe != null) {
123                throw ioe;
124            }
125        }
126    
127        public static byte[] streamToBytes(final ByteArrayInputStream in,
128                                           int maxLength) {
129            byte[] buf = new byte[maxLength];
130            int[] status = fill(buf, 0, in);
131            int size = status[SIZE_KEY];
132            if (buf.length != size) {
133                byte[] smallerBuf = new byte[size];
134                System.arraycopy(buf, 0, smallerBuf, 0, size);
135                buf = smallerBuf;
136            }
137            return buf;
138        }
139    
140        public static byte[] streamToBytes(final InputStream in, int maxLength)
141            throws IOException {
142            byte[] buf = new byte[maxLength];
143            int[] status = fill(buf, 0, in);
144            int size = status[SIZE_KEY];
145            if (buf.length != size) {
146                byte[] smallerBuf = new byte[size];
147                System.arraycopy(buf, 0, smallerBuf, 0, size);
148                buf = smallerBuf;
149            }
150            return buf;
151        }
152    
153        public static byte[] streamToBytes(final InputStream in) throws IOException {
154            byte[] buf = new byte[4096];
155            try {
156                int[] status = fill(buf, 0, in);
157                int size = status[SIZE_KEY];
158                int lastRead = status[LAST_READ_KEY];
159                while (lastRead != -1) {
160                    buf = resizeArray(buf);
161                    status = fill(buf, size, in);
162                    size = status[SIZE_KEY];
163                    lastRead = status[LAST_READ_KEY];
164                }
165                if (buf.length != size) {
166                    byte[] smallerBuf = new byte[size];
167                    System.arraycopy(buf, 0, smallerBuf, 0, size);
168                    buf = smallerBuf;
169                }
170            }
171            finally {
172                in.close();
173            }
174            return buf;
175        }
176    
177        public static byte[] streamToBytes(final ByteArrayInputStream in) {
178            byte[] buf = new byte[4096];
179            int[] status = fill(buf, 0, in);
180            int size = status[SIZE_KEY];
181            int lastRead = status[LAST_READ_KEY];
182            while (lastRead != -1) {
183                buf = resizeArray(buf);
184                status = fill(buf, size, in);
185                size = status[SIZE_KEY];
186                lastRead = status[LAST_READ_KEY];
187            }
188            if (buf.length != size) {
189                byte[] smallerBuf = new byte[size];
190                System.arraycopy(buf, 0, smallerBuf, 0, size);
191                buf = smallerBuf;
192            }
193            // in.close();  <-- this is a no-op on ByteArrayInputStream.
194            return buf;
195        }
196    
197        public static int[] fill(final byte[] buf, final int offset,
198                                 final InputStream in)
199            throws IOException {
200            int read = in.read(buf, offset, buf.length - offset);
201            int lastRead = read;
202            if (read == -1) {
203                read = 0;
204            }
205            while (lastRead != -1 && read + offset < buf.length) {
206                lastRead = in.read(buf, offset + read, buf.length - read - offset);
207                if (lastRead != -1) {
208                    read += lastRead;
209                }
210            }
211            return new int[]{offset + read, lastRead};
212        }
213    
214        public static int[] fill(final byte[] buf, final int offset,
215                                 final ByteArrayInputStream in) {
216            int read = in.read(buf, offset, buf.length - offset);
217            int lastRead = read;
218            if (read == -1) {
219                read = 0;
220            }
221            while (lastRead != -1 && read + offset < buf.length) {
222                lastRead = in.read(buf, offset + read, buf.length - read - offset);
223                if (lastRead != -1) {
224                    read += lastRead;
225                }
226            }
227            return new int[]{offset + read, lastRead};
228        }
229    
230        public static byte[] resizeArray(final byte[] bytes) {
231            byte[] biggerBytes = new byte[bytes.length * 2];
232            System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length);
233            return biggerBytes;
234        }
235    
236        public static String pad(String s, final int length, final boolean left) {
237            if (s == null) {
238                s = "";
239            }
240            int diff = length - s.length();
241            if (diff == 0) {
242                return s;
243            } else if (diff > 0) {
244                StringBuffer sb = new StringBuffer();
245                if (left) {
246                    for (int i = 0; i < diff; i++) {
247                        sb.append(' ');
248                    }
249                }
250                sb.append(s);
251                if (!left) {
252                    for (int i = 0; i < diff; i++) {
253                        sb.append(' ');
254                    }
255                }
256                return sb.toString();
257            } else {
258                return s;
259            }
260        }
261    
262        public static Map parseArgs(final String[] cargs) {
263            Map args = new TreeMap();
264            Map ARGS_MATCH = Ping.ARGS_MATCH;
265    
266            int l = cargs.length;
267            final String[] EMPTY_VALUES = {""};
268            for (int i = 0; i < l; i++) {
269                String k = cargs[i];
270                Ping.Arg a = (Ping.Arg) ARGS_MATCH.get(k);
271                if (l > i + 1) {
272                    String v = cargs[++i];
273                    while (ARGS_MATCH.containsKey(v)) {
274                        args.put(a, EMPTY_VALUES);
275                        a = (Ping.Arg) ARGS_MATCH.get(v);
276                        v = "";
277                        if (l > i + 1) {
278                            v = cargs[++i];
279                        }
280                    }
281                    String[] values = new String[1];
282                    values[0] = v;
283                    args.put(a, values);
284                    if (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) {
285                        LinkedList list = new LinkedList();
286                        list.add(v);
287                        while (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) {
288                            v = cargs[++i];
289                            list.add(v);
290                        }
291                        args.put(a, list.toArray(new String[list.size()]));
292                    }
293                } else {
294                    args.put(a, EMPTY_VALUES);
295                }
296            }
297            return args;
298        }
299    
300        public static HostPort toAddress(final String target,
301                                         final int defaultPort)
302            throws UnknownHostException {
303            String host = target;
304            int port = defaultPort;
305            StringTokenizer st = new StringTokenizer(target, ":");
306            if (st.hasMoreTokens()) {
307                host = st.nextToken().trim();
308            }
309            if (st.hasMoreTokens()) {
310                port = Integer.parseInt(st.nextToken().trim());
311            }
312            if (st.hasMoreTokens()) {
313                throw new IllegalArgumentException("Invalid host: " + target);
314            }
315            return new HostPort(host, port);
316        }
317    
318        public static String cipherToAuthType(String cipher) {
319            if (cipher == null) {
320                return null;
321            }
322    
323            // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  ==> "DHE_DSS_EXPORT"
324            // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA      ==> "DHE_DSS"
325            // SSL_RSA_WITH_3DES_EDE_CBC_SHA          ==> "RSA"
326    
327            StringTokenizer st = new StringTokenizer(cipher.trim(), "_");
328            if (st.hasMoreTokens()) {
329                st.nextToken();  // always skip first token
330            }
331            if (st.hasMoreTokens()) {
332                String tok = st.nextToken();
333                StringBuffer buf = new StringBuffer();
334                buf.append(tok);
335                if (st.hasMoreTokens()) {
336                    tok = st.nextToken();
337                    while (!"WITH".equalsIgnoreCase(tok)) {
338                        buf.append('_');
339                        buf.append(tok);
340                        tok = st.nextToken();
341                    }
342                }
343                return buf.toString();
344            }
345            throw new IllegalArgumentException("not a valid cipher: " + cipher);
346        }
347    
348    
349        public static void main(String[] args) throws Exception {
350            String s = "line1\n\rline2\n\rline3";
351            ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
352            ByteArrayReadLine readLine = new ByteArrayReadLine(in);
353            String line = readLine.next();
354            while (line != null) {
355                System.out.println(line);
356                line = readLine.next();
357            }
358    
359            System.out.println("--------- test 2 ----------");
360    
361            s = "line1\n\rline2\n\rline3\n\r\n\r";
362            in = new ByteArrayInputStream(s.getBytes());
363            readLine = new ByteArrayReadLine(in);
364            line = readLine.next();
365            while (line != null) {
366                System.out.println(line);
367                line = readLine.next();
368            }
369    
370        }
371    
372    
373    }