/* Copyright (c) 2008 Bluendo S.r.L. * See about.html for details about license. * * $Id: Utils.java 1419 2009-05-04 13:45:19Z luca $ */ package it.yup.util; import it.yup.xml.Element; import it.yup.xmpp.Contact; import it.yup.xmpp.packets.Iq; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.Timer; import java.util.Vector; import org.bouncycastle.crypto.digests.GeneralDigest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; public class Utils { /** * Global event scheduler */ static public Timer tasks = new Timer(); private static boolean has_utf8 = false; static { try { // XXX don't waht will happen with optimizer && obfuscator "".getBytes("UTF-8"); has_utf8 = true; } catch (UnsupportedEncodingException usx) { has_utf8 = false; } } /** * Compute a digest of a message * @param msg * The message whose digest must be computed. The encoding must be utf-8 * @param digestType * sha1 or md5 * @return * a string representing the digest */ public static String hexDigest(String msg, String digestType) { return bytesToHex(digest(msg, digestType)); } static public byte[] digest(String msg, String digestType) { return digest(getBytesUtf8(msg), digestType); } /** * * @param data * @param digestType * @return the digest or null if the requested digest is not supported */ static public byte[] digest(byte data[], String digestType) { GeneralDigest digest = null; if (digestType.equals("sha1")) { digest = new SHA1Digest(); } else if (digestType.equals("md5")) { digest = new MD5Digest(); } else { return null; } // XXX too many copies of data, modify the hash functions so that they write // the result to a byte array digest.update(data, 0, data.length); // some emulators fail on calling getByteLength byte out[] = null; try { out = new byte[digest.getByteLength()]; } catch (Error e) { out = new byte[64]; } int len = digest.doFinal(out, 0); byte result[] = new byte[len]; System.arraycopy(out, 0, result, 0, len); return result; } private static void hexDigit(PrintStream p, byte x) { char c; c = (char) ((x >> 4) & 0xf); if (c > 9) c = (char) ((c - 10) + 'a'); else c = (char) (c + '0'); p.write(c); c = (char) (x & 0xf); if (c > 9) c = (char) ((c - 10) + 'a'); else c = (char) (c + '0'); p.write(c); } public static String bytesToHex(byte digestBits[]) { ByteArrayOutputStream ou = new ByteArrayOutputStream(); PrintStream p = new PrintStream(ou); for (int i = 0; i < digestBits.length; i++) hexDigit(p, digestBits[i]); return (ou.toString()); } /** * Parse a line with values separated by delim * */ public static Vector tokenize(String line, char delim) { Vector tokens = new Vector(); StringBuffer token = new StringBuffer(); for (int i = 0; i < line.length(); i++) { char c = line.charAt(i); if (c == delim) { tokens.addElement(token.toString()); token.setLength(0); } else { token.append(c); } } tokens.addElement(token.toString()); return tokens; } /** * Parse a line with values separated by delim * @param line the string that is being parsed * @param delims the set of delimiters * @param keep if true keep delimiters */ public static Vector tokenize(String line, String delims[], boolean keep) { Vector tokens = new Vector(); StringBuffer token = new StringBuffer(); int i = 0; boolean in_delim = true; while (i < line.length()) { int l = -1; // find the longest delimiter int di = -1; for (int j = 0; j < delims.length; j++) { if (delims[j].length() > l && line.startsWith(delims[j], i)) { l = delims[j].length(); di = j; } } if (in_delim) { if (l < 0) { token.append(line.charAt(i)); in_delim = false; } else if (keep) { tokens.addElement(delims[di]); } } else { if (l >= 0) { tokens.addElement(token.toString()); token.setLength(0); if (keep) { tokens.addElement(delims[di]); } ; in_delim = true; } else { token.append(line.charAt(i)); } } i += Math.max(l, 1); } if (token.length() > 0) { tokens.addElement(token.toString()); } return tokens; } public static boolean is_jid(String s) { Vector parts = Utils.tokenize(s, '.'); return (parts.size() >= 2) && ((String) parts.elementAt(0)).length() > 0 && ((String) parts.elementAt(1)).length() > 0; } public static boolean is_email(String s) { Vector parts = Utils.tokenize(s, '@'); return (parts.size() == 2) && ((String) parts.elementAt(0)).length() > 0 && ((String) parts.elementAt(1)).length() > 0; } public static boolean[] str2flags(String s, int start, int length) { int flags = Integer.parseInt(s); boolean v[] = new boolean[length]; flags >>= start; for (int i = 0; i < length; i++) { int mask = 0x01 << i; v[i] = ((flags & mask) == mask); } return v; }; // public static int readExactly (InputStream is, byte [] buf , int start , int length) throws IOException{ // int tempLength = 0; // int n = 0; // do { // n = is.read(buf, tempLength,buf.length - tempLength); // tempLength += n; // } while (n >= 0 && tempLength < length); // return tempLength; // } public static String flags2str(boolean v[], int offset) { int flags = 0; for (int i = 0; i < v.length; i++) { flags |= (v[i] ? (0x01 << i) : (0)); } flags <<= offset; return "" + flags; } public static Vector find_urls(String s) { Vector v = new Vector(); int i = 0; int url_start, url_end; while (i < s.length()) { if ((url_start = s.indexOf("http://", i)) >= 0) { url_end = s.indexOf(' ', url_start + 7); if (url_end < 0) url_end = s.length(); v.addElement(s.substring(url_start, url_end)); i = url_end; } else if ((url_start = s.indexOf("www.", i)) >= 0) { url_end = s.indexOf(' ', url_start + 4); if (url_end < 0) url_end = s.length(); v.addElement("http://" + s.substring(url_start, url_end)); i = url_end; } else { break; } } return v; } public static final String getStringUTF8(byte in[]) { if (has_utf8) { try { return new String(in, "UTF-8"); } catch (UnsupportedEncodingException usx) { // shouldnt... } } StringBuffer buff = new StringBuffer(); int max = in.length; for (int i = 0; i < max; i++) { char c = 0; if ((in[i] & 0x80) == 0) { c = (char) in[i]; } else if ((in[i] & 0xe0) == 0xc0) { c |= ((in[i] & 0x1f) << 6); i++; c |= ((in[i] & 0x3f) << 0); } else if ((in[i] & 0xf0) == 0xe0) { c |= ((in[i] & 0x0f) << 12); i++; c |= ((in[i] & 0x3f) << 6); i++; c |= ((in[i] & 0x3f) << 0); } else if ((in[i] & 0xf8) == 0xf0) { c |= ((in[i] & 0x07) << 18); i++; c |= ((in[i] & 0x3f) << 12); i++; c |= ((in[i] & 0x3f) << 6); i++; c |= ((in[i] & 0x3f) << 0); } else { c = '?'; } buff.append(c); } return buff.toString(); } public static final byte[] getBytesUtf8(String str) { if (has_utf8) { try { return str.getBytes("UTF-8"); } catch (UnsupportedEncodingException usx) { // shouldnt... } } char[] chars = str.toCharArray(); int vlen = chars.length; for (int i = 0; i < chars.length; i++) { char ch = chars[i]; if (ch >= 0 && ch <= 0x07F) { ; } else if (ch >= 0x080 && ch <= 0x07FF) { vlen++; } else if ((ch >= 0x0800 && ch <= 0x0D7FF) || (ch >= 0x00E000 && ch <= 0x00FFFD)) { vlen += 2; } if (ch >= 0x010000 && ch <= 0x10FFFF) { vlen += 3; } else { /* invalid char, ignore */ vlen--; } } byte[] buf = new byte[vlen]; int j = 0; for (int i = 0; i < chars.length; i++) { char ch = chars[i]; if (ch >= 0 && ch <= 0x07F) { buf[j++] = (byte) (ch & 0x07F); } else if (ch >= 0x080 && ch <= 0x07FF) { buf[j++] = (byte) (0xC0 | ((ch & 0x07C0) >> 6)); buf[j++] = (byte) (0x80 | ((ch & 0x003F))); } else if ((ch >= 0x0800 && ch <= 0x0D7FF) || (ch >= 0x00E000 && ch <= 0x00FFFD)) { buf[j++] = (byte) (0xE0 | ((ch & 0x0F000) >> 12)); buf[j++] = (byte) (0x80 | ((ch & 0x00FC0) >> 6)); buf[j++] = (byte) (0x80 | ((ch & 0x0003F))); } if (ch >= 0x010000 && ch <= 0x10FFFF) { /* non dovrebbero essere usate */ buf[j++] = (byte) (0xE0 | ((ch & 0x1C0000) >> 18)); buf[j++] = (byte) (0x80 | ((ch & 0x03F000) >> 12)); buf[j++] = (byte) (0x80 | ((ch & 0x000FC0) >> 6)); buf[j++] = (byte) (0x80 | ((ch & 0x00003F))); } } return buf; } public static Iq easyReply(Element fromIq) { Iq replIq = new Iq(fromIq.getAttribute(Iq.ATT_FROM), Iq.T_RESULT); replIq.setAttribute(Iq.ATT_ID, fromIq.getAttribute(Iq.ATT_ID)); return replIq; } public static boolean compareTo(Contact left, Contact right) { return left.getPrintableName().toLowerCase().compareTo( right.getPrintableName().toLowerCase()) < 0; } // static public void main(String params[]) { // Vector tokens = Utils.tokenize(" Ciao a tutti , come \nva va ciao\r\npipo ", new String[] {" ", " ", "\n", "\r\n"}, true); // for(int i=0; i<tokens.size(); i++) { // System.out.println("->" + tokens.elementAt(i) + "<-"); // } // } }