From 50c983cccd934e1bbc0926a5efde6c9e202e82fd Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Sat, 5 Jan 2013 00:47:26 +0100 Subject: [PATCH] Unicode strings weren't read correctly --- .../util/id3reader/ChapterReader.java | 10 ++--- .../antennapod/util/id3reader/ID3Reader.java | 45 +++++++++---------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java b/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java index 9a86de15d..e1cafe85d 100644 --- a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java +++ b/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java @@ -33,11 +33,11 @@ public class ChapterReader extends ID3Reader { if (currentChapter != null) { if (!hasId3Chapter(currentChapter)) { chapters.add(currentChapter); + System.out.println("Found chapter: " + currentChapter); currentChapter = null; } } - System.out.println("Found chapter"); - String elementId = readString(input, Integer.MAX_VALUE); + String elementId = readISOString(input, Integer.MAX_VALUE); char[] startTimeSource = readBytes(input, 4); long startTime = ((int) startTimeSource[0] << 24) | ((int) startTimeSource[1] << 16) @@ -47,10 +47,10 @@ public class ChapterReader extends ID3Reader { return ID3Reader.ACTION_DONT_SKIP; } else if (header.getId().equals(FRAME_ID_TITLE)) { if (currentChapter != null && currentChapter.getTitle() == null) { - System.out.println("Found title"); - skipBytes(input, 1); currentChapter - .setTitle(readString(input, header.getSize() - 1)); + .setTitle(readString(input, header.getSize())); + System.out.println("Found title: " + currentChapter.getTitle()); + return ID3Reader.ACTION_DONT_SKIP; } } diff --git a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java index 59631f06e..515359730 100644 --- a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java +++ b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java @@ -3,6 +3,8 @@ package de.danoeh.antennapod.util.id3reader; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; import org.apache.commons.io.IOUtils; @@ -23,8 +25,7 @@ public class ID3Reader { protected int readerPosition; - private static final char[] LITTLE_ENDIAN_BOM = { 0xff, 0xfe }; - private static final char[] BIG_ENDIAN_BOM = { 0xfe, 0xff }; + private static final byte ENCODING_UNICODE = 1; public ID3Reader() { } @@ -152,19 +153,23 @@ public class ID3Reader { protected String readString(InputStream input, int max) throws IOException, ID3ReaderException { - char[] bom = readBytes(input, 2); - if (bom == LITTLE_ENDIAN_BOM || bom == BIG_ENDIAN_BOM) { - return readUnicodeString(input, bom, max); + if (max > 0) { + char[] encoding = readBytes(input, 1); + max--; + + if (encoding[0] == ENCODING_UNICODE) { + return readUnicodeString(input, max); + } else { + return readISOString(input, max); + } } else { - PushbackInputStream pi = new PushbackInputStream(input, 2); - pi.unread(bom[1]); - pi.unread(bom[0]); - return readISOString(pi, max); + return ""; } } - private String readISOString(InputStream input, int max) + protected String readISOString(InputStream input, int max) throws IOException, ID3ReaderException { + int bytesRead = 0; StringBuilder builder = new StringBuilder(); char c; @@ -174,22 +179,12 @@ public class ID3Reader { return builder.toString(); } - private String readUnicodeString(InputStream input, char[] bom, int max) + private String readUnicodeString(InputStream input, int max) throws IOException, ID3ReaderException { - StringBuffer builder = new StringBuffer(); - char c1 = (char) input.read(); - char c2 = (char) input.read(); - int bytesRead = 2; - while ((c1 > 0 && c2 > 0) && ++bytesRead <= max) { - - builder.append(c1); - c1 = c2; - c2 = (char) input.read(); - } - if (bom == LITTLE_ENDIAN_BOM) { - builder.reverse(); - } - return builder.toString(); + byte[] buffer = new byte[max]; + IOUtils.readFully(input, buffer); + Charset charset = Charset.forName("UTF-16"); + return charset.newDecoder().decode(ByteBuffer.wrap(buffer)).toString(); } public int onStartTagHeader(TagHeader header) {