summaryrefslogtreecommitdiff
path: root/src/de
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2013-06-21 18:00:58 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2013-06-21 18:00:58 +0200
commit8b3c7d67234025978c0b27c00898f94b01fab238 (patch)
treede6c6aed930bd8637c3023523596bea9308c87d4 /src/de
parent02586d30262c7be62a6668500ceeaeb84e55f39b (diff)
downloadAntennaPod-8b3c7d67234025978c0b27c00898f94b01fab238.zip
Added support for ID3 2.4 tag, resolved problems with frame size calculation
Diffstat (limited to 'src/de')
-rw-r--r--src/de/danoeh/antennapod/util/id3reader/ChapterReader.java6
-rw-r--r--src/de/danoeh/antennapod/util/id3reader/ID3Reader.java47
-rw-r--r--src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java5
3 files changed, 41 insertions, 17 deletions
diff --git a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java b/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java
index a04763bcd..f897f886c 100644
--- a/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java
+++ b/src/de/danoeh/antennapod/util/id3reader/ChapterReader.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.util.id3reader;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@@ -67,7 +68,10 @@ public class ChapterReader extends ID3Reader {
int descriptionLength = readString(null, input, header.getSize());
StringBuffer link = new StringBuffer();
readISOString(link, input, header.getSize() - descriptionLength);
- currentChapter.setLink(link.toString());
+ String decodedLink = URLDecoder.decode(link.toString(), "UTF-8");
+
+ currentChapter.setLink(decodedLink);
+
if (AppConfig.DEBUG) Log.d(TAG, "Found link: " + currentChapter.getLink());
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 8541d667d..92f817363 100644
--- a/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java
+++ b/src/de/danoeh/antennapod/util/id3reader/ID3Reader.java
@@ -24,7 +24,11 @@ public class ID3Reader {
protected int readerPosition;
- private static final byte ENCODING_UNICODE = 1;
+ private static final byte ENCODING_UTF16_WITH_BOM = 1;
+ private static final byte ENCODING_UTF16_WITHOUT_BOM = 2;
+ private static final byte ENCODING_UTF8 = 3;
+
+ private TagHeader tagHeader;
public ID3Reader() {
}
@@ -34,7 +38,7 @@ public class ID3Reader {
int rc;
readerPosition = 0;
char[] tagHeaderSource = readBytes(input, HEADER_LENGTH);
- TagHeader tagHeader = createTagHeader(tagHeaderSource);
+ tagHeader = createTagHeader(tagHeaderSource);
if (tagHeader == null) {
onNoTagHeaderFound();
} else {
@@ -124,12 +128,12 @@ public class ID3Reader {
+ HEADER_LENGTH);
}
if (hasTag) {
- String id = null;
- id = new String(source, 0, ID3_LENGTH);
+ String id = new String(source, 0, ID3_LENGTH);
char version = (char) ((source[3] << 8) | source[4]);
byte flags = (byte) source[5];
int size = (source[6] << 24) | (source[7] << 16) | (source[8] << 8)
| source[9];
+ size = unsynchsafe(size);
return new TagHeader(id, size, version, flags);
} else {
return null;
@@ -142,23 +146,41 @@ public class ID3Reader {
throw new ID3ReaderException("Length of header must be "
+ HEADER_LENGTH);
}
- String id = null;
- id = new String(source, 0, FRAME_ID_LENGTH);
- int size = (((int) source[4]) << 24) | (((int) source[5]) << 16)
- | (((int) source[6]) << 8) | source[7];
+ String id = new String(source, 0, FRAME_ID_LENGTH);
+
+ int size = (((int) source[4]) << 24) | (((int) source[5]) << 16)
+ | (((int) source[6]) << 8) | source[7];
+ if (tagHeader != null && tagHeader.getVersion() >= 0x0400) {
+ size = unsynchsafe(size);
+ }
char flags = (char) ((source[8] << 8) | source[9]);
return new FrameHeader(id, size, flags);
}
+ private int unsynchsafe(int in) {
+ int out = 0;
+ int mask = 0x7F000000;
+
+ while (mask != 0) {
+ out >>= 1;
+ out |= in & mask;
+ mask >>= 8;
+ }
+
+ return out;
+ }
+
protected int readString(StringBuffer buffer, InputStream input, int max) throws IOException,
ID3ReaderException {
if (max > 0) {
char[] encoding = readBytes(input, 1);
max--;
- if (encoding[0] == ENCODING_UNICODE) {
- return readUnicodeString(buffer, input, max) + 1; // take encoding byte into account
- } else {
+ if (encoding[0] == ENCODING_UTF16_WITH_BOM || encoding[0] == ENCODING_UTF16_WITHOUT_BOM) {
+ return readUnicodeString(buffer, input, max, Charset.forName("UTF-16")) + 1; // take encoding byte into account
+ } else if (encoding[0] == ENCODING_UTF8) {
+ return readUnicodeString(buffer, input, max, Charset.forName("UTF-8")) + 1; // take encoding byte into account
+ } else {
return readISOString(buffer, input, max) + 1; // take encoding byte into account
}
} else {
@@ -182,7 +204,7 @@ public class ID3Reader {
return bytesRead;
}
- private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max)
+ private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max, Charset charset)
throws IOException, ID3ReaderException {
byte[] buffer = new byte[max];
int c, cZero = -1;
@@ -203,7 +225,6 @@ public class ID3Reader {
cZero = -1;
}
}
- Charset charset = Charset.forName("UTF-16");
if (strBuffer != null) {
strBuffer.append(charset.newDecoder().decode(ByteBuffer.wrap(buffer)).toString());
}
diff --git a/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java b/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java
index 2c0d8e5ba..df73393a5 100644
--- a/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java
+++ b/src/de/danoeh/antennapod/util/id3reader/model/FrameHeader.java
@@ -11,8 +11,7 @@ public class FrameHeader extends Header {
@Override
public String toString() {
- return "FrameHeader [flags=" + Integer.toString(flags) + ", id=" + id + ", size=" + size
- + "]";
- }
+ return String.format("FrameHeader [flags=%s, id=%s, size=%s]", Integer.toBinaryString(flags), id, Integer.toBinaryString(size));
+ }
}