001/* 002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Util.java $ 003 * $Revision: 121 $ 004 * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $ 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 032package org.apache.commons.ssl; 033 034import java.io.ByteArrayInputStream; 035import java.io.IOException; 036import java.io.InputStream; 037import java.io.OutputStream; 038import java.net.UnknownHostException; 039import java.util.LinkedList; 040import java.util.Map; 041import java.util.StringTokenizer; 042import java.util.TreeMap; 043 044/** 045 * @author Credit Union Central of British Columbia 046 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a> 047 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a> 048 * @since 28-Feb-2006 049 */ 050public class Util { 051 public final static int SIZE_KEY = 0; 052 public final static int LAST_READ_KEY = 1; 053 054 public static boolean isYes(String yesString) { 055 if (yesString == null) { 056 return false; 057 } 058 String s = yesString.trim().toUpperCase(); 059 return "1".equals(s) || "YES".equals(s) || "TRUE".equals(s) || 060 "ENABLE".equals(s) || "ENABLED".equals(s) || "Y".equals(s) || 061 "ON".equals(s); 062 } 063 064 public static String trim(final String s) { 065 if (s == null || "".equals(s)) { 066 return s; 067 } 068 int i = 0; 069 int j = s.length() - 1; 070 while (isWhiteSpace(s.charAt(i))) { 071 i++; 072 } 073 while (isWhiteSpace(s.charAt(j))) { 074 j--; 075 } 076 return j >= i ? s.substring(i, j + 1) : ""; 077 } 078 079 public static boolean isWhiteSpace(final char c) { 080 switch (c) { 081 case 0: 082 case ' ': 083 case '\t': 084 case '\n': 085 case '\r': 086 case '\f': 087 return true; 088 default: 089 return false; 090 } 091 } 092 093 public static void pipeStream(InputStream in, OutputStream out) 094 throws IOException { 095 pipeStream(in, out, true); 096 } 097 098 public static void pipeStream(InputStream in, OutputStream out, 099 boolean autoClose) 100 throws IOException { 101 byte[] buf = new byte[4096]; 102 IOException ioe = null; 103 try { 104 int bytesRead = in.read(buf); 105 while (bytesRead >= 0) { 106 if (bytesRead > 0) { 107 out.write(buf, 0, bytesRead); 108 } 109 bytesRead = in.read(buf); 110 } 111 } 112 finally { 113 // Probably it's best to let consumer call "close", but I'm usually 114 // the consumer, and I want to be lazy. [Julius, November 20th, 2006] 115 try { in.close(); } catch (IOException e) { ioe = e; } 116 if (autoClose) { 117 try { out.close(); } catch (IOException e) { ioe = e; } 118 } 119 } 120 if (ioe != null) { 121 throw ioe; 122 } 123 } 124 125 public static byte[] streamToBytes(final ByteArrayInputStream in, 126 int maxLength) { 127 byte[] buf = new byte[maxLength]; 128 int[] status = fill(buf, 0, in); 129 int size = status[SIZE_KEY]; 130 if (buf.length != size) { 131 byte[] smallerBuf = new byte[size]; 132 System.arraycopy(buf, 0, smallerBuf, 0, size); 133 buf = smallerBuf; 134 } 135 return buf; 136 } 137 138 public static byte[] streamToBytes(final InputStream in, int maxLength) 139 throws IOException { 140 byte[] buf = new byte[maxLength]; 141 int[] status = fill(buf, 0, in); 142 int size = status[SIZE_KEY]; 143 if (buf.length != size) { 144 byte[] smallerBuf = new byte[size]; 145 System.arraycopy(buf, 0, smallerBuf, 0, size); 146 buf = smallerBuf; 147 } 148 return buf; 149 } 150 151 public static byte[] streamToBytes(final InputStream in) throws IOException { 152 byte[] buf = new byte[4096]; 153 try { 154 int[] status = fill(buf, 0, in); 155 int size = status[SIZE_KEY]; 156 int lastRead = status[LAST_READ_KEY]; 157 while (lastRead != -1) { 158 buf = resizeArray(buf); 159 status = fill(buf, size, in); 160 size = status[SIZE_KEY]; 161 lastRead = status[LAST_READ_KEY]; 162 } 163 if (buf.length != size) { 164 byte[] smallerBuf = new byte[size]; 165 System.arraycopy(buf, 0, smallerBuf, 0, size); 166 buf = smallerBuf; 167 } 168 } 169 finally { 170 in.close(); 171 } 172 return buf; 173 } 174 175 public static byte[] streamToBytes(final ByteArrayInputStream in) { 176 byte[] buf = new byte[4096]; 177 int[] status = fill(buf, 0, in); 178 int size = status[SIZE_KEY]; 179 int lastRead = status[LAST_READ_KEY]; 180 while (lastRead != -1) { 181 buf = resizeArray(buf); 182 status = fill(buf, size, in); 183 size = status[SIZE_KEY]; 184 lastRead = status[LAST_READ_KEY]; 185 } 186 if (buf.length != size) { 187 byte[] smallerBuf = new byte[size]; 188 System.arraycopy(buf, 0, smallerBuf, 0, size); 189 buf = smallerBuf; 190 } 191 // in.close(); <-- this is a no-op on ByteArrayInputStream. 192 return buf; 193 } 194 195 public static int[] fill(final byte[] buf, final int offset, 196 final InputStream in) 197 throws IOException { 198 int read = in.read(buf, offset, buf.length - offset); 199 int lastRead = read; 200 if (read == -1) { 201 read = 0; 202 } 203 while (lastRead != -1 && read + offset < buf.length) { 204 lastRead = in.read(buf, offset + read, buf.length - read - offset); 205 if (lastRead != -1) { 206 read += lastRead; 207 } 208 } 209 return new int[]{offset + read, lastRead}; 210 } 211 212 public static int[] fill(final byte[] buf, final int offset, 213 final ByteArrayInputStream in) { 214 int read = in.read(buf, offset, buf.length - offset); 215 int lastRead = read; 216 if (read == -1) { 217 read = 0; 218 } 219 while (lastRead != -1 && read + offset < buf.length) { 220 lastRead = in.read(buf, offset + read, buf.length - read - offset); 221 if (lastRead != -1) { 222 read += lastRead; 223 } 224 } 225 return new int[]{offset + read, lastRead}; 226 } 227 228 public static byte[] resizeArray(final byte[] bytes) { 229 byte[] biggerBytes = new byte[bytes.length * 2]; 230 System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length); 231 return biggerBytes; 232 } 233 234 public static String pad(String s, final int length, final boolean left) { 235 if (s == null) { 236 s = ""; 237 } 238 int diff = length - s.length(); 239 if (diff == 0) { 240 return s; 241 } else if (diff > 0) { 242 StringBuffer sb = new StringBuffer(); 243 if (left) { 244 for (int i = 0; i < diff; i++) { 245 sb.append(' '); 246 } 247 } 248 sb.append(s); 249 if (!left) { 250 for (int i = 0; i < diff; i++) { 251 sb.append(' '); 252 } 253 } 254 return sb.toString(); 255 } else { 256 return s; 257 } 258 } 259 260 public static Map parseArgs(final String[] cargs) { 261 Map args = new TreeMap(); 262 Map ARGS_MATCH = Ping.ARGS_MATCH; 263 264 int l = cargs.length; 265 final String[] EMPTY_VALUES = {""}; 266 for (int i = 0; i < l; i++) { 267 String k = cargs[i]; 268 Ping.Arg a = (Ping.Arg) ARGS_MATCH.get(k); 269 if (l > i + 1) { 270 String v = cargs[++i]; 271 while (ARGS_MATCH.containsKey(v)) { 272 args.put(a, EMPTY_VALUES); 273 a = (Ping.Arg) ARGS_MATCH.get(v); 274 v = ""; 275 if (l > i + 1) { 276 v = cargs[++i]; 277 } 278 } 279 String[] values = new String[1]; 280 values[0] = v; 281 args.put(a, values); 282 if (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { 283 LinkedList list = new LinkedList(); 284 list.add(v); 285 while (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { 286 v = cargs[++i]; 287 list.add(v); 288 } 289 args.put(a, list.toArray(new String[list.size()])); 290 } 291 } else { 292 args.put(a, EMPTY_VALUES); 293 } 294 } 295 return args; 296 } 297 298 public static String readLine(final InputStream in) throws IOException { 299 StringBuffer buf = new StringBuffer(64); 300 int b = in.read(); 301 while (b != -1) { 302 char c = (char) b; 303 if (c == '\n' || c == '\r') { 304 if (buf.length() >= 1) { 305 return buf.toString(); 306 } 307 } else { 308 buf.append(c); 309 } 310 b = in.read(); 311 } 312 return buf.length() >= 1 ? buf.toString() : null; 313 } 314 315 public static String readLine(final ByteArrayInputStream in) { 316 StringBuffer buf = new StringBuffer(64); 317 int b = in.read(); 318 while (b != -1) { 319 char c = (char) b; 320 if (c == '\n' || c == '\r') { 321 if (buf.length() >= 1) { 322 return buf.toString(); 323 } 324 } else { 325 buf.append(c); 326 } 327 b = in.read(); 328 } 329 return buf.length() >= 1 ? buf.toString() : null; 330 } 331 332 public static HostPort toAddress(final String target, 333 final int defaultPort) 334 throws UnknownHostException { 335 String host = target; 336 int port = defaultPort; 337 StringTokenizer st = new StringTokenizer(target, ":"); 338 if (st.hasMoreTokens()) { 339 host = st.nextToken().trim(); 340 } 341 if (st.hasMoreTokens()) { 342 port = Integer.parseInt(st.nextToken().trim()); 343 } 344 if (st.hasMoreTokens()) { 345 throw new IllegalArgumentException("Invalid host: " + target); 346 } 347 return new HostPort(host, port); 348 } 349 350 public static String cipherToAuthType(String cipher) { 351 if (cipher == null) { 352 return null; 353 } 354 355 // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ==> "DHE_DSS_EXPORT" 356 // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA ==> "DHE_DSS" 357 // SSL_RSA_WITH_3DES_EDE_CBC_SHA ==> "RSA" 358 359 StringTokenizer st = new StringTokenizer(cipher.trim(), "_"); 360 if (st.hasMoreTokens()) { 361 st.nextToken(); // always skip first token 362 } 363 if (st.hasMoreTokens()) { 364 String tok = st.nextToken(); 365 StringBuffer buf = new StringBuffer(); 366 buf.append(tok); 367 if (st.hasMoreTokens()) { 368 tok = st.nextToken(); 369 while (!"WITH".equalsIgnoreCase(tok)) { 370 buf.append('_'); 371 buf.append(tok); 372 tok = st.nextToken(); 373 } 374 } 375 return buf.toString(); 376 } 377 throw new IllegalArgumentException("not a valid cipher: " + cipher); 378 } 379 380 381 public static void main(String[] args) throws Exception { 382 String s = "line1\n\rline2\n\rline3"; 383 InputStream in = new ByteArrayInputStream(s.getBytes()); 384 String line = readLine(in); 385 while (line != null) { 386 System.out.println(line); 387 line = readLine(in); 388 } 389 390 System.out.println("--------- test 2 ----------"); 391 392 s = "line1\n\rline2\n\rline3\n\r\n\r"; 393 in = new ByteArrayInputStream(s.getBytes()); 394 line = readLine(in); 395 while (line != null) { 396 System.out.println(line); 397 line = readLine(in); 398 } 399 400 } 401 402 403}