diff --git a/app/src/main/java/protect/card_locker/ZipUtils.java b/app/src/main/java/protect/card_locker/ZipUtils.java index 9935323b5..c0c30bd1d 100644 --- a/app/src/main/java/protect/card_locker/ZipUtils.java +++ b/app/src/main/java/protect/card_locker/ZipUtils.java @@ -15,7 +15,15 @@ import java.io.Reader; import java.nio.charset.StandardCharsets; public class ZipUtils { - static public String read(ZipInputStream zipInputStream) throws IOException { + public static Bitmap readImage(ZipInputStream zipInputStream) { + return BitmapFactory.decodeStream(zipInputStream); + } + + public static JSONObject readJSON(ZipInputStream zipInputStream) throws IOException, JSONException { + return new JSONObject(read(zipInputStream)); + } + + private static String read(ZipInputStream zipInputStream) throws IOException { StringBuilder stringBuilder = new StringBuilder(); Reader reader = new BufferedReader(new InputStreamReader(zipInputStream, StandardCharsets.UTF_8)); int c; @@ -24,12 +32,4 @@ public class ZipUtils { } return stringBuilder.toString(); } - - static public Bitmap readImage(ZipInputStream zipInputStream) { - return BitmapFactory.decodeStream(zipInputStream); - } - - static public JSONObject readJSON(ZipInputStream zipInputStream) throws IOException, JSONException { - return new JSONObject(read(zipInputStream)); - } } diff --git a/app/src/main/java/protect/card_locker/importexport/CatimaImporter.java b/app/src/main/java/protect/card_locker/importexport/CatimaImporter.java index d83c25655..40c290b22 100644 --- a/app/src/main/java/protect/card_locker/importexport/CatimaImporter.java +++ b/app/src/main/java/protect/card_locker/importexport/CatimaImporter.java @@ -13,7 +13,6 @@ import org.apache.commons.csv.CSVRecord; import java.io.BufferedInputStream; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -55,7 +54,7 @@ public class CatimaImporter implements Importer { String fileName = Uri.parse(localFileHeader.getFileName()).getLastPathSegment(); if (fileName.equals("catima.csv")) { - importCSV(context, database, new ByteArrayInputStream(ZipUtils.read(zipInputStream).getBytes(StandardCharsets.UTF_8))); + importCSV(context, database, zipInputStream); } else if (fileName.endsWith(".png")) { Utils.saveCardImage(context, ZipUtils.readImage(zipInputStream), fileName); } else { @@ -68,23 +67,14 @@ public class CatimaImporter implements Importer { bufferedInputStream.reset(); importCSV(context, database, bufferedInputStream); } + + input.close(); } public void importCSV(Context context, SQLiteDatabase database, InputStream input) throws IOException, FormatException, InterruptedException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); - bufferedReader.mark(100); - - Integer version = 1; - - try { - version = Integer.parseInt(bufferedReader.readLine()); - } catch (NumberFormatException _e) { - // Assume version 1 - } - - bufferedReader.reset(); - + int version = parseVersion(bufferedReader); switch (version) { case 1: parseV1(context, database, bufferedReader); @@ -95,8 +85,6 @@ public class CatimaImporter implements Importer { default: throw new FormatException(String.format("No code to parse version %s", version)); } - - bufferedReader.close(); } public void parseV1(Context context, SQLiteDatabase database, BufferedReader input) throws IOException, FormatException, InterruptedException { @@ -118,8 +106,8 @@ public class CatimaImporter implements Importer { } public void parseV2(Context context, SQLiteDatabase database, BufferedReader input) throws IOException, FormatException, InterruptedException { - Integer part = 0; - String stringPart = ""; + int part = 0; + StringBuilder stringPart = new StringBuilder(); try { while (true) { @@ -135,7 +123,7 @@ public class CatimaImporter implements Importer { break; case 1: try { - parseV2Groups(database, stringPart); + parseV2Groups(database, stringPart.toString()); sectionParsed = true; } catch (FormatException e) { // We may have a multiline field, try again @@ -143,7 +131,7 @@ public class CatimaImporter implements Importer { break; case 2: try { - parseV2Cards(context, database, stringPart); + parseV2Cards(context, database, stringPart.toString()); sectionParsed = true; } catch (FormatException e) { // We may have a multiline field, try again @@ -151,7 +139,7 @@ public class CatimaImporter implements Importer { break; case 3: try { - parseV2CardGroups(database, stringPart); + parseV2CardGroups(database, stringPart.toString()); sectionParsed = true; } catch (FormatException e) { // We may have a multiline field, try again @@ -167,12 +155,12 @@ public class CatimaImporter implements Importer { if (sectionParsed) { part += 1; - stringPart = ""; + stringPart = new StringBuilder(); } else { - stringPart += tmp + "\n"; + stringPart.append(tmp).append('\n'); } } else { - stringPart += tmp + "\n"; + stringPart.append(tmp).append('\n'); } } } catch (FormatException e) { @@ -255,6 +243,35 @@ public class CatimaImporter implements Importer { } } + /** + * Parse the version number of the import file + * + * @param reader the reader containing the import file + * @return the parsed version number, defaulting to 1 if none is found + * @throws IOException there was a problem reading the file + */ + private int parseVersion(BufferedReader reader) throws IOException { + reader.mark(10); // slightly over the search limit just to be sure + StringBuilder sb = new StringBuilder(); + int searchLimit = 5; // gives you version numbers up to 99999 + int codePoint; + // search until the next whitespace, indicating the end of the version + while (!Character.isWhitespace(codePoint = reader.read())) { + // we found something that isn't a digit, or we ran out of chars + if (!Character.isDigit(codePoint) || searchLimit <= 0) { + reader.reset(); + return 1; // default value + } + sb.append((char) codePoint); + searchLimit--; + } + reader.reset(); + if (sb.length() == 0) { + return 1; + } + return Integer.parseInt(sb.toString()); + } + /** * Import a single loyalty card into the database using the given * session. @@ -338,7 +355,7 @@ public class CatimaImporter implements Importer { // We catch this exception so we can still import old backups } - DBHelper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starStatus, lastUsed,archiveStatus); + DBHelper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starStatus, lastUsed, archiveStatus); } /**