Grundaufbau der App
[DHBWCampusApp.git] / app / src / main / java / com / codebutler / farebot / Utils.java
1 /*
2  * Utils.java
3  *
4  * Copyright (C) 2011 Eric Butler
5  *
6  * Authors:
7  * Eric Butler <eric@codebutler.com>
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 package com.codebutler.farebot;
24
25 import android.app.Activity;
26 import android.app.AlertDialog;
27 import android.content.DialogInterface;
28 import android.util.Log;
29 import android.view.WindowManager;
30
31 import com.codebutler.farebot.card.desfire.DesfireException;
32 import com.codebutler.farebot.card.desfire.DesfireFileSettings;
33 import com.codebutler.farebot.card.desfire.DesfireProtocol;
34
35 import org.w3c.dom.Node;
36
37 import java.io.StringWriter;
38 import java.util.List;
39
40 import javax.xml.transform.OutputKeys;
41 import javax.xml.transform.Result;
42 import javax.xml.transform.Source;
43 import javax.xml.transform.Transformer;
44 import javax.xml.transform.TransformerFactory;
45 import javax.xml.transform.dom.DOMSource;
46 import javax.xml.transform.stream.StreamResult;
47
48 public class Utils {
49
50         private static final String TAG = Utils.class.getName();
51
52     public static void showError (final Activity activity, Exception ex) {
53         Log.e(activity.getClass().getName(), ex.getMessage(), ex);
54         new AlertDialog.Builder(activity)
55             .setMessage(Utils.getErrorMessage(ex))
56             .show();
57     }
58
59     public static void showErrorAndFinish (final Activity activity, Exception ex) {
60         try {
61             Log.e(activity.getClass().getName(), Utils.getErrorMessage(ex));
62             ex.printStackTrace();
63
64             new AlertDialog.Builder(activity)
65                 .setMessage(Utils.getErrorMessage(ex))
66                 .setCancelable(false)
67                 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
68                     public void onClick(DialogInterface arg0, int arg1) {
69                         activity.finish();
70                     }
71                 })
72                 .show();
73         } catch (WindowManager.BadTokenException unused) {
74             /* Ignore... happens if the activity was destroyed */
75         }
76     }
77
78     public static String getHexString (byte[] b) throws Exception {
79         String result = "";
80         for (int i=0; i < b.length; i++) {
81             result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
82         }
83         return result;
84     }
85
86     public static String getHexString (byte[] b, String defaultResult) {
87         try {
88             return getHexString(b);
89         } catch (Exception ex) {
90             return defaultResult;
91         }
92     }
93
94     public static byte[] hexStringToByteArray (String s) {
95         if ((s.length() % 2) != 0) {
96             throw new IllegalArgumentException("Bad input string: " + s);
97         }
98         
99         int len = s.length();
100         byte[] data = new byte[len / 2];
101         for (int i = 0; i < len; i += 2) {
102             data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
103                                  + Character.digit(s.charAt(i+1), 16));
104         }
105         return data;
106     }
107
108     /*
109     public static byte[] intToByteArray(int value) {
110         return new byte[] {
111                 (byte)(value >>> 24),
112                 (byte)(value >>> 16),
113                 (byte)(value >>> 8),
114                 (byte)value};
115     }
116     */
117     
118     public static int byteArrayToInt(byte[] b) {
119         return byteArrayToInt(b, 0);
120     }
121     
122     public static int byteArrayToInt(byte[] b, int offset) {
123         return byteArrayToInt(b, offset, b.length);
124     }
125     
126     public static int byteArrayToInt(byte[] b, int offset, int length) {
127         return (int) byteArrayToLong(b, offset, length);
128     }
129
130     public static long byteArrayToLong(byte[] b, int offset, int length) {
131         if (b.length < length)
132             throw new IllegalArgumentException("length must be less than or equal to b.length");
133
134         long value = 0;
135         for (int i = 0; i < length; i++) {
136             int shift = (length - 1 - i) * 8;
137             value += (b[i + offset] & 0x000000FF) << shift;
138         }
139         return value;
140     }
141
142     public static byte[] byteArraySlice(byte[] b, int offset, int length) {
143         byte[] ret = new byte[length];
144         for (int i = 0; i < length; i++)
145             ret[i] = b[offset+i];
146         return ret;
147     }
148
149     public static String xmlNodeToString (Node node) throws Exception {
150         // The amount of code required to do simple things in Java is incredible.
151         Source source = new DOMSource(node);
152         StringWriter stringWriter = new StringWriter();
153         Result result = new StreamResult(stringWriter);
154         TransformerFactory factory = TransformerFactory.newInstance();
155         Transformer transformer = factory.newTransformer();
156         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
157         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
158         transformer.setURIResolver(null);
159         transformer.transform(source, result);
160         return stringWriter.getBuffer().toString();
161     }
162
163     public static String getErrorMessage (Throwable ex) {
164         String errorMessage = ex.getLocalizedMessage();
165         if (errorMessage == null)
166             errorMessage = ex.getMessage();
167         if (errorMessage == null)
168             errorMessage = ex.toString();
169
170         if (ex.getCause() != null) {
171             String causeMessage = ex.getCause().getLocalizedMessage();
172             if (causeMessage == null)
173                 causeMessage = ex.getCause().getMessage();
174             if (causeMessage == null)
175                 causeMessage = ex.getCause().toString();
176
177             if (causeMessage != null)
178                 errorMessage += ": " + causeMessage;
179         }
180
181         return errorMessage;
182     }
183
184
185     public static <T> T findInList(List<T> list, Matcher<T> matcher) {
186         for (T item : list) {
187             if (matcher.matches(item)) {
188                 return item;
189             }
190         }
191         return null;
192     }
193
194     public static interface Matcher<T> {
195         public boolean matches(T t);
196     }
197
198     public static int convertBCDtoInteger(byte data) {
199         return (((data & (char)0xF0) >> 4) * 10) + ((data & (char)0x0F));
200     }
201
202     public static int getBitsFromInteger(int buffer, int iStartBit, int iLength) {
203         return (buffer >> (iStartBit)) & ((char)0xFF >> (8 - iLength));
204     }
205
206     /* Based on function from mfocGUI by 'Huuf' (http://www.huuf.info/OV/) */
207     public static int getBitsFromBuffer(byte[] buffer, int iStartBit, int iLength) {
208         int iEndBit = iStartBit + iLength - 1;
209         int iSByte = iStartBit / 8;
210         int iSBit = iStartBit % 8;
211         int iEByte = iEndBit / 8;
212         int iEBit = iEndBit % 8;
213
214         if (iSByte == iEByte) {
215             return (int)(((char)buffer[iEByte] >> (7 - iEBit)) & ((char)0xFF >> (8 - iLength)));
216         } else {
217             int uRet = (((char)buffer[iSByte] & (char)((char)0xFF >> iSBit)) << (((iEByte - iSByte - 1) * 8) + (iEBit + 1)));
218
219             for (int i = iSByte + 1; i < iEByte; i++) {
220                 uRet |= (((char)buffer[i] & (char)0xFF) << (((iEByte - i - 1) * 8) + (iEBit + 1)));
221             }
222
223             uRet |= (((char)buffer[iEByte] & (char)0xFF)) >> (7 - iEBit);
224
225             return uRet;
226         }
227     }
228
229
230         public static DesfireFileSettings selectAppFile(DesfireProtocol tag, int appID, int fileID) {
231                 try {
232                         tag.selectApp(appID);
233                 } catch (DesfireException e) {
234                         Log.w(TAG,"App not found");
235                         return null;
236                 }
237                 try {
238                         return tag.getFileSettings(fileID);
239                 } catch (DesfireException e) {
240                         Log.w(TAG,"File not found");
241                         return null;
242                 }
243         }
244
245         public static boolean arrayContains(int[] arr, int item) {
246                 for (int i: arr)
247                         if (i==item)
248                                 return true;
249                 return false;
250         }
251
252         public static boolean containsAppFile(DesfireProtocol tag, int appID, int fileID) {
253                 try {
254                         tag.selectApp(appID);
255                 } catch (DesfireException e) {
256                         Log.w(TAG,"App not found");
257                         Log.w(TAG, e);
258                         return false;
259                 }
260                 try {
261                         return arrayContains(tag.getFileList(),fileID);
262                 } catch (DesfireException e) {
263                         Log.w(TAG,"File not found");
264                         Log.w(TAG, e);
265                         return false;
266                 }
267         }
268 }