View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2006-2008 Vlad Skarzhevskyy
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   *  @version $Id: Utils.java 2365 2008-07-21 14:59:58Z skarzhevskyy $
20   */
21  package com.intel.bluetooth;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.UnsupportedEncodingException;
26  import java.util.Enumeration;
27  import java.util.Vector;
28  
29  import javax.bluetooth.ServiceRecord;
30  import javax.bluetooth.UUID;
31  
32  /**
33   * Conversion and JVM compatibility functions.
34   * 
35   * <p>
36   * <b><u>Your application should not use this class directly.</u></b>
37   * 
38   * @author vlads
39   */
40  public abstract class Utils {
41  
42  	private static final String blueCoveImplPackage = getPackage(MicroeditionConnector.class.getName());
43  
44  	private Utils() {
45  
46  	}
47  
48  	private static String getPackage(String className) {
49  		int pStart = className.lastIndexOf('.');
50  		if (pStart == -1) {
51  			return "";
52  		} else {
53  			return className.substring(0, pStart);
54  		}
55  	}
56  
57  	public static byte[] UUIDToByteArray(String uuidStringValue) {
58  		byte[] uuidValue = new byte[16];
59  		if (uuidStringValue.indexOf('-') != -1) {
60  			throw new NumberFormatException("The '-' character is not allowed in UUID: " + uuidStringValue);
61  		}
62  		for (int i = 0; i < 16; i++) {
63  			uuidValue[i] = (byte) Integer.parseInt(uuidStringValue.substring(i * 2, i * 2 + 2), 16);
64  		}
65  		return uuidValue;
66  	}
67  
68  	static byte[] UUIDToByteArray(final UUID uuid) {
69  		return UUIDToByteArray(uuid.toString());
70  	}
71  
72  	public static String UUIDByteArrayToString(byte[] uuidValue) {
73  		StringBuffer buf = new StringBuffer();
74  		for (int i = 0; i < uuidValue.length; i++) {
75  			buf.append(Integer.toHexString(uuidValue[i] >> 4 & 0xf));
76  			buf.append(Integer.toHexString(uuidValue[i] & 0xf));
77  		}
78  		return buf.toString();
79  	}
80  
81  	static long UUIDTo32Bit(UUID uuid) {
82  		if (uuid == null) {
83  			return -1;
84  		}
85  		String str = uuid.toString().toUpperCase();
86  		int shortIdx = str.indexOf(BluetoothConsts.SHORT_UUID_BASE);
87  		if ((shortIdx != -1) && (shortIdx + BluetoothConsts.SHORT_UUID_BASE.length() == str.length())) {
88  			// This is short 16-bit or 32-bit UUID
89  			return Long.parseLong(str.substring(0, shortIdx), 16);
90  		}
91  		return -1;
92  	}
93  
94  	static boolean is32Bit(UUID uuid) {
95  		return (UUIDTo32Bit(uuid) != -1);
96  	}
97  
98  	public static int securityOpt(boolean authenticate, boolean encrypt) {
99  		int security = ServiceRecord.NOAUTHENTICATE_NOENCRYPT;
100 		if (authenticate) {
101 			if (encrypt) {
102 				security = ServiceRecord.AUTHENTICATE_ENCRYPT;
103 			} else {
104 				security = ServiceRecord.AUTHENTICATE_NOENCRYPT;
105 			}
106 		} else if (encrypt) {
107 			throw new IllegalArgumentException("Illegal encrypt configuration");
108 		}
109 		return security;
110 	}
111 
112 	static boolean isStringSet(String str) {
113 		return ((str != null) && (str.length() > 0));
114 	}
115 
116 	static String loadString(InputStream inputstream) {
117 		if (inputstream == null) {
118 			return null;
119 		}
120 		try {
121 			byte[] buf = new byte[256];
122 			int len = inputstream.read(buf);
123 			return new String(buf, 0, len);
124 		} catch (IOException e) {
125 			return null;
126 		} finally {
127 			try {
128 				inputstream.close();
129 			} catch (IOException ignore) {
130 			}
131 		}
132 	}
133 
134 	static String getResourceProperty(Class owner, String resourceName) {
135 		try {
136 			String value = loadString(owner.getResourceAsStream("/" + resourceName));
137 			if (value != null) {
138 				int cr = value.indexOf('\n');
139 				if (cr != -1) {
140 					value = value.substring(0, cr - 1);
141 				}
142 			}
143 			return value;
144 		} catch (Throwable e) {
145 			return null;
146 		}
147 	}
148 
149 	/**
150 	 * Modifying the returned Object will not change the internal representation
151 	 * of the object.
152 	 * 
153 	 * @param value
154 	 * @return a clone of the array
155 	 */
156 	public static byte[] clone(byte[] value) {
157 		if (value == null) {
158 			return null;
159 		}
160 		int length = ((byte[]) value).length;
161 		byte[] bClone = new byte[length];
162 		System.arraycopy(value, 0, bClone, 0, length);
163 		return bClone;
164 	}
165 
166 	public static Vector clone(Enumeration en) {
167 		Vector copy = new Vector();
168 		while (en.hasMoreElements()) {
169 			copy.addElement(en.nextElement());
170 		}
171 		return copy;
172 	}
173 
174 	static String newStringUTF8(byte bytes[]) {
175 		try {
176 			return new String(bytes, "UTF-8");
177 		} catch (IllegalArgumentException e) {
178 			return new String(bytes);
179 		} catch (UnsupportedEncodingException e) {
180 			return new String(bytes);
181 		}
182 	}
183 
184 	static byte[] getUTF8Bytes(String str) {
185 		try {
186 			return str.getBytes("UTF-8");
187 		} catch (IllegalArgumentException e) {
188 			return str.getBytes();
189 		} catch (UnsupportedEncodingException e) {
190 			return str.getBytes();
191 		}
192 	}
193 
194 	static String newStringASCII(byte bytes[]) {
195 		try {
196 			return new String(bytes, "US-ASCII");
197 		} catch (IllegalArgumentException e) {
198 			return new String(bytes);
199 		} catch (UnsupportedEncodingException e) {
200 			return new String(bytes);
201 		}
202 	}
203 
204 	static byte[] getASCIIBytes(String str) {
205 		try {
206 			return str.getBytes("US-ASCII");
207 		} catch (IllegalArgumentException e) {
208 			return str.getBytes();
209 		} catch (UnsupportedEncodingException e) {
210 			return str.getBytes();
211 		}
212 	}
213 
214 	/**
215 	 * J2ME/J9 compatibility instead of Vector.toArray
216 	 * 
217 	 */
218 	static Object[] vector2toArray(Vector vector, Object[] anArray) {
219 		vector.copyInto(anArray);
220 		return anArray;
221 	}
222 
223 	/**
224 	 * J2ME/J9 compatibility instead of Long.toHexString
225 	 * 
226 	 */
227 	public static String toHexString(long l) {
228 		StringBuffer buf = new StringBuffer();
229 		String lo = Integer.toHexString((int) l);
230 		if (l > 0xffffffffl) {
231 			String hi = Integer.toHexString((int) (l >> 32));
232 			buf.append(hi);
233 			for (int i = lo.length(); i < 8; i++) {
234 				buf.append('0');
235 			}
236 		}
237 		buf.append(lo);
238 		return buf.toString();
239 	}
240 
241 	static void j2meUsagePatternDellay() {
242 		try {
243 			Thread.sleep(100);
244 		} catch (InterruptedException e) {
245 		}
246 	}
247 
248 	static class TimerThread extends Thread {
249 
250 		long delay;
251 
252 		Runnable run;
253 
254 		public TimerThread(long delay, Runnable run) {
255 			this.delay = delay;
256 			this.run = run;
257 		}
258 
259 		public void run() {
260 			try {
261 				Thread.sleep(delay);
262 				run.run();
263 			} catch (InterruptedException e) {
264 			}
265 		}
266 
267 	}
268 
269 	/**
270 	 * Java 1.1 compatible. Schedules the specified task for execution after the
271 	 * specified delay.
272 	 * 
273 	 * @param delay
274 	 *            delay in milliseconds before task is to be executed.
275 	 * @param run
276 	 *            task to be scheduled.
277 	 */
278 	static TimerThread schedule(final long delay, final Runnable run) {
279 		TimerThread t = new TimerThread(delay, run);
280 		UtilsJavaSE.threadSetDaemon(t);
281 		t.start();
282 		return t;
283 	}
284 
285 	public static void isLegalAPICall(Vector fqcnSet) throws Error {
286 		UtilsJavaSE.StackTraceLocation ste = UtilsJavaSE.getLocation(fqcnSet);
287 		if (ste != null) {
288 			if (ste.className.startsWith("javax.bluetooth.")) {
289 				return;
290 			}
291 			if (ste.className.startsWith(blueCoveImplPackage + ".")) {
292 				return;
293 			}
294 			throw new Error("Illegal use of the JSR-82 API");
295 		}
296 	}
297 }